Is there a way for the kernel module to find the partition addresses of another loaded module?

On an x86 system, I have a Linux kernel module (“observer module”) that gets the kernel every time a particular kernel module (“target”) loads. Almost any kernel module can be the target. I use this in the tooling system I'm working on.

When an observer module processes such a notification, it may be convenient for some reason if the observer knew the addresses of the ELF sections of the loaded target module. Any ideas on how this information can be obtained in kernel space?

Of course, I could probably get the contents of the corresponding files in /sys/module/<target_name>/sections/ in user space as soon as the target is loaded, and then somehow transfer this data to the observer module, but this is too much awkwardly. I would like to find a way to get this information directly in kernel space.

As far as I saw in the sources of the module loader, it does not save the addresses of the sections in the struct module , it simply creates sysfs files for the sections. Maybe you can somehow find the kernel objects corresponding to these files and read the necessary data from these objects? Or perhaps use some other approach?

+8
x86 linux-kernel kernel kernel-module
source share
2 answers

After you learn how information about module sections gets into sysfs, I have not found a way to get it without using the structure definitions internal to the kernel. The use of such material is not an option in my project, so I finally implemented a different approach, which, I hope, is more reliable.

In short, the idea is this. My kernel module uses the user mode helper API to start the user space process (it is actually a shell that runs my script). This process takes the name of the "target" kernel module as a parameter and collects information about its sections from sysfs ( /sys/module/<target_name>/sections/ ). This information can be easily obtained from user space. After that, it passes the collected data to my kernel module as a string through a file in debugfs. The module analyzes the string and checks its contents. If everything is in order, the names and start addresses of the ELF sections will be available.

I admit that the trick with the user mode assistant is pretty awkward, but it does its job.

I prepared an example of the implementation of the approach described above - see the "Sections" example .

For more information on the user mode API, see the code in <linux/kmod.c> and <linux/kmod.h> in the kernel sources, namely the definition of call_usermodehelper() . Examples, as well as an explanation of typical API usage, are available in this article .

Note that the examples in this article are a little inaccurate: the module init function returns the result of call_usermodehelper() . The latter, however, returns a 2-byte status code (at least when called with UMH_WAIT_PROC ), not the 0 or negative error code that the init function is expected to return. This can lead to runtime warnings. What call_usermodehelper() really returns is explained here .

+5
source share

The linux / kernel / module.c file has some non-static functions (but without this EXPORT_SYMBOL in front), such as module_address_lookup (), but these functions use things like preempt_disable () and _enable (). I would prefer not to use these functions and would suggest using the sysfs interface instead if your driver is already in kernel mode.

+1
source share

All Articles