<div dir="ltr">Hi.<div>I'm writing a netfilter module where I need to copy a sk_buff in a global variable that I use in another subsequent call. But I crashed the whole kernel. I've tried to add a code snippet to share with you how I'm doing it. </div><div><br>here case1 is always true before case2 (i.e. 1st call of help -> case1 is true, 2nd call of help -> case2 true).<br>So, in the 2nd call, case2 is true where we're using exp, ctinfoPrev, saddr_m which have been initialized before in case1.</div><div><br>union nf_inet_addr *saddr_m; <br>struct sk_buff* skbPrev;<br>enum ip_conntrack_info ctinfoPrev;<br>struct nf_conntrack_expect *exp;<br><br>static int help(struct sk_buff *skb,<br>                     unsigned int protoff,<br>               struct nf_conn *ct,<br>                 enum ip_conntrack_info ctinfo)<br>{<br>     switch (msgType) {<br>    case case1:<br><br>    ctinfoPrev = ctinfo;<br>    memcpy((void *)skbPrev, (const void *)skb, sizeof(skb));<br>    skbPrev->next = (struct sk_buff*) kmalloc(sizeof(struct sk_buff), GFP_KERNEL);<br>    skbPrev->prev = (struct sk_buff*) kmalloc(sizeof(struct sk_buff), GFP_KERNEL);<br>    skbPrev->sk = (struct sock*) kmalloc(sizeof(struct sock), GFP_KERNEL);<br>    memcpy((void *)(skbPrev->next), (const void *)skb->next, sizeof(skb->next));<br>    memcpy((void *)(skbPrev->prev), (const void *)skb->prev, sizeof(skb->prev));<br>   memcpy((void *)(skbPrev->sk), (const void *)skb->sk, sizeof(skb->sk));<br>      <br>    unsigned int type = (dptr[0] << 8) | dptr[1]; // little endian<br>    unsigned int length = (dptr[2] << 8) | dptr[3];<br>    printk(KERN_INFO "type: %hu length: %hu", type, length);<br><br>    unsigned int ip;<br>    memcpy(&ip, dptr, 4);<br>    ip = ntohl(ip) ^ MAGIC_COOKIE_VALUE_HOST;<br>    exp = nf_ct_expect_alloc(ct);<br>    if (exp == NULL) {<br>        printk( KERN_INFO "cannot alloc expectation");<br>        return NF_DROP;<br>    }<br>    tuple = &ct->tuplehash[IP_CT_DIR_REPLY].tuple;<br>    nf_ct_expect_init(exp, NF_CT_EXPECT_CLASS_DEFAULT,<br>    nf_ct_l3num(ct),<br>    saddr_m, &tuple->dst.u3,<br>    IPPROTO_UDP, NULL, &tuple->dst.u.udp.port);<br><br>    pr_debug("expect: ");<br>    nf_ct_dump_tuple(&exp->tuple);<br><br><br>    break;<br>   case case2:<br>    printk(KERN_INFO "createpermission response\n");<br>    nf_nat_tftp = rcu_dereference(nf_nat_tftp_hook);<br>    if (nf_nat_tftp && ct->status & IPS_NAT_MASK)<br>    ret= nf_nat_tftp(skbPrev, ctinfoPrev, exp);<br>    else if (nf_ct_expect_related(exp, 0) != 0) {<br>    printk( KERN_INFO "cannot add expectation");<br>    nf_ct_helper_log(skb, ct, "cannot add expectation");<br>    ret = NF_DROP;<br>    } <br>   nf_ct_expect_put(exp);<br>   break;<br>   }<br>   return ret;<br>  }<br></div><div>I got this log before crash: 1,589,5743337757,-;BUG: kernel NULL pointer dereference, address: 0000000000000000<br></div>1,590,5743337860,-;#PF: supervisor read access in kernel mode<br>1,591,5743337880,-;#PF: error_code(0x0000) - not-present page<br>6,592,5743337900,-;PGD 0 P4D 0<br>4,593,5743337974,-;Oops: 0000 [#1] SMP PTI<br><br>Is there anything wrong I am doing in copying and initializing?<br><div><br></div></div>