I am trying to detect opening folder in a specific location (myPath). I am using strstr() but I see that my system is always crashed(picture) after executing this function. If I remove the check (if(ret)), it works as normal Here is my code:
struct task_struct *task_list;
struct fdtable * fdt = NULL;
unsigned int process_count = 0;
struct path files_path;
char *access_mode;
char *cwd;
int res;
char *myPath = "/home/anh/src/";
char *buf = (char *)kmalloc(GFP_KERNEL,100*sizeof(char));
char * ret;
for_each_process(task_list) {
fdt = files_fdtable(task_list->files);
int i=0;
while(fdt->fd[i] != NULL) {
files_path = fdt->fd[i]->f_path;
cwd = d_path(&files_path,buf,100*sizeof(char));
if(cwd){//Check if cwd != NULL
ret = strstr(cwd, myPath);//check seeked file path and myPath
if(ret)
{
printk(KERN_INFO "Open file with fd %d cwd: %s", i,cwd);
}
}
i++;
}
process_count++;
}
Could someone review and support me to solve this problem?, why the strstr() cannot be used in a Linux kernel module or is there other ways to verify that a string is in inside a string?
Best regards, Anh
A plausible explanation is that an error occurs, so cwd
is not a valid pointer. strstr
is called on this invalid pointer and crashes. Without if(ret)
, the strstr
call is optimized away so there's no crash.
Functions in the Linux kernel typically return an error code on error. The documentation of d_path
specifically states that this is the case.
Returns a pointer into the buffer or an error code if the path was too long.
if (cwd)
checks that cwd
is non-null. If cwd
contains an error code, it's non-null. So if (cwd)
is not a useful check. The correct error check for functions that return a pointer is IS_ERR()
.
cwd = d_path(&files_path,buf,100*sizeof(char));
if (IS_ERR(cwd)) {
printk(KERN_WARN "At i=%d: d_path -> %ld", i, PTR_ERR(cwd));
} else {
ret = strstr(cwd, myPath);