- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我编写了一个内核模块,它接受数据(结构形式)并将一些数据(相同结构格式)传回用户空间。我可以成功接收来自用户的消息,但在尝试取消引用从内核接收的数据结构的某些成员时出现段错误。我正在使用 netlink 套接字 API。
示例代码如下:
用户空间.c
#define NETLINK_USER 27
#define MAX_PAYLOAD 10000 /* maximum payload size*/
struct sockaddr_nl src_addr, dest_addr;
struct nlmsghdr *nlh = NULL;
struct iovec iov;
int sock_fd;
struct msghdr msg;
Response *p;
Response *req;
test r1;
test r2;
int main()
{
char *data;
data = malloc(4096 * sizeof(char));;
data = "data from user";
sock_fd=socket(PF_NETLINK, SOCK_RAW, NETLINK_USER);
if(sock_fd<0)
return -1;
memset(&src_addr, 0, sizeof(src_addr));
src_addr.nl_family = AF_NETLINK;
src_addr.nl_pid = getpid();
bind(sock_fd, (struct sockaddr*)&src_addr, sizeof(src_addr));
memset(&dest_addr, 0, sizeof(dest_addr));
memset(&dest_addr, 0, sizeof(dest_addr));
dest_addr.nl_family = AF_NETLINK;
dest_addr.nl_pid = 0;
dest_addr.nl_groups = 0;
nlh = (struct nlmsghdr *)malloc(NLMSG_SPACE(MAX_PAYLOAD));
memset(nlh, 0, NLMSG_SPACE(MAX_PAYLOAD));
nlh->nlmsg_len = NLMSG_LENGTH(MAX_PAYLOAD);
nlh->nlmsg_pid = getpid();
nlh->nlmsg_flags = 0;
p = malloc(2*sizeof(Response));
p[0].index = 1;
p[0].dataSize = 2;
p[0].data = data;
p[0].test2 = 3;
p[0].test3 = 4;
p[0].test4 = 5;
r1.t = 10;
r1.ip_addr = malloc(50*sizeof(char));
r1.ip_addr = "192.168.10.2";
p[0].test = &r1;
/* Extra for testing */
p[1].index = 2;
p[1].dataSize = 3;
//strcpy(p[1].data , "Data2 from User");
p[1].data = data;
p[1].test2 = 4;
p[1].test3 = 5;
p[1].test4 = 6;
r2.t = 20;
r2.ip_addr = malloc(50*sizeof(char));
r2.ip_addr = "192.168.20.2";
p[1].test = &r2;
memcpy(NLMSG_DATA(nlh), (void *)p, 2 * sizeof(*p));
iov.iov_base = (void *)nlh;
iov.iov_len = NLMSG_SPACE(MAX_PAYLOAD);
msg.msg_name = (void *)&dest_addr;
msg.msg_namelen = sizeof(dest_addr);
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
printf("Sending message to kernel\n");
sendmsg(sock_fd,&msg,0);
printf("Waiting for message from kernel\n");
/* Read message from kernel */
//recvmsg(sock_fd, &msg, 0);
req = (Response*)NLMSG_DATA(nlh);
printf("Recieved from Kernel:\n");
printf("index %d\n", req[0].index);
printf("dataSize %d\n", req[0].dataSize);
printf("data: %s\n", req[0].data); <---Segmentation fault from here
printf("test2 %d\n", req[0].test2);
printf("test3 %d\n", req[0].test3);
printf("test4 %d\n", req[0].test4);
printf("contents of test structure are %d,%s\n",req[0].test->t,req[0].test->ip_addr); <-----Segmentation fault
close(sock_fd);
内核模块.c
#include <linux/module.h>
#include <net/sock.h>
#include <linux/netlink.h>
#include <linux/skbuff.h>
#include <linux/slab.h>
#define NETLINK_USER 27
struct sock *nl_sk = NULL;
typedef struct _Response Response;
typedef struct _test test;
struct _test{
int t;
char *ip_addr;
};
struct _Response
{
int index;
int dataSize;
char *data;
int test2;
int test3;
int test4;
test *test;
};
static void hello_nl_recv_msg(struct sk_buff *skb) {
struct nlmsghdr *nlh;
int pid;
struct sk_buff *skb_out;
int msg_size;
int res;
Response *req;
Response *req1;
test t;
t.t = 1;
t.ip_addr = kmalloc(50*sizeof(char), GFP_KERNEL);
t.ip_addr = "129.63.45.1";
req1 = (Response *)kmalloc_array(2, sizeof(Response), GFP_KERNEL);
char *data;
data = kmalloc(4096 * sizeof(char), GFP_KERNEL);
data = "data from kernel";
printk(KERN_INFO "Entering: %s\n", __FUNCTION__);
msg_size= 2 * sizeof(*req1);
req1[0].index = 100;
req1[0].dataSize = 100;
req1[0].data = data;
req1[0].test2 = 100;
req1[0].test3 = 100;
req1[0].test4 = 100;
req1[0].test = &t;
printk("Sending to Userspace:\n");
/*Second set of message*/
req1[1].index = 102;
req1[1].dataSize = 103;
//strcpy(req1[1].data , "Data from Kernel");
req1[1].data = data;
req1[1].test2 = 100;
req1[1].test3 = 100;
req1[1].test4 = 100;
req1[1].test = &t;
nlh=(struct nlmsghdr*)skb->data;
req = (Response *)NLMSG_DATA(nlh); <--message received from user-space
printk("Recieved from Userspace:\n");
printk("index %d\n", req[0].index);
printk("dataSize %d\n", req[0].dataSize);
printk("data: %s\n", req[0].data);
printk("test2 %d\n", req[0].test2);
printk("test3 %d\n", req[0].test3);
printk("test4 %d\n", req[0].test4);
printk("contents of test are %d, %s\n",req[0].test->t,req[0].test->ip_addr);
printk("Next set of data\n");
printk("Recieved from Userspace:\n");
printk("index %d\n", req[1].index);
printk("dataSize %d\n", req[1].dataSize);
printk("data: %s\n", req[1].data);
printk("test2 %d\n", req[1].test2);
printk("test3 %d\n", req[1].test3);
printk("test4 %d\n", req[1].test4);
printk("contents of test are %d, %s\n",req[1].test->t,req[1].test->ip_addr);
pid = nlh->nlmsg_pid; /*pid of sending process */
skb_out = nlmsg_new(10000,0);
if(!skb_out)
{
printk(KERN_ERR "Failed to allocate new skb\n");
return;
}
nlh=nlmsg_put(skb_out,0,0,NLMSG_DONE,10000,0);
NETLINK_CB(skb_out).dst_group = 0; /* not in mcast group */
/*End of second set*/
memcpy(NLMSG_DATA(nlh), req1, 2 * sizeof(*req1));
res=nlmsg_unicast(nl_sk,skb_out,pid);
if(res<0)
printk(KERN_INFO "Error while sending bak to user\n");
}
static int __init hello_init(void) {
printk("Entering: %s\n",__FUNCTION__);
struct netlink_kernel_cfg cfg = {
.input = hello_nl_recv_msg,
};
nl_sk = netlink_kernel_create(&init_net, NETLINK_USER, &cfg);
if(!nl_sk)
{
printk(KERN_ALERT "Error creating socket.\n");
return -10;
}
return 0;
}
static void __exit hello_exit(void) {
printk(KERN_INFO "exiting hello module\n");
netlink_kernel_release(nl_sk);
}
module_init(hello_init); module_exit(hello_exit);
MODULE_LICENSE("GPL");
}
全局.h
#ifndef __GLOBAL_H
#define __GLOBAL_H
typedef struct _Response Response;
typedef struct _test test;
struct _test{
int t;
char *ip_addr;
};
struct _Response
{
int index;
int dataSize;
char *data;
int test2;
int test3;
int test4;
test *test;
};
#endif
基本上问题出在指针上。如果我使用 char data[4096] 而不是字符指针,我会收到消息。但是我在取消引用测试结构时遇到段错误。如何解决这个问题?
谢谢
最佳答案
这段代码是非常错误的,全面的批评可能是不必要的,所以我只会指出两种最明显的违规类型。
char *data;
data = kmalloc(4096 * sizeof(char), GFP_KERNEL);
data = "data from kernel";
首先,nit: sizeof(char) 保证为 1。但真正的问题是,这会立即覆盖 data 的值,从而丢失 malloc 返回的指针。这出现在代码中的多个位置。
req = (Response *)NLMSG_DATA(nlh); <--message received from user-space
printk("Recieved from Userspace:\n");
printk("index %d\n", req[0].index);
printk("dataSize %d\n", req[0].dataSize);
printk("data: %s\n", req[0].data);
这段代码虽然可能“有效”,但却是完全错误的。用户空间缓冲区(.data)无法以这种方式安全地访问,并且在某些体系结构上根本无法访问。它可能“工作”,因为完整的地址空间分为内核和用户空间,原则上内核可以访问那里。如果指针指向完全虚假的东西或内核内的东西,或者可能指向未映射的东西,就会出现问题。
代码的用户空间部分尝试执行相反的操作,不出所料,失败了——您无法访问内核内存,否则就不会有任何安全性。
问题的出现只是因为协议(protocol)错误。您应该在用户空间中分配一个缓冲区和一个保存其大小的变量。然后你可以告诉内核把数据放在哪里(以及多少个顶部)。
无论哪种方式,我认为您此时还没有准备好进行内核工作,因此强烈建议暂时坚持使用用户空间。
关于c - 在用户空间使用 netlink 从内核接收数据时出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38989116/
我有一个存储结构向量的应用程序。这些结构保存有关系统上每个 GPU 的信息,如内存和 giga-flop/s。每个系统上有不同数量的 GPU。 我有一个程序可以同时在多台机器上运行,我需要收集这些数据
我很好奇 MPI 中缺少此功能: MPI_Isendrecv( ... ); 即,非阻塞发送和接收,谁能告诉我其省略背后的基本原理? 最佳答案 我的看法是 MPI_SENDRECV存在是为了方便那些想
当我用以下方法监听TCP或UDP套接字时 ssize_t recv(int sockfd, void *buf, size_t len, int flags); 或者 ssize_t recvfrom
SUM:如何在 azure 事件网格中推迟事件触发或事件接收? 我设计的系统需要对低频对象状态(创建、启动、检查长时间启动状态、结束)使用react。它看起来像是事件处理的候选者。我想用azure函数
我正在 MPI 中实现一个程序,其中主进程(等级 = 0)应该能够接收来自其他进程的请求,这些进程要求只有根才知道的变量值。如果我按等级 0 进行 MPI_Recv(...),我必须指定向根发送请求的
我正在学习DX12,并在此过程中学习“旧版Win32”。 我在退出主循环时遇到问题,这似乎与我没有收到WM_CLOSE消息有关。 在C++,Windows 10控制台应用程序中。 #include
SUM:如何在 azure 事件网格中推迟事件触发或事件接收? 我设计的系统需要对低频对象状态(创建、启动、检查长时间启动状态、结束)使用react。它看起来像是事件处理的候选者。我想用azure函数
我想编写方法来通过号码发送短信并使用编辑文本字段中的文本。发送消息后,我想收到一些声音或其他东西来提醒我收到短信。我怎样才能做到这一点?先感谢您,狼。 最佳答案 这个网站似乎对两者都有很好的描述:ht
所以我正在用 Java 编写一个程序,在 DatagramSocket 和 DatagramPacket 的帮助下发送和接收数据。问题是,在我发送数据/接收数据之间的某个时间 - 我发送数据的程序中的
我是 Android 编程新手,我正在用 Java 编写一个应用程序,该应用程序可以打开相机拍照并保存。我通过 Intents 做到了,但看不到 onActivityResult 正在运行。 我已经在
我有一个套接字服务器和一个套接字客户端。客户端只有一个套接字。我必须使用线程在客户端发送/接收数据。 static int sock = -1; static std::mutex mutex; vo
我正在尝试使用 c 中的套接字实现 TCP 服务器/客户端。我以这样的方式编写程序,即我们在客户端发送的任何内容都逐行显示在服务器中,直到键入退出。该程序可以运行,但数据最后一起显示在服务器中。有人可
我正在使用微 Controller 与 SIM808 模块通信,我想发送和接收 AT 命令。 现在的问题是,对于某些命令,我只收到了我应该收到的答案的一部分,但对于其他一些命令,我收到了我应该
我用c设计了一个消息传递接口(interface),用于在我的系统中运行的不同进程之间提供通信。该接口(interface)为此目的创建 10-12 个线程,并使用 TCP 套接字提供通信。 它工作正
我需要澄清一下在套接字程序中使用多个发送/接收。我的客户端程序如下所示(使用 TCP SOCK_STREAM)。 send(sockfd,"Messgfromlient",15,0);
我正在构建一个真正的基本代理服务器到我现有的HTTP服务器中。将传入连接添加到队列中,并将信号发送到另一个等待线程队列中的一个线程。此线程从队列中获取传入连接并对其进行处理。 问题是代理程序真的很慢。
我正在使用 $routeProvider 设置一条类似 的路线 when('/grab/:param1/:param2', { controller: 'someController',
我在欧洲有通过 HLS 流式传输的商业流媒体服务器。http://europe.server/stream1/index.m3u8现在我在美国的客户由于距离而遇到一些网络问题。 所以我在美国部署了新服
我有一个长期运行的 celery 任务,该任务遍历一系列项目并执行一些操作。 任务应该以某种方式报告当前正在处理的项目,以便最终用户知道任务的进度。 目前,我的django应用程序和celery一起坐
我需要将音频文件从浏览器发送到 python Controller 。我是这样做的: var xmlHttp = new XMLHttpRequest(); xmlHttp.open( "POST",
我是一名优秀的程序员,十分优秀!