В ядре Linux устранена следующая уязвимость:
net: pktgen: исправить запись в процедуре use-after-free
pktgen_change_name() заменяет pkt_dev->entry, удерживая t->if_lock.
pktgen_remove_device() удаляет ту же запись, что и раньше.
_rem_dev_from_if_list() берет эту блокировку. Это позволяет следующее чередование:
ЦП 0 (NETDEV_CHANGENAME) ЦП 1 (kpktgend)
if_lock(т)
proc_remove(pkt_dev->запись)
proc_remove(pkt_dev->запись)
pkt_dev->entry = proc_create_data(...)
if_unlock(т)
Kthread может передать устаревшую запись proc_dir_entry в функцию proc_remove() после
переименование пути освободило его. Репродуктор с расширенным окном гонки сообщает:
ОШИБКА: KASAN: slab-use-after-free в proc_remove+0x78/0x80.
Чтение размера 8 по адресу ffff8881478fea70 с помощью задачи kpktgend_0/67. Отслеживание вызова:
proc_remove+0x78/0x80
pktgen_remove_device.isra.0+0x11c/0x4c0
pktgen_thread_worker+0x1214/0x6bc0
kthread+0x2c6/0x3b0
Выделено по заданию 95:
__proc_create+0x204/0x790
proc_create_data+0x72/0xe0
pktgen_thread_write+0xd61/0x1510
Освобожден заданием 28:
kmem_cache_free+0xcb/0x3d0
proc_free_inode+0x5b/0x80
rcu_core+0x50a/0x1850
Адрес ошибки принадлежит объекту по адресу ffff8881478fea00.
который принадлежит кэшу proc_dir_entry размером 192
Переместите proc_remove() в помощник удаления списка, защищенного if_lock. Держи это
перед list_del_rcu(), чтобы сохранить порядок, требуемый add_device().
Путь переименования должен затем завершить замену записи перед удалением, или он замечает, что устройства больше нет в списке.
Показать оригинальное описание (EN)
In the Linux kernel, the following vulnerability has been resolved: net: pktgen: fix proc entry use-after-free pktgen_change_name() replaces pkt_dev->entry while holding t->if_lock. pktgen_remove_device() removes the same entry before _rem_dev_from_if_list() takes that lock. This allows the following interleaving: CPU 0 (NETDEV_CHANGENAME) CPU 1 (kpktgend) if_lock(t) proc_remove(pkt_dev->entry) proc_remove(pkt_dev->entry) pkt_dev->entry = proc_create_data(...) if_unlock(t) The kthread can pass the stale proc_dir_entry to proc_remove() after the rename path has freed it. A reproducer with a widened race window reports: BUG: KASAN: slab-use-after-free in proc_remove+0x78/0x80 Read of size 8 at addr ffff8881478fea70 by task kpktgend_0/67 Call Trace: proc_remove+0x78/0x80 pktgen_remove_device.isra.0+0x11c/0x4c0 pktgen_thread_worker+0x1214/0x6bc0 kthread+0x2c6/0x3b0 Allocated by task 95: __proc_create+0x204/0x790 proc_create_data+0x72/0xe0 pktgen_thread_write+0xd61/0x1510 Freed by task 28: kmem_cache_free+0xcb/0x3d0 proc_free_inode+0x5b/0x80 rcu_core+0x50a/0x1850 The buggy address belongs to the object at ffff8881478fea00 which belongs to the cache proc_dir_entry of size 192 Move proc_remove() into the if_lock-protected list removal helper. Keep it before list_del_rcu() to preserve the ordering required by add_device(). The rename path must then finish replacing the entry before removal, or it observes that the device is no longer on the list.
Характеристики атаки
Последствия
Строка CVSS v3.1