В ядре Linux устранена следующая уязвимость:
Apparmor: исправлено использование после освобождения в цикле дедупликации необработанных данных.
aa_replace_profiles() проходит ns->rawdata_list для дедупликации входящих данных.
большой двоичный объект политики в отношении записей, уже прикрепленных к существующим профилям. Согласно документации ядра в структуре aa_loaddata, членство в списке не имеет значения.
хранить ссылку: профили содержат pcount, и когда последний pcount
падает, do_ploaddata_rmfs() ставится в очередь в рабочей очереди, которая занимает
ns->lock и удаляет запись. Между сбросом последнего pcount
и рабочая очередь работает, запись остается в списке с
псчет == 0.
aa_get_profile_loaddata() — это безусловный kref_get() для
pcount, поэтому, когда цикл дедупликации достигает такой записи, refcount
отчеты об укреплении
refcount_t: добавление по 0; использовать после бесплатно.
внутри aa_replace_profiles(), а затем отравленный счетчик
отключения «насыщенность» и предупреждения «недолив» при последующем
использование одних и тех же данных загрузки.
Перед коммитом a0b7091c4de4 («apparmor: исправлена гонка на rawdata
разыменование"), путь дедупликации использовал хелпер в стиле get_unless_zero.
на одном счетчике, поэтому существующая защита «if (tmp)» была
значимый. Представлен рефакторинг разделенного рефсчета
aa_get_profile_loaddata(), который имеет простую семантику kref_get(),
и охранник тихо стал бездействовать. Введите aa_get_profile_loaddata_not0(), соответствующий существующему
Соглашение _not0, используемое aa_get_profile_not0(), и используйте его для
дедупированный поиск rawdata_list, поэтому умирающие записи пропускаются.
Воспроизведено на x86_64 с v7.1-rc5 в QEMU+KVM под управлением Ubuntu.
24.04 + стресс-нг 0.17.06:
стресс-нг --apparmor 1 --klog-check --timeout 60 с
Без этого патча три предупреждения refcount_t срабатывают в течение одного
несколько секунд. С ним тот же пробег 60-х чистый. Покрытие – это
только дым-тест; более длительное вымачивание с помощью CONFIG_KASAN, CONFIG_KCSAN
и CONFIG_PROVE_LOCKING будут приветствоваться у всех, у кого есть
циклы.
Показать оригинальное описание (EN)
In the Linux kernel, the following vulnerability has been resolved: apparmor: fix use-after-free in rawdata dedup loop aa_replace_profiles() walks ns->rawdata_list to dedup the incoming policy blob against entries already attached to existing profiles. Per the kernel-doc on struct aa_loaddata, list membership does not hold a reference: profiles hold pcount, and when the last pcount drops, do_ploaddata_rmfs() is queued on a workqueue that takes ns->lock and removes the entry. Between dropping the last pcount and the workqueue running, an entry remains on the list with pcount == 0. aa_get_profile_loaddata() is an unconditional kref_get() on pcount, so when the dedup loop hits such an entry, refcount hardening reports refcount_t: addition on 0; use-after-free. inside aa_replace_profiles(), and the poisoned counter then trips "saturated" and "underflow" warnings on the subsequent uses of the same loaddata. Before commit a0b7091c4de4 ("apparmor: fix race on rawdata dereference") the dedup path used a get_unless_zero-style helper on a single counter, so the existing "if (tmp)" guard was meaningful. The split-refcount refactor introduced aa_get_profile_loaddata(), which has plain kref_get() semantics, and the guard quietly became a no-op. Introduce aa_get_profile_loaddata_not0(), matching the existing _not0 convention used by aa_get_profile_not0(), and use it for the rawdata_list dedup lookup so dying entries are skipped. Reproduced on x86_64 with v7.1-rc5 in QEMU+KVM running Ubuntu 24.04 + stress-ng 0.17.06: stress-ng --apparmor 1 --klog-check --timeout 60s Without this patch the three refcount_t warnings fire within a few seconds. With it the same 60 s run is clean. Coverage is a smoke-test only; a longer soak with CONFIG_KASAN, CONFIG_KCSAN and CONFIG_PROVE_LOCKING would be welcome from anyone with the cycles.
Характеристики атаки
Последствия
Строка CVSS v3.1