08.12.2021

Команда из Университета Миннесоты раскрыла детали об отправленных вредоносных изменениях

Следом за открытым письмом с извинениями группа исследователей из Университета Миннесоты, приём изменений в ядро 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; } 

Источник.