Sending a struct from kernel to userland via netlink
Asked Answered
A

1

6

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?

Apc answered 22/9, 2013 at 14:3 Comment(0)
Y
5

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.

Yi answered 22/9, 2013 at 16:59 Comment(2)
This makes sense, but why the demo from the answer I link to works? The demo sends a char *, not a char [N].Apc
Also, this was just a POC, my real struct has a 5 char* and a pid_t, and maybe I'll add more. I think I need a de/serialization library. Do you know any (that will work in the kernel side, aka, no malloc/free but kmalloc/kfree and so on...)?Apc

© 2022 - 2024 — McMap. All rights reserved.