2013-09-22 77 views
5

我試圖從LKM到用戶空間的基礎上,這個答案發送一個struct用戶態:Netlink Sockets in C using the 3.X linux kernel發送從內核結構通過網絡鏈路

從答案本身的代碼是完全編譯,但是當我嘗試發送一個struct而不是一個char *,我得到了用戶級的segfaults。

這是我改變:

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

問題出在哪裏?

回答

4

下面是您的問題:您的結構包含指向其他內核空間的指針(char *b)。但是,發送給用戶空間的內容只是結構中的指針,而不是其他位內存("The answer")。另外,即使你也發送了額外的內存,b仍然是一個指向內核的虛擬地址。

最好的辦法是讓b成爲一個char數組並將數據複製到b中。

在進程之間或進程與內核之間發送的數據內部的指針通常很成問題。使用指針結構的系統調用, G。 man 2 recvmsg,不要只是在用戶空間和內核之間逐字地發送指針,相反,內核會分開訪問用戶空間來解析每個指針。

+0

這是有道理的,但爲什麼演示從我鏈接到答案的作品?演示發送一個'''char *''',而不是'''char [N]'''。 – alexandernst

+0

此外,這只是一個POC,我真正的結構有5個字符*和一個pid_t,也許我會添加更多。我想我需要一個de /序列化庫。你知道任何(這將在內核方面,也就是說,沒有malloc/free但是kmalloc/kfree等等)? – alexandernst