Gopi
Gopi

Reputation: 350

strcmp inside kernel module crash

I am trying to to detect the a outgoing packets in my kernel(Netfilter) module. I am using a strcmp function to achieve it. The kernel always crashes after loading my kernel module with strcmp function. I tried removing the strcmp function - loaded without any problem. I hope the problem is with all string function, I also tried strstr() - my system crashed

The logic behind this, Incoming packet will have eth[0-9]+ assigned to "in->name" and "out->name" will be and vice-versa for outgoing packet.

Any insight to detect a outgoing packet? I knew another option is to use output_hook instead of prerouting and postrouting hook. But here I want to mangle both incoming and outgoing packet in different way. Does the kernel version I am using doesn't support string function inside modules?

$ uname -a
Linux vmdsk01 2.6.32-21-generic #32-Ubuntu SMP Fri Apr 16 08:09:38 UTC 2010 x86_64 GNU/Linux

Include Part

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>

#include <linux/netfilter.h>
#include <linux/netfilter_ipv4.h>

#include <linux/skbuff.h>
#include <linux/inet.h>
#include <linux/ip.h>
#include <linux/tcp.h>
#include <net/ip.h>

#include <linux/string.h>

Main Hook

31 unsigned int main_hook(unsigned int hooknum,  
32                   struct sk_buff *skb,
33                   const struct net_device *in,
34                   const struct net_device *out,
35                   int (*okfn)(struct sk_buff*))
36 {
37     if( strcmp(out->name, "<NULL>") == NULL ) // Outgoing packet must not have <NULL>
38     {
39         printk( KERN_INFO "OUTGOING PACKET");
40     }
41     ....

I also tried replacing line 37 with following, my system hangs

37     if( strstr(out->name, "eth") != NULL ) // Outgoing packet must have eth[0-9]+ 

Upvotes: 2

Views: 9336

Answers (2)

Gopi
Gopi

Reputation: 350

I understood the issue, the hook function is sequence of iterations like while(1) checking for packet. A iteration may or may not received a packet. If an iteration received a packet, the struct "out" would be available and its members could be accessible; I made a mistake by trying to access a member without checking availability of struct.

The following code fixed the purpose and working fine.

if(out)
{
    if( strcmp(out->name, "<NULL>") ) // Outgoing packet must not have <NULL>
    {
        printk( KERN_INFO "Outgoing Packet");
    }
}

Upvotes: 1

Alexander Dzyoba
Alexander Dzyoba

Reputation: 4189

You might have NULL pointer in out struct pointer. You may add some sanity checks in main_hook like:

unsigned int main_hook(unsigned int hooknum,  
                   struct sk_buff *skb,
                   const struct net_device *in,
                   const struct net_device *out,
                   int (*okfn)(struct sk_buff*))
 {
     if (!out)
         return -EINVAL;

     if( strncmp(out->name, "<NULL>", IFNAMSIZ) == 0 ) // Outgoing packet must not have <NULL>
     {
         printk( KERN_INFO "OUTGOING PACKET");
     }
     ....

So I've added check for out pointer and using strncmp instead of strcmp where IFNAMSIZ is size of out->name as defined in include/linux/netdevice.h. Also, str(n)cmp does not return NULL, it returns 0.

Check it and please provide any crash messages.

Upvotes: 4

Related Questions