Hi everyone,

I am a Linux noob and have only recently started playing around with it. So, I apologize if this doubt seems immature.

I am trying to "hijack" some syscalls by modifying their function pointers in the syscall table to redirect access to my own functions where I preprocess the arguments before calling the original functions with possibly modified arguments. To get to the heart of the problem, I'll give an example of what happens for 2 syscalls - open and lstat.

Note that I am doing this by loading an LKM in a user-mode linux running off kernel version runnning in x86_64 mode.

All versions of sys_lstat accept two userland pointers - file-name and a struct where stat information is to be stored. What my function does is it checks the file-name and for some match, passes a different file-name (which is a kernel pointer) to the original sys_lstat version. A simplified version of the code is (ignore syntactic mistakes, if any):

asmlinkage long my_sys_lstat(const char __user *userland_filename, 
                                  struct __old_kernel_stat __user *statbuf) 
    int err;  
    struct path path; 
    bool modify_fs = false; 
    char* filename_param_to_orig = userland_filename; 
    mm_segment_t old_fs; 
    err = user_path_at(AT_FDCWD, userland_filename, 0, &path); 
    if (err)    return err; 
    if (file_match(path)) {    //compare inodes 
        // Modify DS before calling the original function with a kernel pointer 
        // as a param 
        modify_fs = true; 
        old_fs =  = get_fs(); 
        filename_param_to_orig = my_mod_filename; 
    err = orig_sys_lstat(filename_param_to_orig, statbuf); // doesn't return if file matches 
    if (modify_fs) 
    return err; 
On a file match, it all goes fine until control reaches memcpy called from copy_to_user method (eventually called from sys_lstat), where the kernel tries to copy into the userland struct from its own struct which is filled with (hopefully) the right info. In memcpy (arch/x86/lib/memcpy_64.S) the kernel completely freezes. If gdb is to be trusted, this freeze happens on line 70 in the instruction:

movq 0*8(%rsi), %r8
Unfortunately I am not very well versed with x86 architecture either, and I have not been able to figure why this freeze happens.

A similar implementation for sys_open is working for me (passing a kernel pointer to the original function after changing the data segment). I have also tried this in UML on an i386 system (courtesy virtualbox), and the result is the same (although the memcpy file is likely different).

Could anybody point out what's going wrong here or at least point me in a direction where I could look for it myself? Any help is much appreciated. Thanks a lot!