Подробности

[В начало]

Проблема в реализации № K0002

Краткое описание

(ext4) Вызов kfree для неинициализированного указателя в ext4_mb_init_backend

Подробное описание

В fs/ext4/mballoc.c:2389 выделяется память для массива for sbi->s_group_info. Элементы этого массива (тоже указатели) инициализируются при выполнении ext4_mb_add_groupinfo() (строка 2408).

Если по каким-то причинам ext4_mb_add_groupinfo() завершается с ошибкой (например, если не удаётся выделить память в строке 2296), ext4_mb_init_backend() вызывает kfree() для всех элементов массива sbi->s_group_info array, в т.ч. и тех, что ещё не были инициализированы (fs/ext4/mballoc.c:2414):

err_freebuddy:
    cachep = get_groupinfo_cache(sb->s_blocksize_bits);
    while (i-- > 0)
        kmem_cache_free(cachep, ext4_get_group_info(sb, i));
    i = num_meta_group_infos; 
    while (i-- > 0)
        kfree(sbi->s_group_info[i]); /* <= oops here */
    iput(sbi->s_buddy_cache);

Проблема проявилась при выполнении тестов для ext4 из Linux Test Project (точнее, ext4-alloc-test, test #7).

'num_meta_group_infos' (общее количество элементов массива) в данном случае было равно 12. Первые 2 вызова ext4_mb_add_groupinfo() (строка 2408) отработали успешно, 3-й завершился с ошибкой.

При выполнении kfree(sbi->s_group_info[11]) произошёл kernel oops.

Способы устранения

fs/ext4/mballoc.c:2389:
- sbi->s_group_info = kmalloc(array_size, GFP_KERNEL);
+ sbi->s_group_info = kzalloc(array_size, GFP_KERNEL);

Компонент

linux-kernel 2.6.38

Ссылки

Problems found by KEDR

Принято

Kernel Bug Tracker, bug #30872

Статус

Исправлено в ядре 2.6.39-rc1

[В начало]