Linux kernel allows you to have discardable sections in LKM and this creates problem of links between two kind of memory. As you can guess keeping pointer to already unloaded area can be very dangerous so I made simple tool kotest to check such kind of links. It divides sections of ELF file into two category and check all relocations - relocs between areas of the same type considered as ok. To keep track if some symbol from persistent area is used only from discardable sections I also use couple of reference counts
command line options
- -b take into account variables in .bss
- -h make hexdump of found vars
- -v verbose mode
find path_to_kernel_root -type f -name "*.ko" | xargs kotest
it is reliable to use for analysis only fixups?
.init.text:0000000000016155 mov rdi, offset ip_vs_genl_family
.init.text:000000000001615C mov cs:ip_vs_genl_family.module, offset __this_module
.init.text:0000000000016167 mov cs:ip_vs_genl_family.ops, offset ip_vs_genl_ops
.init.text:0000000000016172 mov cs:ip_vs_genl_family.mcgrps, 0
.init.text:000000000001617D mov qword ptr cs:ip_vs_genl_family.n_ops, 10h
.init.text:0000000000016188 call __genl_register_family
.rodata + 5A0 (ip_vs_genl_ops) rref 1 xref 0 add size 768
why not use famous objtool?
LKM loading
- layout_and_allocate collects sections and allocates persistent and discardable modules memory in function layout_sections
- find_module_sections is the most important bcs it fills module structure with lots of pointers to content of section for further processing
- post_relocations from where arch-specific module_finalize are called
- do_init_module calls init function of module and frees discardable memory by inserting new task into init_free_list
Mod[60] 0xffffffffc0454300 base 0xffffffffc0451000 serio_raw
init: 0xffffffffc037e000 - nls_iso8859_1!uni2char
exit: 0xffffffffc0451b8a - serio_raw!serio_raw_drv_exit
ls -1a /sys/module/serio_raw/sections | grep init
.init.text
What sections considered by kernel as discardable?
- ".altinstructions" - processing inside apply_alternatives called from module_finalize <- post_relocation <- load_module before do_init_module
- under Risc-V for unknown reason it has name ".alternative"
- from the same function module_finalize also ".retpoline_sites", ".return_sites" etc
However this not all. Let's check function do_mod_ctors. Field module->ctors can point to section ".init.array" (which is considered as discardable) or to ".ctors" (which is not). Logic? Haven't heard
Which data from discardable sections kernel able to clean up?
If the exception table is sorted, any referring to the module init will be at the beginning or the end.The problem is that exception table (stored in module->extable) is always sorted in post_relocation
Комментариев нет:
Отправить комментарий