Есть ли способ для модуля ядра найти адреса разделов другого загруженного модуля? - PullRequest
8 голосов
/ 21 октября 2011

В системе x86 у меня есть модуль ядра Linux («модуль-наблюдатель»), который получает уведомление от ядра каждый раз, когда загружается определенный модуль ядра («цель»).Практически любой модуль ядра может быть целью.Я использую это в системе инструментов , над которой я работаю.

Когда модуль-наблюдатель обрабатывает такое уведомление, по какой-то причине было бы удобно, если бы наблюдатель знал адреса секций ELFзагруженный целевой модуль.Любые идеи, как эта информация может быть получена в пространстве ядра?

Конечно, я мог бы, вероятно, получить содержимое соответствующих файлов в /sys/module/<target_name>/sections/ в пространстве пользователя, как только цель будет загружена, и затем каким-то образом передать эти данныек модулю наблюдателя, но это слишком неуклюже.Я хотел бы найти способ получить эту информацию непосредственно в пространстве ядра.

Насколько я видел в источниках загрузчика модулей, он не хранит адреса разделов в struct module, просто создаетsysfs файлы для разделов.Может быть, можно как-то найти объекты ядра, соответствующие этим файлам, и прочитать нужные данные из этих объектов?Или, возможно, использовать какой-то другой подход?

Ответы [ 2 ]

5 голосов
/ 06 ноября 2011

После изучения того, как информация о разделах модуля попадает в sysfs, я не нашел способа извлечь ее без использования внутренних структур ядра.Использование такого материала не является опцией в моем проекте, поэтому я наконец-то реализовал другой подход, который, надеюсь, более надежен.Мой модуль ядра использует вспомогательный API пользовательского режима для запуска процесса в пользовательском пространстве (фактически, это оболочка, выполняющая мой скрипт).Этот процесс получает имя «целевого» модуля ядра в качестве параметра и собирает информацию о его разделах из sysfs (/sys/module/<target_name>/sections/).Из пространства пользователя эту информацию можно легко получить.После этого он передает собранные данные моему модулю ядра в виде строки через файл в debugfs.Модуль анализирует строку и проверяет ее содержимое.Если все в порядке, имена и начальные адреса секций ELF будут доступны.

Признаюсь, уловка с помощником пользовательского режима довольно неуклюжа, но она выполняет свою работу.

Я подготовил пример реализации описанного выше подхода - см. Пример «Разделов» .

Подробнее о вспомогательном API пользовательского режима см. Код в <linux/kmod.c> и * 1013.* в исходниках ядра, а именно в определении call_usermodehelper().Примеры, а также объяснения типичного использования API доступны в этой статье .

Обратите внимание, что примеры из , в которых статья немного неточна: функция init модуля возвращает там результат call_usermodehelper().Последний, однако, возвращает 2-байтовый код состояния (по крайней мере, когда вызывается с UMH_WAIT_PROC), а не 0 или отрицательный код ошибки, который должна вернуть функция init.Это может привести к предупреждениям во время выполнения.Что call_usermodehelper() на самом деле возвращает, объясняется здесь .

1 голос
/ 21 октября 2011

Файл linux / kernel / module.c имеет некоторые нестатические функции (но без этого EXPORT_SYMBOL спереди), такие как module_address_lookup (), но эти функции используют такие вещи, как preempt_disable () и _enable (). Я бы предпочел не использовать эти функции и предложил бы вместо этого использовать sysfs-интерфейс, хотя ваш драйвер уже находится в режиме ядра.

...