Следом за открытым письмом с извинениями группа исследователей из Университета Миннесоты, приём изменений в ядро Linux от которой был заблокирован Грегом Кроа-Хартманом, раскрыла детальную информацию об отправленных разработчикам ядра патчах и связанную с этими патчами переписку с мэйнтейнерами. Примечательно, что все из проблемных патчей были отвергнуты по инициативе мэйнтейнеров, ни один из патчей не был одобрен.
Всего в августе 2020 года с анонимных адресов [email protected] и [email protected] (письмо от Джеймса Бонда) было отправлено пять патчей: два корректных (1, 2) и три включающих скрытые ошибки (1, 2, 3), создающие условия для возникновения уязвимостей. Каждый патч содержал всего 1-4 строки кода. Продвижение всех проблемных патчей было остановлено на стадии до добавления изменений в Git.
Первый проблемный патч устранял утечку памяти, добавляя вызов 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 dev); dev_err(&chdev->dev, DRV_NAME “: kfifo_alloc failedn”); ret = -ENOMEM; goto err_fifo;
Третий патч также не был принят мэйнтейнером (Miquel Raynal) из-за наличия другой ошибки, не связанной с уязвимостью (двойной вызов put для pdev).
if (!window->virt) { printk(KERN_ERR MOD_NAME “: ioremap(%08lx, %08lx) failedn”, 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 патчей имеют проблемы, но исследователи сами допустили ошибку и в одном проблемном, по их мнению, патче было предложено корректное исправление, без возникновения предполагаемых условий для использования памяти после освобождения.