title:User mode helper keywords:kernel,linux,threads # User mode helper ## Adding usermode helper Here is diff of added new usermode helper ```diff diff --git a/kernel/sysctl.c b/kernel/sysctl.c index c6d9dec11..5d0b5b0ea 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -82,6 +82,8 @@ #include #endif +#include + /* shared constants to be used in various sysctls */ const int sysctl_vals[] = { 0, 1, 2, 3, 4, 100, 200, 1000, 3000, INT_MAX, 65535, -1 }; EXPORT_SYMBOL(sysctl_vals); @@ -2091,6 +2093,13 @@ static struct ctl_table kern_table[] = { .extra2 = SYSCTL_INT_MAX, }, #endif + { + .procname = "secret_parth", + .data = &sysctl_secret_path, + .maxlen = sizeof(sysctl_secret_path), + .mode = 0644, + .proc_handler = proc_dostring, + }, { } }; ``` create file __hacks.h__ under the __include/linux/hacks.h__ ```c static char sysctl_secret_path[256] = "/usr/bin/utility"; ``` Add to kernel and rebuild then run system with new kernel. After reboot there should be file at __/proc/sys/kernel__ ```sh /proc/sys/kernel/sysctl_secret_path ``` Now we can set values with echo and when kernel module executes the path will be executed ```sh echo "/usr/bin/utility" > /proc/sys/kernel/sysctl_secret_path ``` Lets write utility that dumps time to file at /tmp. Dump time utility ```c #include #include #include int main() { FILE *f=NULL; time_t t; struct tm *tm; char str[128]; f = fopen("/tmp/date","w+"); if (f == NULL) { printf("cannot create file\n"); } printf("Start utility\n"); printf("Date today\n"); time(&t); tm = localtime(&t); strftime(str, sizeof(str), "%A %c\n", tm); printf("Date %s\n", str); printf("Dump to file /tmp/date\n"); fwrite(str, strlen(str), 1, f); printf("Stop utility\n"); fclose(f); return 0; } ``` Compile and copy under the /usr/bin directory Call usermod helper from kernel module ## Kernel module starting point __usermod_helper.c__ ```c //http://www.tldp.org/LDP/lkmpg/2.4/html/c147.htm #include /* Needed by all modules */ #include int usermod_helper_init( void ) { printk(KERN_DEBUG "Hello World!\n"); return 0; } void usermod_helper_exit( void ) { printk(KERN_DEBUG "Exit Hello World!\n"); } module_init( usermod_helper_init ); module_exit( usermod_helper_exit ); MODULE_LICENSE("GPL"); ``` Call usermode helper from a driver ```c ... #include ... void run_usermode_helper(void) { char *argv[1]; char *envp[3]; int ret; //no args argv[0] = 0; //basic env envp[0] = "HOME=/"; envp[1] = "PATH=/sbin:/usr/sbin:/usr/bin"; envp[2] = 0; ret = call_usermodehelper(argv[0], argv, envp, 0); } int usermode_helper_init( void ) { printk(KERN_DEBUG "Hello usermode!\n"); run_usermode_helper(); return 0; } ``` Run ```sh sudo insmod usermode_helper.ko ``` Now there should be file /tmp/date that is created with utility called by driver ## Links https://www.raspberrypi.com/documentation/computers/linux_kernel.html#updating-your-kernel