I'm trying to send a struct from a LKM to userland, based on this answer: Netlink Sockets in C using the 3.X linux kernel
The code from the answer itself is perfectly compilable, but when I try to send a struct
instead of a char *
, I get segfaults in userland.
This is what I change:
netlinkKernel.c
I add:
typedef struct test{
int a;
char *b;
} s_test;
and replace
char *msg = "Hello from kernel";
---
msg_size = strlen(msg);
---
strncpy(nlmsg_data(nlh),msg,msg_size);
with
s_test x;
x.a = 42;
x.b = "The answer";
---
msg_size(sizeof(x));
---
memcpy(nlmsg_data(nlh), &x, msg_size);
netlinkUser.c
I add the same struct and replace
printf("Received message payload: %s\n", (char *)NLMSG_DATA(nlh));
with
s_test *x = (s_test *)NLMSG_DATA(nlh);
printf("Received message payload: %d - %s\n", x->a, x->b);
Where is the problem?
Here's your problem: your structure contains a pointer to other memory in kernel space (char *b
). However, what you are sending to user space is only the pointer in the structure and not that other bit of memory ("The answer"
). In addition, even if you were to also send the additional memory, b
still is a pointer to kernel virtual addresses.
Your best bet is to make b a char array and copy the data into b.
Pointers inside data sent between processes or between a process and the kernel are generally very problematic. system calls that use structures of pointers, e. g. man 2 recvmsg
, do not just send the pointers verbatim between user space and kernel, instead, the kernel does separate access to userspace to resolve each pointer.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With