Слідом за відкритим листом з вибаченнями група дослідників з Університету Міннесоти, прийом змін до ядра Linux від якої був заблокований Грегом Кроа-Хартманом, розкрила детальну інформацію про відправлені розробникам ядра патчі і пов'язану з цими патчами листування з мейнтейнерами.
Примітно, що всі проблемні патчі були відкинуті з ініціативи мейнтейнерів, жоден з патчів не був схвалений. Зазначений факт дає зрозуміти, чому Грег Кроа-Хартман вчинив настільки жорстко, оскільки незрозуміло, як вчинили б дослідники, якби патчі були схвалені мейнтейнерами. Заднім числом вони стверджували, що мали намір повідомити про помилку і не припустилися б надходження патчів у Git, але незрозуміло як вони вчинили б насправді і як далеко могли зайти.
Загалом у серпні 2020 року з анонімних адрес acostag.ubuntu@gmail.com і jameslouisebond@gmail.com (лист від Джеймса Бонда) було відправлено п'ять патчів: два коректні (1, 2) і три включають приховані помилки (1, 2, 3), що створюють умови для виникнення вразливостей. Кожен патч містив лише 1-4 рядки коду. Основна ідея помилкових патчів була в тому, що виправлення витоку пам'яті може створювати умову появи вразливості через подвійне звільнення пам'яті. Через тиждень розробникам ядра було надіслано інформацію з пропозицією обговорити можливість просування вразливостей під виглядом очевидних виправлень витоків пам'яті, але про раніше спроби відправки шкідливих патчів нічого сказано не було.
Перший проблемний патч усував витік пам'яті, додаючи виклик kfree() перед поверненням управління у разі помилки, але створював умови для звернення до області пам'яті після її звільнення (use-after-free). Вказаний патч був відкинутий супроводжуючим (Jiri Slaby), який визначив наявність проблеми і вказав, що рік тому хтось уже намагався запропонувати подібну зміну і вона була спочатку прийнята, але потім була відкинута після виявлення умов появи вразливості. > p2 = p1[n] = kmalloc_array(64, sizeof(u16), GFP_KERNEL); > - if (! p2) return -ENOMEM; > + if (! p2) { > + kfree (p1); > + return-ENOMEM; > + }
Другий патч також містив умови виникнення проблеми use-after-free. Зазначений патч не був прийнятий супроводжуючим (Dan Carpenter), який відхилив патч через іншу проблему з list_add_tail, але не звернув увагу на те, що функції put_device може бути звільнений покажчик «chdev», який нижче використовується у виклику dev_err(&chdev ->dev..). Тим не менш, патч не був прийнятий, хоч і через не пов'язану з вразливістю. if (ret < 0) { + put_device(&chdev->dev); dev_err(&chdev->dev, DRV_NAME ": kfifo_alloc failed\n"); ret = -ENOMEM; goto err_fifo;
Третій патч також не був прийнятий мейнтейнер (Miquel Raynal) через наявність іншої помилки, не пов'язаної з вразливістю (подвійний виклик put для pdev). if (!window->virt) { printk(KERN_ERR MOD_NAME ": ioremap(%08lx, %08lx) failed\n", window->phys, window->size); + pci_dev_put(pdev); goto out; } … if (!map) { printk(KERN_ERR MOD_NAME ": kmalloc failed"); + pci_dev_put(pdev); goto out; } memset(map, 0, sizeof(*map)); … if (mtd_device_register(map->mtd, NULL, 0)) { map_destroy(map->mtd); map->mtd = NULL; + pci_dev_put(pdev); goto out; }
Цікаво, що спочатку передбачалося, що 4 з 5 патчів мають проблеми, але дослідники самі припустилися помилки і в одному проблемному, на їхню думку, патчі було запропоновано коректне виправлення, без виникнення передбачуваних умов для використання пам'яті після звільнення. err = pci_request_mem_regions(pdev, nitrox_driver_name); if (err) {pci_disable_device(pdev); + dev_err(&pdev->dev, "Failed to request mem regions!\n"); return err; }
Джерело: opennet.ru
