从 Linux 内核模块发出运行进程

从 Linux 内核模块发出运行进程

我正在尝试运行位于内核模块中的进程/usr/bin,并且我正在使用call_usermodehelper().在我的模块中,我有:

int rc;

char *argv[] = {"/usr/bin/myProgram", NULL};
char *envp[] = {"HOME=/", NULL};

rc = call_usermodehelper(argv[0], argv, envp, UMH_WAIT_EXEC);

printk("RC is: %i \n", rc);

我的示例程序/usr/bin

#include <stdio.h>
#include <string.h>
#include <unistd.h>

int main(){

    char *arg[] = {"firefox", "sample.html", NULL};
    execvp(arg[0], arg);
    return 0;
}

查看syslog后,我可以看到RC为0,这表明call_usermodehelper成功,但程序从未真正运行(它应该打开Firefox浏览器)。如果我手动遍历/usr/bin并运行该进程,它会正常工作并执行预期的行为。不太确定为什么会发生这种情况,并且在网上找不到太多信息,有什么想法吗?

我找到了这个旧帖子:http://www.linuxquestions.org/questions/programming-9/call_usermodehelper-problem-849860/用户遇到了类似的问题,并声称像printf()和那样的调用system()不起作用,他通过使用修复了它exec(),我最初一直在这样做(他也使用了他的程序的目标文件,我也尝试过) :

int rc;

char *argv[] = {"/usr/bin/myProgram.o", NULL};
char *envp[] = {"HOME=/", NULL};

rc = call_usermodehelper(argv[0], argv, envp, UMH_WAIT_EXEC);

printk("RC is: %i \n", rc);

解决方案

在更多地使用它并看到一些关于需要显式声明环境变量的评论之后,因为我们位于内核中,我将我的内核模块更改为与此类似,现在正在打开浏览器call_usermodehelper()

int rc;

static char *envp[] = {
    "SHELL=/bin/bash",
    "HOME=/home/admin",
    "USER=admin",
    "PATH=/home/admin/bin:/home/admin/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/home/admin",
    "DISPLAY=:0",
    "PWD=/home/admin", 
    NULL};

char *argv[] = {"/home/admin/mySample", NULL};

rc = call_usermodehelper(argv[0], argv, envp, UMH_WAIT_EXEC);
printk("RC is: %i \n", rc);

示例程序现在看起来像:

#include <stdio.h>
#include <string.h>
#include <unistd.h>

int main()
{
    char *arg[] = {"firefox", "/home/admin/sample.html", NULL};
    execvp(arg[0], arg);
    return 0;
}

答案1

在更多地使用它并看到一些关于需要显式声明环境变量的评论之后,因为我们位于内核中,我将我的内核模块更改为与此类似,现在正在打开浏览器call_usermodehelper()

int rc;

static char *envp[] = {
    "SHELL=/bin/bash",
    "HOME=/home/admin",
    "USER=admin",
    "PATH=/home/admin/bin:/home/admin/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/home/admin",
    "DISPLAY=:0",
    "PWD=/home/admin", 
    NULL};

char *argv[] = {"/home/admin/mySample", NULL};

rc = call_usermodehelper(argv[0], argv, envp, UMH_WAIT_EXEC);
printk("RC is: %i \n", rc);

示例程序现在看起来像:

#include <stdio.h>
#include <string.h>
#include <unistd.h>

int main()
{
    char *arg[] = {"firefox", "/home/admin/sample.html", NULL};
    execvp(arg[0], arg);
    return 0;
}

相关内容