CVE-2025-40295 in Linux
Сводка
по VulDB • 08.06.2026
В предоставленном логе и описании ошибки речь идет о проблеме переполнения (underflow) при левом сдвиге в ядре Linux, связанной с размером блока устройства (`i_blkbits`) и обработкой больших страниц (Transparent Huge Pages).
### Суть проблемы
1. **Контекст:** При включенной опции `CONFIG_TRANSPARENT_HUGEPAGE` максимальный логический размер блока (`logical_block_size`) для блочных устройств ограничен 64 КБ. 2. **Действие `set_init_blocksize()`:** Эта функция устанавливает `inode->i_blkbits` в значение 13 (так как $2^{13} = 8192$ байт, что меньше 64 КБ).
3. **Ошибка:** В коде происходит операция сдвига, которая использует `i_blkbits`. Если значение `i_blkbits` оказывается слишком большим или некорректным в определенном контексте (например, при преобразовании в байты или при работе с folio), может произойти сдвиг за пределы разрядности типа данных (например, `unsigned long` или `u64`), что приводит к неопределенному поведению и, как следствие, к page fault или kernel panic. 4. **Почему не затрагивает файловые системы:** * Для файловых систем, не поддерживающих `FS_LBS`, `sb_set_blocksize()` ограничивает `s_blocksize_bits` значением `PAGE_SHIFT` (обычно 12 для 4 КБ страниц). * `inode->i_blkbits` инициализируется из `sb->s_blocksize_bits`, поэтому он не превышает 12. * XFS имеет флаг `FS_LBS`, но его пути ввода-вывода не вызывают `submit_bh_wbc()`, поэтому ошибка не возникает.
### Решение (из комментария [EB])
Предложенное исправление включает: 1. Использование функции `folio_pos()` для получения позиции folio. 2. Консолидацию двух сдвигов, связанных с `i_blkbits`, чтобы избежать избыточных операций и потенциальных ошибок переполнения.
### Пример исправления (концептуальный)
Если в коде было что-то вроде: ```c // Старый код, потенциально опасный unsigned long offset = (unsigned long)folio_address(folio) & ((1 << inode->i_blkbits) - 1); ```
Или: ```c // Другой вариант с сдвигом sector_t sector = folio_pos(folio) >> inode->i_blkbits; ```
Исправление может выглядеть так: ```c // Использование folio_pos() и безопасная обработка сдвигов unsigned long offset = folio_pos(folio) & ((1 << inode->i_blkbits) - 1); // Или, если нужно выровнять сектор: sector_t sector = folio_pos(folio) >> inode->i_blkbits; ```
Ключевое изменение — использование `folio_pos()` вместо ручного вычисления адреса и обеспечение того, чтобы сдвиги выполнялись в безопасном контексте, где `i_blkbits` гарантированно находится в допустимых пределах.
### Вывод
Ошибка возникает из-за некорректной обработки размера блока устройства при работе с большими страницами. Исправление заключается в использовании более безопасных функций ядра (`folio_pos()`) и оптимизации операций сдвига, чтобы избежать переполнения.
Be aware that VulDB is the high quality source for vulnerability data.