On Tue, May 2, 2023 at 3:26 PM Abdul Matin <abdulmatincuetcse17@xxxxxxxxx> wrote: > > Hi. > 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. > > here case1 is always true before case2 (i.e. 1st call of help -> case1 is true, 2nd call of help -> case2 true). > So, in the 2nd call, case2 is true where we're using exp, ctinfoPrev, saddr_m which have been initialized before in case1. > > union nf_inet_addr *saddr_m; > struct sk_buff* skbPrev; This declares a pointer to struct sk_buff which is uninitialised and most probably set to NULL by the compiler. Where do you allocate memory for skbPrev? > enum ip_conntrack_info ctinfoPrev; > struct nf_conntrack_expect *exp; > > static int help(struct sk_buff *skb, > unsigned int protoff, > struct nf_conn *ct, > enum ip_conntrack_info ctinfo) > { > switch (msgType) { > case case1: > > ctinfoPrev = ctinfo; > memcpy((void *)skbPrev, (const void *)skb, sizeof(skb)); The NULL pointer dereference probably happens here, as memcpy attempts to copy data from skb to skbPrev, which is likely to be NULL. > skbPrev->next = (struct sk_buff*) kmalloc(sizeof(struct sk_buff), GFP_KERNEL); > skbPrev->prev = (struct sk_buff*) kmalloc(sizeof(struct sk_buff), GFP_KERNEL); > skbPrev->sk = (struct sock*) kmalloc(sizeof(struct sock), GFP_KERNEL); > memcpy((void *)(skbPrev->next), (const void *)skb->next, sizeof(skb->next)); > memcpy((void *)(skbPrev->prev), (const void *)skb->prev, sizeof(skb->prev)); > memcpy((void *)(skbPrev->sk), (const void *)skb->sk, sizeof(skb->sk)); > > unsigned int type = (dptr[0] << 8) | dptr[1]; // little endian > unsigned int length = (dptr[2] << 8) | dptr[3]; > printk(KERN_INFO "type: %hu length: %hu", type, length); > > unsigned int ip; > memcpy(&ip, dptr, 4); > ip = ntohl(ip) ^ MAGIC_COOKIE_VALUE_HOST; > exp = nf_ct_expect_alloc(ct); > if (exp == NULL) { > printk( KERN_INFO "cannot alloc expectation"); > return NF_DROP; > } > tuple = &ct->tuplehash[IP_CT_DIR_REPLY].tuple; > nf_ct_expect_init(exp, NF_CT_EXPECT_CLASS_DEFAULT, > nf_ct_l3num(ct), > saddr_m, &tuple->dst.u3, > IPPROTO_UDP, NULL, &tuple->dst.u.udp.port); > > pr_debug("expect: "); > nf_ct_dump_tuple(&exp->tuple); > > > break; > case case2: > printk(KERN_INFO "createpermission response\n"); > nf_nat_tftp = rcu_dereference(nf_nat_tftp_hook); > if (nf_nat_tftp && ct->status & IPS_NAT_MASK) > ret= nf_nat_tftp(skbPrev, ctinfoPrev, exp); > else if (nf_ct_expect_related(exp, 0) != 0) { > printk( KERN_INFO "cannot add expectation"); > nf_ct_helper_log(skb, ct, "cannot add expectation"); > ret = NF_DROP; > } > nf_ct_expect_put(exp); > break; > } > return ret; > } > I got this log before crash: 1,589,5743337757,-;BUG: kernel NULL pointer dereference, address: 0000000000000000 > 1,590,5743337860,-;#PF: supervisor read access in kernel mode > 1,591,5743337880,-;#PF: error_code(0x0000) - not-present page > 6,592,5743337900,-;PGD 0 P4D 0 > 4,593,5743337974,-;Oops: 0000 [#1] SMP PTI > > Is there anything wrong I am doing in copying and initializing? > > _______________________________________________ > Kernelnewbies mailing list > Kernelnewbies@xxxxxxxxxxxxxxxxx > https://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies _______________________________________________ Kernelnewbies mailing list Kernelnewbies@xxxxxxxxxxxxxxxxx https://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies