BUG: kernel NULL pointer dereference while copying sk_buff struct

Abdul Matin abdulmatincuetcse17 at gmail.com
Tue May 2 08:26:02 EDT 2023


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;
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));
    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?
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.kernelnewbies.org/pipermail/kernelnewbies/attachments/20230502/8af4f294/attachment.html>


More information about the Kernelnewbies mailing list