Search code examples
clinux-kernelnullreferenceexceptionkernelsystem-calls

Linux Kernel Programming: “Unable to handle kernel NULL pointer dereference at virtual address [address]”


For a class assignment, we are writing a custom syscall which pulls certain information about the existing process tree. The syscall is working fine for the most part and gets the appropriate information. However, a few processes it, in crashes with the error message, "Unable to handle kernel NULL pointer dereference at virtual address [address]". What I don't understand is that I'm testing if the pointer is NULL before accessing it, and yet, it still fails.

Example: In the code below, current_process is a valid pointer to a task_struct and k_buf is valid

printk("Setting parent process\n");
parent_process = current_process->real_parent;
printk("Parent process set\n");
if (parent_process != NULL) {
printk("Parent process is not null and getting pid\n");
    k_buf[i].parent_pid = parent_process->pid;
} else {
    k_buf[i].parent_pid = 0;
}
printk("Done with parent process\n");

When run, the program prints:

Setting parent process
Parent process set
Parent process is not null and getting pid
Done with parent process

a couple of times, and then

Setting parent process
Parent process set
Parent process is not null and getting pid

before throwing the error and going into kernel panic.

What am I doing wrong? Any thoughts?

EDIT:

For the time being, I commented out the above code so I could continue working on the rest of the system call. When I try to access the pid of a child process (again after a couple of successful attempts), it gives me a "Unable to handle kernel paging request at virtual address" error. As far as I understand, I have the correct locks in place for reading this data. However, is there something else I need to do to check the memory before I access it?


Solution

  • I'm speculating here but could parent_process->pid being NULL be the cause of your "kernel panic"? If so, you could check for that too.

    Its either that, or some issue with accessing the ith element of k_buf array ie. *(k_buf+i)