문제

I am writing a linux kernel module in which I implemented a linked list. I know there is a list API in linux kernel but when I implemented it I didn't know so implemented it handling raw pointer with kmalloc(). After running several hours, kernel is crashing and in crash log it is showing "General Protection Fault". Log also shows that it is occuring from my function for searching linked list. Apparently search function is like below which has no logical error.

/*
 * Searches in a certain index of hash table for a data
 * returns NULL if not found else returns pointer of that element in the table
 */

struct queue_data * search_table(unsigned int hash_index, struct queue_data *new_data)
{
        /* Taking a new queue pointer. Which will be pointing to the queue represented
         * by new_data at last. */
        struct queue_data *ret;
        /* First initializing it with first queue on the list */
        ret = table[hash_index].next;
        /* Iterating through the list to find the desired queue */
        while(ret != NULL) {
                /* Checking if current queue matches our criteria */
                if(ret->saddr == new_data->saddr &&
                        ret->daddr == new_data->daddr &&
                        ret->dest == new_data->dest &&
                        ret->ssrc == new_data->ssrc) {
                        /* It matched. So I can return it */
                        return ret;
                }
                /* It didn't match so I need to go to next queue */
                ret = ret->next;
        }

        /* No queue matched out criteria. Because if it matched it would have not
         * come this far. It would have returned before.
         * So I need to return a NULL. Now value of 'ret' is NULL.
         * I can return 'ret'
         */
        return ret;
}

It's also apparent that insert function is also flawless in logical point of view. As General Protection Fault usually occurs in when invalid memory access occurs and I never used a memory allocated by other than kmalloc(). Now my question is if I use a memory allocated by kmalloc then there is any possibility of using invalid memory which should I check before use?

Fraction of crash Log is here:

[ffff8804130cb690] general_protection at ffffffff81661c85
    [exception RIP: search_table+52]
    RIP: ffffffffa00bc854  RSP: ffff8804130cb748  RFLAGS: 00010286
    RAX: d6d4575455d55555  RBX: ffff88040f46db00  RCX: 0000000000000018
    RDX: 02b53202ab706c17  RSI: ffff8803fccaaa00  RDI: 00000000000c2568
    RBP: ffff8804130cb748   R8: ffffffff8180cb80   R9: 000000000000016d
    R10: a3d70a3d70a3d70b  R11: ffff8803fccaab58  R12: ffffc9001262cc38
    R13: 000000000000079f  R14: ffff8803fccaaa00  R15: ffffffffa00cbee8
    ORIG_RAX: ffffffffffffffff  CS: 0010  SS: 0018

When inserting, I checked allocated memory by kmalloc with this :

   /* Allocating and initializing a new queue.
    * If a queue corresponding to it already exists then it's data will
    * copied and this queue will be dropped.
    * Else this queue will be inserted to the hash table that manages the queues.
    */
    new_data = (struct queue_data *)kmalloc(sizeof(struct queue_data), GFP_ATOMIC);
    if (!new_data) {
        //printk(KERN_ALERT "pkt_queue EXCEPTION: new_data\n");
        return NULL;
    }
도움이 되었습니까?

해결책

Looking at the code you posted, the only possible source for the General Protection Fault I can see is this line:

ret = table[hash_index].next;

You're not checking the size of table, so perhaps you're accessing out-of-bounds memory? No way to be sure, without knowing how, where and what table is declared as, and how you initialize it.

After looking at your comment, saying hash_index, an unsigned int, is the result of a modulus of the HASH_PRIME macro, it could be that at some point, you're encountering possible signed-unsigned arithmetic issues, so that, despite the modulus on HASH_PRIME, you are in fact going out of bounds. Perhaps add:

if (hash_index >= HASH_PRIME) hash_index = HASH_PRIME-1;//or error

Just for completeness' sake: as I pointed out in the comments, the functions you're using all use the kernel's u32 type. As it turns out, that was the reason for your code still accessing wrong memory. (Typed this update on phone... Hate it)

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top