c - 如何从内核空间的用户空间指针中正确提取字符串?

标签 c linux linux-kernel system-calls

我为 execve 系统调用编写了一个钩子(Hook),在开始时我编写它来打印 "hi",每次执行文件时。它运行良好,但是当我尝试打印传递给系统调用的 filename 时,这导致了崩溃,当然我不得不重新启动计算机。

这是我的代码:

static asmlinkage long our_execl(const char __user * filename,
            const char __user * const __user * argv,
            const char __user * const __user * envp) {
    printk("%s\n",filename);
    return original_execl(filename, argv, envp);
}

这就是我注入(inject)新系统调用的方式:

static int lkm_example_init(void)
{

    printk("new new new 2");

    write_cr0(read_cr0()&(~ 0x10000));

    sys_call_table = (void*)0xdd8c4240//the syscall address from the   /proc/kallsyms ;

    execl= sys_call_table[__NR_execve];
    sys_call_table[__NR_execve]=our_execl;

    write_cr0(read_cr0() | 0X10000);
    return 0;
}

最佳答案

这里最有可能发生的是 SMAP ( Supervisor Mode Access Prevention ) 阻止内核访问原始用户空间指针,从而导致 panic 。

从用户空间访问字符串的正确方法是使用 strncpy_from_user() 复制其内容第一的。另外,请小心并确保正确终止字符串。

static asmlinkage long our_execl(const char __user * filename,
            const char __user * const __user * argv,
            const char __user * const __user * envp) {
    char buf[256];
    buf[255] = '\0';

    long res = strncpy_from_user(buf, filename, 255);
    if (res > 0)
        printk("%s\n", buf);

    return original_execl(filename, argv, envp);
}

在这种情况下,由于我们专门讨论文件名,您可以使用 getname()putname()函数,使用 struct filename 工作.

static asmlinkage long our_execl(const char __user * filename,
            const char __user * const __user * argv,
            const char __user * const __user * envp) {

    struct filename *fname = getname(filename);
    if (!IS_ERR(fname)) {
        printk("%s\n", fname->name);
        putname(fname);
    }

    return original_execl(filename, argv, envp);
}

关于c - 如何从内核空间的用户空间指针中正确提取字符串?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59772132/

相关文章:

python - 寻找一个工作的 linux 命令行工具从 rapidshare 下载

Linux 内核 3.13 : How to list gendisk's?

c - 为什么我在通过内核模块访问 GPIO2 和 GPIO3 时在 Beaglebone Black 上出现段错误?

c - sqlcxt() 导致段错误

C:为什么用 %s 打印空字符会打印 "(null)"?

c++ - 编译器错误 xcode 未声明的标识符 c++

当行 > 1 时,C dup2 会覆盖文件错误

linux - Tmux - 如何在更改 Pane 时自动执行命令?

linux - apache linux (centos 7) 上的网页未出现在我局域网的其他计算机上

c - Linux 内核 v5 中的 current_kernel_time 相当于什么?