CVE-2026-68082 in Linux
Сводка
по VulDB • 08.08.2026
В ядре Linux устранена следующая уязвимость:
libceph: исправлены две небезопасные операции необработанного декодирования в decode_lockers()
Функция decode_lockers() в файле cls_lock_client.c содержит две операции необработанного (bare) декодирования, которые позволяют злонамеренному или скомпрометированному OSD инициировать чтение за пределами области slab-буфера:
1. Вызов ceph_decode_32(p) для поля num_lockers не имеет предварительной проверки границ. Функция ceph_start_decoding() принимает struct_len=0 как допустимое значение -- внутренняя проверка ceph_decode_need(p, end, 0, bad) всегда проходит успешно -- поэтому при отправке OSD значения struct_len=0 функция ceph_start_decoding() возвращает успех с условием p == end. Непосредственно следующий за этим вызов необработанного декодирования ceph_decode_32(p) считывает 4 байта после границы валидированного буфера. Полученное мусорное значение напрямую передается в kzalloc_objs() в качестве количества блокировщиков (locker count).
Функция-близнец decode_watchers() в osd_client.c уже использует ceph_decode_32_safe() после собственного вызова ceph_start_decoding(). decode_lockers() была единственным местом, использующим необработанный вариант.
2. Вызов ceph_decode_8(p) после цикла decode_locker() не имеет предварительной проверки границ. Если OSD формирует значение num_lockers таким образом, что цикл продвигает указатель p ровно до end, последующий вызов необработанного декодирования ceph_decode_8(p) считывает один байт за пределами границы валидированного буфера. Результат напрямую передается в *type, который используется вызывающими сторонами как дискриминатор типа блокировки, что дает возможность OSD-контролируемого чтения одного байта вне границ (OOB read) с прямым влиянием на поле типа блокировки.
Исправление обоих случаев заключается в замене необработанных операций их безопасными вариантами: ceph_decode_32(p) -> ceph_decode_32_safe(p, end, *num_lockers, err_inval) ceph_decode_8(p) -> ceph_decode_8_safe(p, end, *type, err_free_lockers)
Цели перехода (goto targets) различаются намеренно: err_inval: это новая метка, возвращающая -EINVAL напрямую. Она используется для пути обработки ошибки предварительного выделения памяти, где *lockers еще не выделена и ее нельзя передавать в ceph_free_lockers().
err_free_lockers: это существующая метка. Она используется для пути обработки ошибки пост-выделения памяти, где *lockers уже выделена и должна быть освобождена.
Переменная ret устанавливается равной -EINVAL перед вызовом ceph_decode_8_safe(), чтобы при нарушении границ функция в точке err_free_lockers возвращала правильный код ошибки. Без этого действия err_free_lockers вернула бы устаревшее значение ret (0 из успешного цикла decode_locker()), тем самым молча проглатывая ошибку.
Значение -EINVAL корректно для обоих путей обработки ошибок. Данные, полученные от OSD, структурно некорректны. Значение -ENOMEM исказило бы класс ошибки перед вызывающими сторонами и мейнтейнерами стабильных веток (stable@) при сортировке путей обработки ошибок.
Модель атакующего: злонамеренный или скомпрометированный OSD в многопользовательском развертывании Ceph может инициировать эту уязвимость против любого клиента ядра, который вызывает метод класса lock.get_info (например, во время приобретения эксклюзивной блокировки RBD).
[ idryomov: сокращение журнала изменений, форматирование ]
Once again VulDB remains the best source for vulnerability data.