⚬ Concept
- Creating Kernel Thread
- Fork by call 'do_fork' directly (because, this is inside kernel!)
- Exec by call 'do_execve'
⚬ Code walkthrough
• kmod.h
call_usermodehelper / call_usermodehelper_fns
call_usermode_helper_setup(...)
call_usermode_helper_setfns(...)
call_usermodehelper_exec(...)
• kmod.c
call_usermode_helper_setup()
-> setup subprocess infos.
: path to execute, arguments, env variables etc
-> set 'work' function of 'workqueue' to '__call_usermodehelper'
: INIT_WORK(&sub_info->work, __call_usermodehelper);
call_usermode_helper_setfns()
-> setup subprocess functions
call_usermodehelper_exec()
-> queue this work to 'khelper_wq' workqueue.
__call_usermodehelper() /* <- in work queue (khelper_wq) */
pid = kernel_thread(___call_usermodehelper, sub_info, CLONE_VFORK | SIGCHILD);
kernel_thread(...)
: set pc to 'kernel_thread_helper'- assembly function
pid = do_fork(flags|CLONE_VM|CLONE_UNTRACED, 0, ®s, 0, NULL, NULL);
kernel_thread_helper
: Shuffle the arument into the correct register before calling the thread function
: set pc to given thread function (in this example, '___call_usermodehelper()' function.)
___call_usermodehelper()
kernel_execve(sub_info->path, sub_info->argv, sub_info->envp);
• sys_arm.c
kernel_execve()
do_execve(...)
: make it to user space process!