在我学习Linux内核的过程中,我写了一个模块,用我的自定义(custom_sys_open)函数覆盖了系统调用sys_open。 代码为我的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; }
在这种情况下,它不起作用,retVal总是-14。 但是,如果我只是复制CUSTOM_FILE_CHECKstring到“文件名”它开始工作,如下面的代码: –
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; }
它按预期工作。 但我无法理解:
请帮我理解这一点。
在这里,您正试图将在内核空间中分配的内存传递给系统调用,而系统调用期望在用户空间中分配内存。 我不知道如何从内核空间分配用户空间中的内存,但是我认为这个链接( 从内核线程分配用户空间的内存 )对它有一些指示。 还有另外一种方法可以做,那就是要禁用内存地址有效性检查。 要做到这一点尝试下面的代码: –
mm_segment_t orig_fs = get_fs(); set_fs(KERNEL_DS); retVal= (*orig_file_open)(CUSTOM_CHECK_FILE, flag, mode); set_fs(orig_fs);