Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Kernel unable to handle NULL pointer dereference - using kmem_cache_alloc with struct

I am trying to write a simple char driver in an attempt to learn more about drivers in Linux.

The idea for the driver is to have a linked list that in each node will hold a single character and a pointer to the next node. I intended to use a kmem_cache to build this linked list as I thought that allocating a single object at a time, as necessary, for an individual node would be simple.

Here is the relevant code that I'm having a problem with. It's not pretty, as I'm just trying to get this thing to work.

struct kmem_cache *memCache;

typedef struct {
    char data;
    struct node* next;
} node;

node *head = NULL;

static ssize_t hello_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
{
    int i;
    accesscount++;

    for(i = 0; i < count; i++)
    {
        node *finder;
        node *temp;

        finder = head;

        if(finder == NULL)
        {
            finder = kmem_cache_alloc(memCache, GFP_KERNEL);
            //memset(finder, 0, sizeof(node)); 

            if(!finder)
                return -ENOMEM;

            finder->next = NULL;

            //!!!NULL DEREFERENCE HERE!!!
            copy_from_user(finder->data, buf+i, 1);

            head = finder;
        }
        else
        {
            while(finder->next != NULL)
                finder = finder->next;

            temp = kmem_cache_alloc(memCache, GFP_KERNEL);
            //memset(temp, 0, sizeof(node)); 

            if(!temp)
                return -ENOMEM;

            temp->next = NULL;

            copy_from_user(temp->data, buf+i, 1);

            finder->next = temp;
        }

        charsStored++;  
    }

    return count;
}

static int __init hello_init(void)
{
    memCache = kmem_cache_create("hello1", sizeof(node), 0, 0, NULL);
}

So as you can see from my comment, when I call copy_from_user() and pass in the char variable in a node, I get a null dereference. I thought since I allocated the memory for the node, it should not be null anymore. I've also tried setting the char to char* instead and got different results, but it still did not function correctly.

I know my issue lies somewhere with how I'm allocating the memory or the way I constructed my pointers, but I'm really stuck here. I hope someone has some idea of what is wrong here.

like image 397
Shaun Avatar asked Nov 03 '22 11:11

Shaun


1 Answers

Pass the address of finder->data, not its value, to copy_from_user, and I think you'll be all set.

like image 190
Jamey Sharp Avatar answered Nov 15 '22 04:11

Jamey Sharp