'packet drop Netfilter module crash the system

I'm learning Linux Netfilter module development with the following demo module code:

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

static struct nf_hook_ops nfho;

unsigned int hook_func(void *priv, struct sk_buff *skb, const struct nf_hook_state *state)
{
  printk(KERN_INFO "packet dropped\n");
  return NF_DROP;
}

static int drop_init(void)
{
  nfho.hook = hook_func;
  nfho.hooknum = NF_INET_PRE_ROUTING;
  nfho.pf = PF_INET;
  nfho.priority = NF_IP_PRI_FIRST;
  nf_register_net_hook(&init_net, &nfho);
  return 0;
}

static void drop_exit(void)
{
  nf_unregister_net_hook(&init_net,&nfho);
}

module_init(drop_init);

module_exit(drop_exit);

MODULE_LICENSE("GPL");

and this Makefile:

obj-m += drop-packet.o
all:
        make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
        make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean

My current Kernel version is 4.15.0-176-generic. So in the code level, I did some investigations as follows:

  • change nf_register_hook to nf_register_net_hook and nf_unregister_hook to nf_unregister_net_hook
  • hook function uses the new signature: unsigned int hook_func(void *priv, struct sk_buff *skb, const struct nf_hook_state *state)

So far, I can build the module by running make command. I didn't see any potential error message from the console output:

make -C /lib/modules/4.15.0-176-generic/build M=/home/DIR/jbao6/develop/kernel/drop-packet modules
make[1]: Entering directory '/usr/src/linux-headers-4.15.0-176-generic'
  Building modules, stage 2.
  MODPOST 1 modules
make[1]: Leaving directory '/usr/src/linux-headers-4.15.0-176-generic'

But when I tried to install the module by running the insmod drop-packet.ko command. The system crashes. In fact the insmod command can return successfully without any message. So at the beginning, I thought it works. But the shell becomes blocked and unresponsive.

I'm running this demo module on a remote virtual machine and each time I need to reboot the VM.

And I did some experiments based on this document https://sysprog21.github.io/lkmpg/. I can build and install the simplest hello-world module successfully like this one:

#include <linux/kernel.h> /* Needed for pr_info() */ 
#include <linux/module.h> /* Needed by all modules */ 
 
int init_module(void) 
{ 
    pr_info("Hello world 1.\n"); 
 
    /* A non 0 return means init_module failed; module can't be loaded. */ 
    return 0; 
} 
 
void cleanup_module(void) 
{ 
    pr_info("Goodbye world 1.\n"); 
} 
 
MODULE_LICENSE("GPL");

Is there any solution or ideas to troubleshoot my problem.



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source