Отправка структуры из ядра в пользовательскую область через netlink

Я пытаюсь отправить структуру из LKM в пользовательскую область, основываясь на этом ответе: сокеты Netlink в C с использованием ядра Linux 3.X

Код из самого ответа отлично компилируется, но когда я пытаюсь отправить struct вместо char *Я получаю segfaults в userland.

Это то, что я меняю:

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);

В чем проблема?

1 ответ

Решение

Вот ваша проблема: ваша структура содержит указатель на другую память в пространстве ядра (char *b). Однако то, что вы отправляете в пространство пользователя, это только указатель в структуре, а не тот другой бит памяти ("The answer"). Кроме того, даже если вы должны были также отправить дополнительную память, b по-прежнему является указателем на виртуальные адреса ядра.

Лучше всего сделать массив ба чар и скопировать данные в b.

Указатели внутри данных, передаваемых между процессами или между процессом и ядром, как правило, очень проблематичны. системные вызовы, использующие структуры указателей, например man 2 recvmsg, не просто передавайте дословно указатели между пользовательским пространством и ядром, вместо этого ядро ​​делает отдельный доступ к пользовательскому пространству для разрешения каждого указателя.

Другие вопросы по тегам