Loading Modules

The real difficulties are encountered when implementing load_module — the kernel comment ''do all the hard work'' for the function is quite right. This is a very comprehensive function (with more than 350 lines) that assumes the following tasks:

□ Copying module data (and arguments) from userspace into a temporary memory location in kernel address space; the relative addresses of the ELF sections are replaced with absolute addresses of the temporary image.

□ Finding the positions of the (optional) sections

□ Ensuring that the version control string and the definition of struct module match in the kernel and module

□ Distributing the existing sections to their final positions in memory

□ Relocating symbols and resolving references. Any version control information linked with the module symbols is noted.

□ Processing the arguments of the module load_module is the cornerstone of the module loader, which is why I deal in greater detail with the most important code sections.

The information below makes frequent reference to special features of the ELF format. The data structures made available for this format by the kernel are also often used. Appendix E discusses both in detail.

kernel/module.c static struct module *load_module(void _user *umod, unsigned long len, const char __user *uargs)

Elf_Ehdr *hdr; Elf_Shdr *sechdrs;

char *secstrings, *args, *modmagic, *strtab = NULL;

unsigned int i;

unsigned int symindex = 0;

unsigned int strindex = 0;

unsigned int setupindex;

unsigned int exindex;

unsigned int exportindex;

unsigned int modindex;

unsigned int obsparmindex;

unsigned int infoindex;

unsigned int gplindex;

unsigned int crcindex;

unsigned int gplcrcindex;

if (copy_from_user(hdr, umod, len) != 0) { err = -EFAULT; goto free_hdr;

/* Convenience variables */ sechdrs = (void *)hdr + hdr->e_shoff;

secstrings = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;

Once a large number of variables has been defined, the kernel loads the module binary data into kernel memory using copy_from_user (I have dispensed with some index variables for ELF sections and information on error handling — and will do so in the following sections — so as not to add unnecessarily to the volume of this description).

hdr then points to the start address of the binary data, in other words, to the ELF header of the module.

sechdrs and secstring are set so that they point to the positions in memory where information on the existing ELF sections and the string table with the section names is located. The relative value in the ELF header is added to the absolute address of the module in the kernel address space to determine the correct position (we will come across this procedure frequently).

Continue reading here: Rewriting Section Addresses

Was this article helpful?

0 0