summaryrefslogtreecommitdiff
path: root/md/notes/kernel/usermode_helper.md
diff options
context:
space:
mode:
Diffstat (limited to 'md/notes/kernel/usermode_helper.md')
-rw-r--r--md/notes/kernel/usermode_helper.md164
1 files changed, 164 insertions, 0 deletions
diff --git a/md/notes/kernel/usermode_helper.md b/md/notes/kernel/usermode_helper.md
index dd8155a..5ac7532 100644
--- a/md/notes/kernel/usermode_helper.md
+++ b/md/notes/kernel/usermode_helper.md
@@ -3,6 +3,170 @@ 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 <linux/rtmutex.h>
+ #endif
+
++#include <linux/hacks.h>
++
+ /* 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 <stdio.h>
+#include <time.h>
+#include <string.h>
+
+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 <linux/module.h> /* Needed by all modules */
+#include <linux/kernel.h>
+
+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 <linux/hacks.h>
+...
+
+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
+
+
+