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