カスタムモジュールをロードすると、カーネルがハングします。

カスタムモジュールをロードすると、カーネルがハングします。

私は基本的に与えられたインターフェイス(下のコード)のすべてのパケットにメッセージを印刷する単純なカーネルモジュールを持っています。どのカーネルを使用してコンパイルして実行しても、システムの実行中に数秒間中断されます。 Linux自体では何のメッセージも受け取れませんが、VMWareはゲストOSがCPUを停止したと言います。モジュールはエラーなしでコンパイルされロードされます。どんなアイデアがありますか?どのようにデバッグするのですか? Journalctlは何も表示しません。どんな助けでも大変感謝します。私はこれについてあまり慣れておらず、デバッグ方法がわかりません。

仮想マシンログ:

2024-02-01T11:57:03.994Z In(05) vcpu-0 MsgHint: msg.monitorevent.halt
2024-02-01T11:57:03.994Z In(05)+ vcpu-0 The CPU has been disabled by the guest operating system. Power off or reset the virtual machine.
2024-02-01T11:57:03.994Z In(05)+ vcpu-0 ---------------------------------------```

カーネルモジュールのソースコード:

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

static struct nf_hook_ops netfilter_ops;
static char *interface = "ens33"; 
module_param(interface, charp, 0);

static unsigned int hook_func(void *priv, struct sk_buff *skb, const struct nf_hook_state *state) {
    char source[16], dest[16];

    if (!skb) {
        return NF_ACCEPT;
    }

    if (strcmp(state->in->name, interface) == 0 || strcmp(state->out->name, interface) == 0) {

        struct iphdr *ip_header = ip_hdr(skb);
        if (!ip_header) {
            return NF_ACCEPT;
        }


        snprintf(source, 16, "%pI4", &ip_header->saddr);
        snprintf(dest, 16, "%pI4", &ip_header->daddr);

        printk(KERN_INFO "Packet logged on %s: Source IP: %s, Destination IP: %s\n", interface, source, dest);
    }
    return NF_ACCEPT;
}

static int __init my_module_init(void) {
    netfilter_ops.hook = hook_func;
    netfilter_ops.pf = PF_INET;
    netfilter_ops.hooknum = NF_INET_PRE_ROUTING;
    netfilter_ops.priority = NF_IP_PRI_FIRST;

    nf_register_net_hook(&init_net, &netfilter_ops);
    printk(KERN_INFO "Kernel module initialized on interface %s\n", interface);
    return 0;
}

static void __exit my_module_exit(void) {
    nf_unregister_net_hook(&init_net, &netfilter_ops);
    printk(KERN_INFO "Kernel module removed\n");
}

module_init(my_module_init);
module_exit(my_module_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("foo bar baz");
MODULE_DESCRIPTION("Netfilter packet logging module");
MODULE_VERSION("0.1");

ベストアンサー1

まあ、私は直接答えを見つけたようです。問題は、フックメソッドが呼び出されたときにステータス->インまたはステータス->アウトのいずれかを設定できることです(明らかに)。修正後の関連行は次のとおりです。

if ((state->in && strcmp(state->in->name, interface) == 0) || (state->out && strcmp(state->out->name, interface) == 0)) {

おすすめ記事