在用户态中,我们可以通过execve()直接执行应用程序;那么,在内核态,我们是否可以直接调用用户态程序呢?答案是可以的,内核提供了一个函数:call_usermodehelpere,它可以帮助我们在内核就可以执行用户态的二进制程序。
这里写一个例子程序:
文件b.c:
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
static int __init call_usermodehelper_init(void)
{
int ret = -1;
char path[] = "/bin/mkdir";
char *argv[] = {path, "-p","/home/jian/new/new_dir", NULL};
char *envp[3];
envp[0] = "HOME=/";
envp[1] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
envp[2] = NULL;
printk("call_usermodehelper module isstarting..!\n");
ret = call_usermodehelper(path, argv, envp,UMH_WAIT_PROC);
printk("ret=%d\n", ret);
return 0;
}
static void __exit call_usermodehelper_exit(void)
{
int ret = -1;
char path[] = "/bin/rm";
char *argv[] = {path, "-r","/home/jian/new", NULL};
char *envp[3];
envp[0] = "HOME=/";
envp[1] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
envp[2] = NULL;
printk("call_usermodehelper module isstarting..!\n");
ret = call_usermodehelper(path, argv, envp,UMH_WAIT_PROC);
printk("ret=%d\n", ret);
}
module_init(call_usermodehelper_init);
module_exit(call_usermodehelper_exit);
MODULE_LICENSE("GPL");
Makefile:
obj-m += b.o
CURRENT_PATH:=$(shell pwd)
LINUX_KERNEL_PATH:=/lib/modules/$(shell uname -r)/build
all:
$(MAKE) -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) modules
clean:
rm -rf *.mod *.mod.c *ko *.mod.o *.a *.order *.symvers *.o
准备好这两个文件,执行make就可以编译出b.ko驱动。
我们安装驱动可以看到目录的创建,卸载驱动可以看到目录已经被卸载了:
jian@ubuntu:~/share/call$ sudo insmod b.ko
jian@ubuntu:~/share/call$ ls /home/jian/new/
new_dir
jian@ubuntu:~/share/call$ sudo rmmod b
jian@ubuntu:~/share/call$ ls /home/jian/new/
ls: cannot access '/home/jian/new/': No such file or directory
jian@ubuntu:~/share/call$