Re: BUG: kernel NULL pointer dereference while copying sk_buff struct

2023-05-02 Thread Abdul Matin
Thanks for the tip!

On Tue, May 2, 2023 at 10:18 PM Alexander Kapshuk <
alexander.kaps...@gmail.com> wrote:

> On Tue, May 2, 2023 at 6:35 PM Abdul Matin
>  wrote:
> >
> > I'm initializing the memory for skbPrev at module init function:
> >
> > static int __init nf_conntrack_my_mod_init(void)
> > {
> > saddr_m = (union nf_inet_addr* ) kmalloc(sizeof(union nf_inet_addr),
> GFP_KERNEL);
> > skbPrev = (struct sk_buff*) kmalloc(sizeof(struct sk_buff),
> GFP_KERNEL);
> > if (saddr_m == NULL) {
> >   printk(KERN_INFO "Can not allocate space for saddr\n");
> >   return -ENOMEM;
> > }
> > if(skbPrev == NULL) {
> >   printk(KERN_INFO "Can not allocate space for skbPrev\n");
> >   return -ENOMEM;
> > }
> >
> > On Tue, May 2, 2023 at 8:23 PM Alexander Kapshuk <
> alexander.kaps...@gmail.com> wrote:
> >>
> >> On Tue, May 2, 2023 at 3:26 PM Abdul Matin
> >>  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(, 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 = >tuplehash[IP_CT_DIR_REPLY].tuple;
> >> > nf_ct_expect_init(exp, NF_CT_EXPECT_CLASS_DEFAULT,
> >> > nf_ct_l3num(ct),
> >> > saddr_m, >dst.u3,
> >> > IPPROTO_UDP, NULL, >dst.u.udp.port);
> >> >
> >> > pr_debug("expect: ");
> >> > nf_ct_dump_tuple(>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: 
> >> > 1,590,5743337860,-;#PF: supervisor read access in kernel mode
> >> > 1,591,5743337880,-;#PF: error_code(0x) - not-present page
> >> > 6,592,5743337900,-;PGD 0 P4D 0
> >> > 4,593,5743337974,-;Oops:  [#1] SMP PTI
> >> >
> >> > Is there anything wrong I am doing in copying and initializing?
> >> >
> >> > ___
> >> > Kernelnewbies mailing list
> >> > Kernelnewbies@kernelnewbies.org
> >> > https://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
>
> I see.
> Without seeing the code in its entirety it's hard to tell which
> pointer is being null-dereferenced.
> Examine the OOPS output. The answer may very well be there.
> Otherwise, you want to 

Re: BUG: kernel NULL pointer dereference while copying sk_buff struct

2023-05-02 Thread Alexander Kapshuk
On Tue, May 2, 2023 at 6:35 PM Abdul Matin
 wrote:
>
> I'm initializing the memory for skbPrev at module init function:
>
> static int __init nf_conntrack_my_mod_init(void)
> {
> saddr_m = (union nf_inet_addr* ) kmalloc(sizeof(union nf_inet_addr), 
> GFP_KERNEL);
> skbPrev = (struct sk_buff*) kmalloc(sizeof(struct sk_buff), GFP_KERNEL);
> if (saddr_m == NULL) {
>   printk(KERN_INFO "Can not allocate space for saddr\n");
>   return -ENOMEM;
> }
> if(skbPrev == NULL) {
>   printk(KERN_INFO "Can not allocate space for skbPrev\n");
>   return -ENOMEM;
> }
>
> On Tue, May 2, 2023 at 8:23 PM Alexander Kapshuk 
>  wrote:
>>
>> On Tue, May 2, 2023 at 3:26 PM Abdul Matin
>>  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(, 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 = >tuplehash[IP_CT_DIR_REPLY].tuple;
>> > nf_ct_expect_init(exp, NF_CT_EXPECT_CLASS_DEFAULT,
>> > nf_ct_l3num(ct),
>> > saddr_m, >dst.u3,
>> > IPPROTO_UDP, NULL, >dst.u.udp.port);
>> >
>> > pr_debug("expect: ");
>> > nf_ct_dump_tuple(>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: 
>> > 1,590,5743337860,-;#PF: supervisor read access in kernel mode
>> > 1,591,5743337880,-;#PF: error_code(0x) - not-present page
>> > 6,592,5743337900,-;PGD 0 P4D 0
>> > 4,593,5743337974,-;Oops:  [#1] SMP PTI
>> >
>> > Is there anything wrong I am doing in copying and initializing?
>> >
>> > ___
>> > Kernelnewbies mailing list
>> > Kernelnewbies@kernelnewbies.org
>> > https://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies

I see.
Without seeing the code in its entirety it's hard to tell which
pointer is being null-dereferenced.
Examine the OOPS output. The answer may very well be there.
Otherwise, you want to add some pr_info() or printk() calls around the
pointers being dereferenced in your code and see if any of those are
set to NULL.

___
Kernelnewbies mailing list
Kernelnewbies@kernelnewbies.org
https://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies


Re: BUG: kernel NULL pointer dereference while copying sk_buff struct

2023-05-02 Thread Alexander Kapshuk
On Tue, May 2, 2023 at 3:26 PM Abdul Matin
 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(, 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 = >tuplehash[IP_CT_DIR_REPLY].tuple;
> nf_ct_expect_init(exp, NF_CT_EXPECT_CLASS_DEFAULT,
> nf_ct_l3num(ct),
> saddr_m, >dst.u3,
> IPPROTO_UDP, NULL, >dst.u.udp.port);
>
> pr_debug("expect: ");
> nf_ct_dump_tuple(>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: 
> 1,590,5743337860,-;#PF: supervisor read access in kernel mode
> 1,591,5743337880,-;#PF: error_code(0x) - not-present page
> 6,592,5743337900,-;PGD 0 P4D 0
> 4,593,5743337974,-;Oops:  [#1] SMP PTI
>
> Is there anything wrong I am doing in copying and initializing?
>
> ___
> Kernelnewbies mailing list
> Kernelnewbies@kernelnewbies.org
> https://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies

___
Kernelnewbies mailing list
Kernelnewbies@kernelnewbies.org
https://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies


BUG: kernel NULL pointer dereference while copying sk_buff struct

2023-05-02 Thread Abdul Matin
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(, 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 = >tuplehash[IP_CT_DIR_REPLY].tuple;
nf_ct_expect_init(exp, NF_CT_EXPECT_CLASS_DEFAULT,
nf_ct_l3num(ct),
saddr_m, >dst.u3,
IPPROTO_UDP, NULL, >dst.u.udp.port);

pr_debug("expect: ");
nf_ct_dump_tuple(>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: 
1,590,5743337860,-;#PF: supervisor read access in kernel mode
1,591,5743337880,-;#PF: error_code(0x) - not-present page
6,592,5743337900,-;PGD 0 P4D 0
4,593,5743337974,-;Oops:  [#1] SMP PTI

Is there anything wrong I am doing in copying and initializing?
___
Kernelnewbies mailing list
Kernelnewbies@kernelnewbies.org
https://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies