3

In my quest to learn about Linux kernel, I have written a module, which overrides a system call sys_open with my custom (custom_sys_open) function. Code for my custom_file_open :-

#define CUSTOM_CHECK_FILE "/home/xxxx/Programming/kernel_module/custom.txt"
asmlinkage long custom_file_open(const char __user *fileName, int flags, umode_t mode)
{
    long retVal = 0;
    int len = strlen(fileName);
    if(strcmp(fileName+len-9,"check.txt")== 0){
       retVal= (*orig_file_open)(CUSTOM_CHECK_FILE, flag, mode);
    }
    return retVal;
}

It doesn't work and retVal is always -14 in this case. However if I just copy CUSTOM_FILE_CHECK string into "fileName" it starts working as in code below :-

asmlinkage long custom_file_open(const char __user *fileName, int flags, umode_t mode)
{
    long retVal = 0;
    int len = strlen(fileName);
    if(strcmp(fileName+len-9,"check.txt")== 0){
       memcpy((void*)fileName, (void*)CUSTOM_CHECK_FILE, strlen(CUSTOM_CHECK_FILE));
       retVal = (*orig_file_open)(fileName, flag, mode);
    }
    return retVal;
}

It works as expected. But I am unable to understand :-

  1. What is wrong with previous custom file open function ?
  2. Am I doing anything wrong while passing parameter to original file open syscall ?

Please help me understand this.

1 Answers1

2

Here you are trying to pass a memory allocated in kernel space to a syscall whereas a syscall expects memory allocated in userspace. I don't know how to allocate memory in user space from kernel space but I think this link (Allocating memory for user space from kernel thread) sheds some light over it. There is another way to do the thing, that you are trying to do, is to disable memory address validity check. To do so try following code :-

mm_segment_t orig_fs = get_fs();
set_fs(KERNEL_DS);
retVal= (*orig_file_open)(CUSTOM_CHECK_FILE, flag, mode);
set_fs(orig_fs);
Community
  • 1
  • 1
Efficience
  • 111
  • 5