【问题标题】:Cannot printk user space string parameter when intercepting a syscall拦截系统调用时无法打印k用户空间字符串参数
【发布时间】:2021-08-25 02:03:13
【问题描述】:

我正在尝试拦截 Linux 系统调用以将所有打开的文件名记录到日志文件中。但是有一个问题:它无法在用户空间中打印文件名。以下是假系统调用函数的代码:

static inline long hacked_open(const char __user *filename, int flags, umode_t mode)
{
    char buf[256];
    buf[255] = '\0';

    long res = strncpy_from_user(buf, filename, 255);
    if (res > 0)
        printk("%s\n", buf);
    else
        printk("---err len : %ld ---\n", res);

    orig_func a = (orig_func)orig_open;

    return a(filename, flags, mode);
}

在我加载内核模块后,dmesg 显示了很多信息:

---err len : -14---

我已经尝试过 copy_from_user 并直接 printk 文件名,但它们都不起作用。

【问题讨论】:

  • 这是由你自己调用open()的程序触发的,还是系统上的随机活动触发的?可能是您的机器上确实有一些错误程序调用open(),而filename 的指针无效。如果是这样,除了记录它并让它失败之外,没什么可做的。
  • 我尝试拦截另一个系统调用 ( mkdir ) 以打印 k 路径名,但它仍然不起作用。所以我认为这个问题与 syscall open 无关。
  • 所以也许你的拦截代码搞砸了,你在filename 参数中得到的不是用户空间传递给系统调用的东西。您可以通过调用系统调用的测试程序来确认这一点;比较它传入的指针和你的处理程序接收的指针。
  • 没有。我不认为拦截代码搞砸了,它在调用 origin syscall 函数时运行良好。

标签: linux-kernel system-calls


【解决方案1】:

我自己解决了这个问题。

hacked_open 的参数错误。

正确的 hacked_openat 应该是:

asmlinkage long hacked_openat(struct pt_regs *regs)

我们可以像这样从用户空间获取文件名:

int nRet = strncpy_from_user(filename, (char __user *)regs->si, 1024);

【讨论】:

    猜你喜欢
    • 2014-01-22
    • 1970-01-01
    • 2022-07-07
    • 2015-10-04
    • 2021-07-06
    • 2012-02-27
    • 2012-05-28
    • 1970-01-01
    • 2010-09-09
    相关资源
    最近更新 更多