strcmp内核模块崩溃

时间:2014-05-19 07:08:58

标签: linux-kernel kernel-module strcmp netfilter

我正在尝试检测内核(Netfilter)模块中的传出数据包。我正在使用strcmp函数来实现它。使用strcmp函数加载内核模块后,内核总是崩溃。我尝试删除strcmp函数 - 加载没有任何问题。我希望问题是所有字符串函数,我也尝试过strstr() - 我的系统崩溃了

这背后的逻辑,Incoming数据包将eth [0-9] +分配给“in-> name”,而“out-> name”将是,反之亦然,用于传出数据包。

检测传出数据包的任何见解?我知道另一种选择是使用output_hook而不是prerouting和postrouting hook。但在这里,我想以不同的方式破坏传入和传出的数据包。我使用的内核版本是否不支持模块内的字符串函数?

$ 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 <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>

主钩

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     ....

我也尝试用以下代替第37行,我的系统挂起

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

2 个答案:

答案 0 :(得分:4)

out结构指针中可能有NULL指针。您可以在main_hook中添加一些健全性检查,如:

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");
     }
     ....

所以我添加了对out指针的检查,并使用strncmp代替strcmp,其中IFNAMSIZ的大小为out->name,如{{3}中所定义}}。另外,str(n)cmp不返回NULL,而是返回0

检查并提供任何崩溃消息。

答案 1 :(得分:1)

我理解了这个问题,钩子函数是迭代序列,比如while(1)检查数据包。迭代可能会也可能不会收到数据包。如果迭代收到一个数据包,结构“out”将可用,其成员可以访问;我试图在不检查struct的可用性的情况下访问成员时犯了一个错误。

以下代码修正了目的并正常工作。

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