Saturday, October 30, 2021

[SOLVED] Cannot printk user space string parameter when intercepting a syscall

Issue

I'm trying to intercept a Linux syscall to record all opened filename to a log file. but there's a problem: it failed to printk the filename in user space. Here are the codes of fake syscall function:

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);
}

after I loaded the kernel module, dmesg showed a lot of message as:

---err len : -14---

I've tried copy_from_user and printk the filename directly, but they all doesn't work.


Solution

I've solved this problem by myself.

the parameters of hacked_open are wrong.

the correct hacked_openat should be :

asmlinkage long hacked_openat(struct pt_regs *regs)

and we can get filename from user-space like this:

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



Answered By - gemini