usermodehelper在Linux内核中直接运行用户空间程序(3)

     call_usermodeheler函数创建的新程序实际上作为keventd内核线程的子进程运行,因此具有root权限。

      新程序被扔到内核工作队列“khelper”中进行执行。

      如果使用UMH_NO_WAIT,那么因为没有在事件队列上等待和唤醒的过程,因此可以在中断上下文中使用。

     它的返回值是新程序的返回值。


call_usermodeheler函数的参数用法和execve函数一致

#include<unistd.h>

intexecve(const char *filename, char *const argv[],
char*const
 envp[]);

execve函数使用sys_execve系统调用,创建并运行一个程序。

argv是字符串数组,是将被传输到新程序的参数。

envp是字符串数组,格式是key=value,是传递给新程序的环境变量。

argvenvp都必须以NULL字符串结束。以此来实现对字符串数组的大小统计。



     这就意味着,argv的第一个参数也必须是程序名。也就是说,新程序名要在execve函数的参数中传递两次。



     这和main函数传入的参数格式也是一致的。



使用call_usermodehelper在内核态创建和运行用户空间程序的示例



/*

============================================================================

Name : testDriver1.c

Author :Edward Shenshendl_s@hotmail.com

Version :

Copyright : Your copyrightnotice

Description : Hello World in C,Ansi-style

============================================================================

*/


#include<linux/init.h>

#include<linux/module.h>

#include<linux/moduleparam.h>

//#include<linux/config.h>


#include<linux/kernel.h>/*printk()*/

#include<linux/sched.h>

MODULE_LICENSE("DualBSD/GPL");



static__initinttestDriver1_init(void){

     intresult=0;

     char cmdPath[]="/usr/bin/touch";

     char* cmdArgv[]={cmdPath,"/touchX.txt",NULL};

     char* cmdEnvp[]={"HOME=/",

"PATH=/sbin:/bin:/usr/bin",NULL};

      result=call_usermodehelper(cmdPath,cmdArgv,cmdEnvp,UMH_WAIT_PROC);

      printk(KERN_DEBUG"testDriver1_initexec!Theresult of call_usermodehelper is %d\n",result);

      printk(KERN_DEBUG"testDriver1_initexec!Theprocess is \"%s\",pidis %d ,sys_getpid is %d \n",current->comm,current->pid);

      returnresult;

}



static__exitvoidtestDriver1_exit(void){

      intresult=0;

      char cmdPath[]="/bin/rm";

      char* cmdArgv[]={cmdPath,"/touchX.txt",NULL};

      char* cmdEnvp[]={"HOME=/",

"PATH=/sbin:/bin:/usr/bin",NULL};

      result=call_usermodehelper(cmdPath,cmdArgv,cmdEnvp,UMH_WAIT_PROC);

      printk(KERN_DEBUG"testDriver1_exitexec!Theresult of call_usermodehelper is %d\n",result);

      printk(KERN_DEBUG"testDriver1_exitexec!Theprocess is \"%s\",pidis %d \n",current->comm,current->pid);

}


module_init(testDriver1_init);

module_exit(testDriver1_exit);



编译上述模块的命令

make-C /lib/modules/`uname -r`/build M=`pwd` modules


然后使用insmodrmmod命令加载和卸载驱动。可以看到上述命令创建了文件和删除了创建的文件。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wwjxsp.html