[Q] Why has NULL pointer returned in my code?

From: Blusjune Jung (blusjune@nits5.etri.re.kr)
Date: Fri Jun 23 2000 - 03:05:27 EST


The following is my code to allocate new socket buffer with new 'skb->truesize'.

        
        /* skbhandle.h
         *
         * C header file - Socket buffer handling module added on by blusjune.
         *
         * Last modified:
         * A.D. 2000. 06. 22. THU.
         *
         * Author:
         * | blusjune@nirva | ^_^ | stoneroses |
         */
        
        #ifndef _SKBHANDLE_H_
        #define _SKBHANDLE_H_
        
        #include <linux/skbuff.h>
        
        int skb_replace_with_newsize(
                struct sk_buff *nskb,
                struct sk_buff *oldskb,
                unsigned int nskb_truesize
        );
        
        struct sk_buff *skb_copy_with_newsize(
                struct sk_buff *skb,
                int gfp_mask,
                unsigned int nskb_truesize
        );
        
        #endif /* _SKBHANDLE_H_ */
        
        
        
        /* skbhandle.c
         *
         * C source file - Socket buffer handling module added on by blusjune.
         *
         * Last modified:
         * A.D. 2000. 06. 22. THU.
         *
         * Author:
         * | blusjune@nirva | ^_^ | stoneroses |
         */
        
        #include <linux/kernel.h>
        #include <linux/mm.h>
        #include <linux/ip.h>
        #include <linux/skbuff.h>
        
        #include <net/ip.h>
        #include <net/protocol.h>
        #include <net/dst.h>
        #include <net/skbhandle.h>
        
        __inline__ int skb_replace_with_newsize(
                struct sk_buff *nskb,
                struct sk_buff *oldskb,
                unsigned int nskb_truesize
        )
        {
                // nskb = skb_copy_with_newsize(oldskb, GFP_ATOMIC, nskb_truesize);
                nskb = skb;
                if (!nskb)
                {
                        printk("\nError: NULL skb poiner returned!.");
                        return -1;
                }
                return 0;
        }
        
        struct sk_buff *skb_copy_with_newsize(
                struct sk_buff *skb,
                int gfp_mask,
                unsigned int nskb_truesize
        )
        {
                struct sk_buff *n;
                unsigned long offset;
                unsigned int skb_truesize = skb->end - skb->head;
        
                /*
                 * Allocate the copy buffer
                 */
                n = alloc_skb(nskb_truesize, gfp_mask);
                if (n == NULL)
                {
                        printk("\nalloc_skb(): returns a NULL pointer.");
                        return NULL;
                }
        
                /*
                 * Shift between the two data areas in bytes
                 */
                offset = n->head - skb->head;
        
                /* Set the data pointer */
                skb_reserve(n, skb->data - skb->head);
        
                /* Set the tail pointer and length */
                skb_put(n, skb->len + nskb_truesize - skb_truesize);
        
                /* Copy the bytes */
                if (nskb_truesize > skb_truesize)
                        memcpy(n->head, skb->head, skb_truesize);
                else
                        memcpy(n->head, skb->head, nskb_truesize);
        
                /* explicit skb->len substitution */
                n->len = skb->len + nskb_truesize - skb_truesize;
                /* explicit skb->truesize substitution */
                n->truesize = nskb_truesize;
                n->csum = skb->csum;
                n->list = NULL;
                n->sk = NULL;
                n->dev = skb->dev;
                n->priority = skb->priority;
                n->protocol = skb->protocol;
                n->dst = dst_clone(skb->dst);
                n->h.raw = skb->h.raw + offset;
                n->nh.raw = skb->nh.raw + offset;
                n->mac.raw = skb->mac.raw + offset;
                memcpy(n->cb, skb->cb, sizeof(skb->cb));
                n->used = skb->used;
                n->is_clone = 0;
                atomic_set(&n->users, 1);
                n->pkt_type = skb->pkt_type;
                n->stamp = skb->stamp;
                n->destructor = NULL;
                n->security = skb->security;
        #ifdef CONFIG_IP_FIREWALL
                n->fwmark = skb->fwmark;
        #endif
                return n;
        }
                

The objectives of the code above are
        to allocate new socket buffer with new skb->truesize,
        to have the same contents with the original socket buffer (i.e., carbon copy except socket buffer size).

After finishing kernel compile(no warning, no error), I reboot the computer as the newly created kernel image.

After some boot strapping messages are scrolled,
kernel panic has occurred with the following message:

        <1>Unable to handle kernel NULL pointer dereference at virtual address 00000004
        current->tss.cr3 = 00101000, %cr3 = 00101000
        *pde = 00000000
        Oops: 0002
        CPU: 0
        EIP: 0010: [<c016fe8e>]
        EFLAGS: 00010296
        eax: .............. /* register values */ .................
        esi: .............. /* register values */ .................
        ds: 0018 es: 0018 ss: 0018
        Process swapper (pid: 0, process nr: 0, stackpage = c01fb000)
        Stack: .............. /* Stack values */ ..................
        Call Trace: ............
        Code: 89 4d 04 89 0f 89 71 08 ff 46 08 5b 5e 5f 5d 83 c4 08 c3 90

        Aiee, killing interrupt handler
        Kernel panic: Attempted to kill the idle task!
        In swapper task - not syncing

So I analized my code included in kernel(ip_output.c, ip_input.c).
After a few minutes, I've got found out the fact that the return value of skb_copy_with_newsize() is 'NULL'.
But... I can't understand why 'NULL' pointer should be returned whenever kernel uses it.

Would you mind teaching me why?
Thank you.

-- 
| blusjune@nirva | ^_^ | stoneroses |
  Blusjune Jung
  Email: blusjune@yahoo.com

- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Fri Jun 23 2000 - 21:00:25 EST