通过netlink将结构从内核发送到userland

ale*_*nst 5 c linux kernel kernel-module netlink

我试图将一个结构从LKM发送到userland,基于这个答案:使用3.X linux内核的C中的Netlink套接字

答案本身的代码是完全可编译的,但是当我尝试发送struct而不是a时char *,我会在userland中获得段错误.

这是我改变的:

netlinkKernel.c

我加:

typedef struct test{
    int a;
    char *b;
} s_test;
Run Code Online (Sandbox Code Playgroud)

并替换

char *msg = "Hello from kernel";

---

msg_size = strlen(msg);

---

strncpy(nlmsg_data(nlh),msg,msg_size);
Run Code Online (Sandbox Code Playgroud)

s_test x;
x.a = 42;
x.b = "The answer";

---

msg_size(sizeof(x));

---

memcpy(nlmsg_data(nlh), &x, msg_size);
Run Code Online (Sandbox Code Playgroud)

netlinkUser.c

我添加相同的结构和替换

printf("Received message payload: %s\n", (char *)NLMSG_DATA(nlh));
Run Code Online (Sandbox Code Playgroud)

s_test *x = (s_test *)NLMSG_DATA(nlh);
printf("Received message payload: %d - %s\n", x->a, x->b);
Run Code Online (Sandbox Code Playgroud)

问题出在哪儿?

Dox*_*ver 5

这是您的问题:您的结构包含一个指向内核空间中其他内存的指针 ( char *b)。但是,您发送到用户空间的只是结构中的指针,而不是其他内存位 ( "The answer")。另外,即使你还发送了额外的内存,b仍然是一个指向内核虚拟地址的指针。

最好的办法是制作 ba 字符数组并将数据复制到 b 中。

在进程之间或进程与内核之间发送的数据内部的指针通常很成问题。使用指针结构的系统调用,例如man 2 recvmsg,不只是在用户空间和内核之间逐字发送指针,相反,内核单独访问用户空间以解析每个指针。