Подробности
[В начало]
Проблема в реализации № K0005
Краткое описание
(ath5k) Не все элементы массива chinfo[pier].pd_curves[] освобождаются
Подробное описание
Некоторые из блоков памяти, выделенных с помощью kcalloc() в ath5k_eeprom_convert_pcal_info_*(), не удаляются даже при выгрузке модуля ath5k.
Трасса вызовов функций для одной итерации внешнего цикла 'for' в
ath5k_eeprom_convert_pcal_info_2413(),
drivers/net/wireless/ath/ath5k/eeprom.c:1148:
// Создание chinfo[pier].pd_curves, строка 1153. // Выделена память под 4 элемента типа struct ath5k_pdgain_info. called___kmalloc: (.text+0x212f) arguments: (48, 80d0), result: ab3ad780 // Внутренний цикл, итерация 0, // создание pd->pd_step и pd->pd_pwr // для chinfo[pier].pd_curves[pdgain_idx[0]] (строки 1176 and 1182) called___kmalloc: (.text+0x212f) arguments: (4, 80d0), result: ab1c3f68 called___kmalloc: (.text+0x212f) arguments: (8, 80d0), result: ab1c3f70 // Внутренний цикл, итерация 1, // создание pd->pd_step и pd->pd_pwr // для chinfo[pier].pd_curves[pdgain_idx[1]] (строки 1176 and 1182) called___kmalloc: (.text+0x212f) arguments: (5, 80d0), result: ab1c3f78 called___kmalloc: (.text+0x212f) arguments: (10, 80d0), result: ab17ce80 <...>
Трасса вызовов функций для одной итерации внешнего цикла 'for' в
ath5k_eeprom_free_pcal_info(),
drivers/net/wireless/ath/ath5k/eeprom.c:1564:
// Внутренний цикл, итерация 0, строка 1573 called_kfree: (.text+0x20be) arguments: ((null)) called_kfree: (.text+0x20c6) arguments: ((null)) // Внутренний цикл, итерация 1, line 1573 called_kfree: (.text+0x20be) arguments: (ab1c3f78) called_kfree: (.text+0x20c6) arguments: (ab17ce80) // Удаление массива chinfo[pier].pd_curves called_kfree: (.text+0x20de) arguments: (ab3ad780) <...>
Аналогично - для остальных итераций внешних циклов 'for' в ath5k_eeprom_convert_pcal_info_*() и ath5k_eeprom_free_pcal_info().
ath5k_eeprom_free_pcal_info() пытается освободить поля 'pd_step' и 'pd_pwr' не для тех элементов, для которых это нужно.
На системе, где проявилась данная проблема, массив chinfo[pier].pd_curves[] состоял из 4 (AR5K_EEPROM_N_PD_CURVES) элементов, из которых использовались на практике только 2, №1 и №2, как и должно было быть. Элементы №0 и №3 оставались заполненными нулями.
Строка 1162:for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) { u8 idx = pdgain_idx[pdg]; struct ath5k_pdgain_info *pd = &chinfo[pier].pd_curves[idx];
ee->ee_pd_gains[mode] было равно 2, массив pdgain_idx[] был {1; 2}. Судя по коду из eeprom.c, именно эти элементы и использовались в во всех операциях калибровки и пр.
Функция ath5k_eeprom_free_pcal_info(), тем не менее, работает по-другому. Она пытается освободить 'pd_step' и 'pd_pwr' для первых двух элементов массива chinfo[pier].pd_curves вместо тех двух элементов, для которых была выделена память:
for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) { struct ath5k_pdgain_info *pd = &chinfo[pier].pd_curves[pdg]; if (pd != NULL) { kfree(pd->pd_step); kfree(pd->pd_pwr); } }
Т.е., здесь обрабатываются элементы pd_curves[0] и pd_curves[1] вместо pd_curves[pdgain_idx[0]] и pd_curves[pdgain_idx[1]].
Способ воспроизведения
Чтобы воспроизвести проблему, достаточно загрузить модуль ath5k.ko, а затем выгрузить его.
Способы устранения
eeprom.c:1568: - for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) { + for (pdg = 0; pdg < AR5K_EEPROM_N_PD_CURVES; pdg++) { struct ath5k_pdgain_info *pd = &chinfo[pier].pd_curves[pdg];
Компонент
linux-kernel 2.6.39-rc2
Ссылки
Problems found by KEDR
Начало обсуждения: Kernel Bug Tracker, bug #32722
Принято
Kernel Bug Tracker, bug #32942
Статус
Исправлено в ядре 3.0
[В начало]