際際滷

際際滷Share a Scribd company logo
Anatomy of the Loadable
Kernel Module (LKM)
Adrian Huang
Agenda
 From insmod command
 Call path for LKMs init function
 .gnu.linkonce.this_module section
 Deep Dive into call path
 modinfo
Note
 Kernel source: 5.10
 Mainly focus on the init function call path
From `insmod` command
Hello World Kernel Module strace
finit_module() system call loads an ELF image into kernel space
From `insmod` command
Hello World Kernel Module strace
finit_module() system call loads an ELF image into kernel space
finit_module()
 Load an ELF image into kernel space
 Perform symbol relocations
 Initialize module parameters to values
 Run the modules init function
Call path for LKMs init function
finit_module
load_module
do_init_module
do_one_initcall(mod->init)
mod->init();
Analysis
 Key: mod->init()
 How to assign the address of mod->init()?
kernel_read_file_from_fd
elf_header_check
setup_load_info
blacklisted(info->name)?
cleanup & return
module_sig_check
Y
N
mod = layout_and_allocate(info, ..)
rewrite_section_headers
apply_relocations
.gnu.linkonce.this_module section (1/6)
.gnu.linkonce.this_module section (2/6)
.gnu.linkonce.this_module section (3/6)
.gnu.linkonce.this_module section (4/6)
User Space Tool  modpost: Generate a file module_name.mod.c when
compiling your kernel module
.gnu.linkonce.this_module section - Where is
init_module() definition? (5/6)
Hello World Kernel Module module_init() macro
__init macro
.gnu.linkonce.this_module section (6/6)
Deep Dive into call path (1/7)
finit_module
load_module
do_init_module
do_one_initcall(mod->init)
mod->init();
kernel_read_file_from_fd
elf_header_check
setup_load_info
blacklisted(info->name)?
cleanup & return
module_sig_check
Y
N
mod = layout_and_allocate(info, ..)
rewrite_section_headers
apply_relocations
ELF Header
Section 1
.init.text
.exit.text
.gnu.linkonce.this_module

Section n
Section Header 1
.init.text
.exit.text
.gnu.linkonce.this_module

Section Header n
load_info
name
mod
hdr
len
sechdrs
secstrings
strtab
A (kernel addr)
A + e_shoff
finit_module
load_module
do_init_module
do_one_initcall(mod->init)
mod->init();
kernel_read_file_from_fd
elf_header_check
setup_load_info
blacklisted(info->name)?
cleanup & return
module_sig_check
Y
N
mod = layout_and_allocate(info, ..)
rewrite_section_headers
apply_relocations
ELF Header
Section 1
.init.text
.exit.text
.gnu.linkonce.this_module

Section n
Section Header 1
.init.text
.exit.text
.gnu.linkonce.this_module

Section Header n
load_info
name
mod
hdr
len
sechdrs
secstrings
strtab
A (kernel addr)
A + e_shoff
Deep Dive into call path (2/7)
finit_module
load_module
kernel_read_file_from_fd
elf_header_check
setup_load_info
blacklisted(info->name)?
cleanup & return
module_sig_check
Y
N
rewrite_section_headers
ELF Header
Section 1
.init.text
.exit.text
.gnu.linkonce.this_module

Section n
Section Header 1
.init.text
.exit.text
.gnu.linkonce.this_module

Section Header n
load_info
name
mod
hdr
len
sechdrs
secstrings
strtab
A (kernel addr)
A + e_shoff
for (i = 1; i < info->hdr->e_shnum; i++)
Elf_Shdr *shdr = &info->sechdrs[i];
shdr->sh_addr = (size_t)info->hdr +
shdr->sh_offset;
Deep Dive into call path (3/7)
Update sh_addr (virtual address) of each section header table based on
address A
Update sh_addr (virtual address) of each section header table
based on core/init section memory allocation
module

init
core_layout
init_layout
exit

module_layout
base
size
text_size
ro_size
ro_after_init_size
.init.text
.symtab
.strtab
Init section memory allocation
0xffffffffc0819000
0xffffffffc081a000
0xffffffffc081a000
module_layout
base
size
text_size
ro_size
ro_after_init_size
Deep Dive into call path (4/7)
module

init
core_layout
init_layout
exit

module_layout
base
size
text_size
ro_size
ro_after_init_size
.symtab
.strtab
Init section memory allocation
0xffffffffc0819000
0xffffffffc081a000
0xffffffffc081a000
module_layout
base
size
text_size
ro_size
ro_after_init_size
init_module
.init.text
Deep Dive into call path (5/7)
module

init
core_layout
init_layout
exit

module_layout
base
size
text_size
ro_size
ro_after_init_size
.symtab
.strtab
Init section memory allocation
0xffffffffc0819000
0xffffffffc081a000
0xffffffffc081a000
module_layout
base
size
text_size
ro_size
ro_after_init_size
init_module
.init.text
Deep Dive into call path (6/7)
Deep Dive into call path (7/7)
finit_module
load_module
do_init_module
do_one_initcall(mod->init)
mod->init();
kernel_read_file_from_fd
elf_header_check
setup_load_info
blacklisted(info->name)?
cleanup & return
module_sig_check
Y
N
mod = layout_and_allocate(info, ..)
rewrite_section_headers
apply_relocations
free & cleanup init_layout
Free memory space of init_layout after calling mod->init()
modinfo
Key=Value format in .modinfo section

More Related Content

Anatomy of the loadable kernel module (lkm)