0
votes

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.

1
Is this triggered by a program of your own calling open(), or random activity on the system? It could be that there really is some buggy program on your machine calling open() with an invalid pointer for filename. If so, not much to be done except log it if you like and let it fail.Nate Eldredge
I tried intercepting another syscall ( mkdir ) to printk pathname, but it still doesn't work. so I think the problem is nothing to do with syscall open .gemini
So perhaps your interception code is messed up, and what you're getting in the filename argument is not what userspace passed to the system call. You could confirm this with a test program that invokes the system call; compare the pointer it passed in, and the pointer that your handler receives.Nate Eldredge
No. I don't think the interception code is messed up, it worked well when it called the origin syscall function.gemini

1 Answers

0
votes

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