我正在尝试根据以下答案将LKM中的结构发送到用户空间:Netlink Sockets in C using the 3.X linux kernel
答案中的代码本身是完全可编译的,但当我尝试发送struct
而不是char *
时,我会在用户空间中获得段错误。
这就是我的改变:
netlinkKernel.c
我补充说:
typedef struct test{
int a;
char *b;
} s_test;
并替换
char *msg = "Hello from kernel";
---
msg_size = strlen(msg);
---
strncpy(nlmsg_data(nlh),msg,msg_size);
与
s_test x;
x.a = 42;
x.b = "The answer";
---
msg_size(sizeof(x));
---
memcpy(nlmsg_data(nlh), &x, msg_size);
netlinkUser.c
我添加相同的结构并替换
printf("Received message payload: %s\n", (char *)NLMSG_DATA(nlh));
与
s_test *x = (s_test *)NLMSG_DATA(nlh);
printf("Received message payload: %d - %s\n", x->a, x->b);
问题出在哪里?
答案 0 :(得分:4)
这是你的问题:你的结构包含一个指向内核空间中其他内存的指针(char *b
)。但是,您发送到用户空间的只是结构中的指针而不是内存的其他位("The answer"
)。此外,即使您还要发送额外内存,b
仍然是指向内核虚拟地址的指针。
你最好的办法是将b作为char数组并将数据复制到b。
在进程之间或进程与内核之间发送的数据中的指针通常是非常有问题的。使用指针结构的系统调用,例如: G。 man 2 recvmsg
,不要只是在用户空间和内核之间逐字发送指针,而是内核对用户空间进行单独访问以解析每个指针。