null pointer deref issue while executing skb_release_data

Discussion in 'Linux Networking' started by vdx, Dec 2, 2013.

  1. vdx

    vdx New Member

    Messages:
    1
    Likes Received:
    0
    Trophy Points:
    1
    Dear Friends,

    I am building a packet forwarder kern-mod. for that I did add prerouting hook function in netfilter.
    In the same function, on successful match I am stilling that same. For that I use below function,


    Code:
    /* Transmitter function */
    static int my_xmit(struct sk_buff *skb)
    {
            struct rtable *rt;                      // route to the other host
            struct iphdr  *iph = skb->nh.iph;
            u8    tos = iph->tos;
            int    mtu;
            struct flowi flp;
    
            memset(&flp, 0, sizeof(flp));
            flp.fl4_dst = iph->daddr;
            flp.fl4_tos = RT_TOS(tos);
    
            if(ip_route_output_flow(&rt, &flp, NULL, 0)) {
    
                    printk(KERN_ERR  "my_xmit[%d]: ip_route_output error, dest: %u.%u.%u.%u\n",__LINE__,NIPQUAD(iph->daddr));
                    goto tx_error_icmp;
            }
    
            /* MTU checking ??? */
            mtu = dst_mtu(&rt->u.dst);
            if ((skb->len > mtu) && (iph->frag_off&__constant_htons(IP_DF))) {
    
                    icmp_send(skb, ICMP_DEST_UNREACH,ICMP_FRAG_NEEDED, htonl(mtu));
                    ip_rt_put(rt);
    
                    printk(KERN_ERR "my_xmit[%d]: frag needed\n",__LINE__);
                    goto tx_error;
            }
    
            /* drop old route */
            dst_release(skb->dst);
            skb->dst = &rt->u.dst;
    
            dst_output(skb);
            return NF_STOLEN;
    
      tx_error_icmp:
            dst_link_failure(skb);
      tx_error:
            kfree_skb(skb);
            return NF_STOLEN;
    }
    the issue with above is, at some point of time my system gets crash. Below is crash dump utility analysis

    Code:
    crash> bt
    PID: 0      TASK: ffff81022fd0f040  CPU: 16  COMMAND: "swapper"
    #0 [ffff81012fe0b9b0] crash_kexec at ffffffff800b093a
    #1 [ffff81012fe0ba70] __die at ffffffff80065137
    #2 [ffff81012fe0bab0] do_page_fault at ffffffff80067484
    #3 [ffff81012fe0bba0] error_exit at ffffffff8005dde9
        [exception RIP: my_prerouting_hook+1044]
        RIP: ffffffff8845a475  RSP: ffff81012fe0bc50  RFLAGS: 00010206
        RAX: ffffc200111b5000  RBX: ffff81012fe0bd50  RCX: 0000000000000000
        RDX: ffff81010a591044  RSI: 0000000000000014  RDI: ffff81011be607c0
        RBP: 0000000007be4e60  R8: ffffffff80254a2c  R9: ffffffff8845d3c0
        R10: ffff81010f52b080  R11: 00000000000000c8  R12: ffff81012b5a4000
        R13: 00000000000ffff0  R14: ffff81012fe0bda0  R15: ffffffff805c7ac0
        ORIG_RAX: ffffffffffffffff  CS: 0010  SS: 0018
    #4 [ffff81012fe0bce8] nf_iterate at ffffffff80033faf
    #5 [ffff81012fe0bd10] ip_rcv_finish at ffffffff80254a2c
    #6 [ffff81012fe0bd88] ip_rcv at ffffffff8003550b
    #7 [ffff81012fe0bdc8] netif_receive_skb at ffffffff80020aed
    #8 [ffff81012fe0be18] tg3_poll at ffffffff881b0be7 [tg3]
    #9 [ffff81012fe0bef8] net_rx_action at ffffffff8000c9bf
    #10 [ffff81012fe0bf38] __do_softirq at ffffffff80012531
    #11 [ffff81012fe0bf68] call_softirq at ffffffff8005e2fc
    #12 [ffff81012fe0bf80] do_softirq at ffffffff8006d646
    #13 [ffff81012fe0bf90] do_IRQ at ffffffff8006d4d6
    Code:
    crash> dis -lr ffffffff8845a475
    0xffffffff8845a061 <my_prerouting_hook>: push  %r14
    0xffffffff8845a0bb <my_prerouting_hook+90>:      mov    %rbx,%rdx
    0xffffffff8845a0be <my_prerouting_hook+93>:      callq  0xffffffff80233be4 <skb_copy_bits+317>
    0xffffffff8845a218 <my_prerouting_hook+439>:    callq  0xffffffff80048106 <mpage_end_io_read+71>
    0xffffffff8845a23b <my_prerouting_hook+474>:    callq  0xffffffff802509ae <nf_register_hooks+11>
    0xffffffff8845a29e <my_prerouting_hook+573>:    callq  0xffffffff80011fec <do_munmap+634>
    0xffffffff8845a305 <my_prerouting_hook+676>:    callq  0xffffffff8025713a <ip_copy_metadata+167>
    0xffffffff8845a31e <my_prerouting_hook+701>:    callq  0xffffffff8006201c <__memset>
    0xffffffff8845a33d <my_prerouting_hook+732>:    callq  0xffffffff80253106 <ip_route_output_flow+316>
    0xffffffff8845a370 <my_prerouting_hook+783>:    callq  0xffffffff8026ab1a <icmp_send+326>
    0xffffffff8845a3a2 <my_prerouting_hook+833>:    callq  0xffffffff80094387 <printk+3>
    0xffffffff8845a3a7 <my_prerouting_hook+838>:    callq  0xffffffff8006c4a1 <dump_stack>
    0xffffffff8845a3f4 <my_prerouting_hook+915>:    callq  0xffffffff80094387 <printk+3>
    0xffffffff8845a3f9 <my_prerouting_hook+920>:    callq  0xffffffff8006c4a1 <dump_stack>
    0xffffffff8845a43a <my_prerouting_hook+985>:    callq  0xffffffff80094387 <printk+3>
    
    0xffffffff8845a465 <my_prerouting_hook+1028>:    callq  0xffffffff802344b1 <skb_release_data+150>
    0xffffffff8845a46a <my_prerouting_hook+1033>:    mov    $0x2,%eax
    0xffffffff8845a46f <my_prerouting_hook+1038>:    jmp    0xffffffff8845a4a8
    0xffffffff8845a471 <my_prerouting_hook+1040>:    mov    0x0(%rbp),%rbp
    0xffffffff8845a475 <my_prerouting_hook+1044>:    mov    0x0(%rbp),%rax
    I getting NULL pointer deref issue in above case. how do I resolve ?
  2. GrumpyOldMan

    GrumpyOldMan Member

    Messages:
    72
    Likes Received:
    27
    Trophy Points:
    18
    First thing I would do is verify that any pointer object you dereference is valid. This includes arguments to functions. For example, in the function shown above, you're dereferencing skb without doing a sanity check. And then, you're dereferencing the value you obtained from a field in skb again without checking, all within the declaration block. Paranoia is your friend here.

Share This Page