Hi,
I write a kernel module and a userspace client. They use netlink sockets to communicate with each
other. The source codes and the last kernel log before system crashed are attached below.
Inserting the module is ok but when I ran the client, my kernel crashed after the client received
first message from the module. Is there anything wrong in my codes? I think the problem is the
netlink_unicast(), because when I didn't call it, everything work well. Please help me.
Thank you.
=== nltest.c - kernel module ===
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <net/sock.h>
#include <linux/socket.h>
#include <linux/net.h>
#include <asm/types.h>
#include <linux/netlink.h>
#include <linux/skbuff.h>
#define NETLINK_VFW 18
#define VFW_GROUP 0
#define MSG_SIZE NLMSG_SPACE(1024)
static struct sock *nl_sk = NULL;
static void nltest_rcv(struct sock *sk, int len)
{
struct sk_buff *nl_skb;
struct nlmsghdr *nl_hdr;
int pid;
while ((nl_skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) {
nl_hdr = (struct nlmsghdr *)nl_skb->data;
pid = nl_hdr->nlmsg_pid;
printk(KERN_ALERT "nltest: message from user (pid = %d) = %s\n", pid, (char
*)NLMSG_DATA(nl_hdr));
nl_skb = alloc_skb(MSG_SIZE, in_interrupt() ? GFP_ATOMIC : GFP_KERNEL);
skb_put(nl_skb, MSG_SIZE);
nl_hdr = (struct nlmsghdr *)nl_skb->data;
nl_hdr->nlmsg_len = MSG_SIZE;
nl_hdr->nlmsg_pid = 0;
nl_hdr->nlmsg_flags = 0;
strcpy(NLMSG_DATA(nl_hdr), "hello user abcd1234");
NETLINK_CB(nl_skb).pid = 0;
NETLINK_CB(nl_skb).dst_pid = pid;
NETLINK_CB(nl_skb).dst_group = VFW_GROUP;
netlink_unicast(nl_sk, nl_skb, pid, 0);
kfree_skb(nl_skb);
}
}
static int __init nltest_init(void)
{
printk(KERN_ALERT "nltest: init\n");
nl_sk = netlink_kernel_create(NETLINK_VFW, VFW_GROUP, nltest_rcv, THIS_MODULE);
if (!nl_sk) {
printk(KERN_ALERT "nltest: netlink_kernel_create() failed\n");
return -1;
}
return 0;
}
static void __exit nltest_exit(void)
{
printk(KERN_ALERT "nltest: exit\n");
sock_release(nl_sk->sk_socket);
return;
}
module_init(nltest_init);
module_exit(nltest_exit);
MODULE_DESCRIPTION("Netlink Test");
MODULE_LICENSE("GPL");
=== nlclient.c - userspace client ===
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <asm/types.h>
#include <linux/netlink.h>
#define NETLINK_VFW 18
#define VFW_GROUP 0
#define MSG_SIZE NLMSG_SPACE(1024)
int main(void)
{
int nl_sd;
struct sockaddr_nl src_addr;
struct nlmsghdr *nl_hdr;
unsigned char buf[MSG_SIZE];
int ret;
memset(&src_addr, 0, sizeof(struct sockaddr_nl));
memset(buf, 0, MSG_SIZE);
nl_sd = socket(PF_NETLINK, SOCK_RAW, NETLINK_VFW);
src_addr.nl_family = AF_NETLINK;
src_addr.nl_pid = getpid();
src_addr.nl_groups = VFW_GROUP;
bind(nl_sd, (struct sockaddr *)&src_addr, sizeof(struct sockaddr));
nl_hdr = (struct nlmsghdr *)buf;
nl_hdr->nlmsg_len = MSG_SIZE;
nl_hdr->nlmsg_pid = getpid();
nl_hdr->nlmsg_flags = 0;
strcpy(NLMSG_DATA(nl_hdr), "hello kernel");
ret = send(nl_sd, buf, MSG_SIZE, 0);
printf("send ret = %d\n", ret);
if (ret == -1)
return ret;
while (1) {
ret = recv(nl_sd, buf, MSG_SIZE, 0);
printf("message from kernel = %s\n", (char *)NLMSG_DATA(nl_hdr));
}
return 0;
}
=== syslog ===
Hi,
I write a kernel module and a userspace client. They use netlink sockets to communicate with each
other. The source codes are attached below. Inserting the module is ok but when I ran the client,
my kernel crashed after the client received first message from the module. Is there anything wrong
in my codes?
Thank you.
=== nltest.c - kernel module ===
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <net/sock.h>
#include <linux/socket.h>
#include <linux/net.h>
#include <asm/types.h>
#include <linux/netlink.h>
#include <linux/skbuff.h>
#define NETLINK_VFW 18
#define VFW_GROUP 0
#define MSG_SIZE NLMSG_SPACE(1024)
static struct sock *nl_sk = NULL;
static void nltest_rcv(struct sock *sk, int len)
{
struct sk_buff *nl_skb;
struct nlmsghdr *nl_hdr;
int pid;
while ((nl_skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) {
nl_hdr = (struct nlmsghdr *)nl_skb->data;
pid = nl_hdr->nlmsg_pid;
printk(KERN_ALERT "nltest: message from user (pid = %d) = %s\n", pid, (char
*)NLMSG_DATA(nl_hdr));
nl_skb = alloc_skb(MSG_SIZE, in_interrupt() ? GFP_ATOMIC : GFP_KERNEL);
skb_put(nl_skb, MSG_SIZE);
nl_hdr = (struct nlmsghdr *)nl_skb->data;
nl_hdr->nlmsg_len = MSG_SIZE;
nl_hdr->nlmsg_pid = pid;
nl_hdr->nlmsg_flags = 0;
strcpy(NLMSG_DATA(nl_hdr), "hello user abcd1234");
NETLINK_CB(nl_skb).pid = 0;
NETLINK_CB(nl_skb).dst_pid = pid;
NETLINK_CB(nl_skb).dst_group = VFW_GROUP;
netlink_unicast(nl_sk, nl_skb, pid, 0);
kfree_skb(nl_skb);
}
}
static int __init nltest_init(void)
{
printk(KERN_ALERT "nltest: init\n");
nl_sk = netlink_kernel_create(NETLINK_VFW, VFW_GROUP, nltest_rcv, THIS_MODULE);
if (!nl_sk) {
printk(KERN_ALERT "nltest: netlink_kernel_create() failed\n");
return -1;
}
return 0;
}
static void __exit nltest_exit(void)
{
printk(KERN_ALERT "nltest: exit\n");
sock_release(nl_sk->sk_socket);
return;
}
module_init(nltest_init);
module_exit(nltest_exit);
MODULE_DESCRIPTION("Netlink Test");
MODULE_LICENSE("GPL");
=== nlclient.c - userspace client ===
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <asm/types.h>
#include <linux/netlink.h>
#define NETLINK_VFW 18
#define VFW_GROUP 0
#define MSG_SIZE NLMSG_SPACE(1024)
int main(void)
{
int nl_sd;
struct sockaddr_nl src_addr;
struct nlmsghdr *nl_hdr;
unsigned char buf[MSG_SIZE];
int ret;
memset(&src_addr, 0, sizeof(struct sockaddr_nl));
memset(buf, 0, MSG_SIZE);
nl_sd = socket(PF_NETLINK, SOCK_RAW, NETLINK_VFW);
src_addr.nl_family = AF_NETLINK;
src_addr.nl_pid = getpid();
src_addr.nl_groups = VFW_GROUP;
bind(nl_sd, (struct sockaddr *)&src_addr, sizeof(struct sockaddr));
nl_hdr = (struct nlmsghdr *)buf;
nl_hdr->nlmsg_len = MSG_SIZE;
nl_hdr->nlmsg_pid = getpid();
nl_hdr->nlmsg_flags = 0;
strcpy(NLMSG_DATA(nl_hdr), "hello kernel");
ret = send(nl_sd, buf, MSG_SIZE, 0);
printf("send ret = %d\n", ret);
if (ret == -1)
return ret;
while (1) {
ret = recv(nl_sd, buf, MSG_SIZE, 0);
printf("message from kernel = %s\n", (char *)NLMSG_DATA(nl_hdr));
}
return 0;
}
=== syslog ===J
Jan 8 15:42:07 vfw kernel: [ 61.627275] nltest: init
Jan 8 15:42:10 vfw kernel: [ 64.540280] nltest: message from user (pid = 2467) = hello kernel
Jan 8 15:42:10 vfw kernel: [ 64.550012] Unable to handle kernel NULL pointer dereference at
virtual address 00000004
Jan 8 15:42:10 vfw kernel: [ 64.551283] printing eip:
Jan 8 15:42:10 vfw kernel: [ 64.552893] c041c83f
Jan 8 15:42:10 vfw kernel: [ 64.552950] *pde = 00000000
Jan 8 15:42:10 vfw kernel: [ 64.553106] Oops: 0002 [#1]
Jan 8 15:42:10 vfw kernel: [ 64.555635] Modules linked in: nltest vmhgfs
Jan 8 15:42:10 vfw kernel: [ 64.561239] CPU: 0
Jan 8 15:42:10 vfw kernel: [ 64.561249] EIP: 0060:[<c041c83f>] Tainted: P VLI
Jan 8 15:42:10 vfw kernel: [ 64.561254] EFLAGS: 00010046 (2.6.14.5)
Jan 8 15:42:10 vfw kernel: [ 64.573449] EIP is at skb_dequeue+0x2f/0x60
Jan 8 15:42:10 vfw kernel: [ 64.577072] eax: 00000000 ebx: c59d3080 ecx: 00000000 edx:
00000282
Jan 8 15:42:10 vfw kernel: [ 64.578352] esi: c59da1e0 edi: c59d308c ebp: c59d3080 esp:
c2609d10
Jan 8 15:42:10 vfw kernel: [ 64.588064] ds: 007b es: 007b ss: 0068
Jan 8 15:42:10 vfw kernel: [ 64.594769] Process nlclient (pid: 2467, threadinfo=c2608000
task=c5ba9030)
Jan 8 15:42:10 vfw kernel: [ 64.595567] Stack: 00000000 c59d3000 c59d3000 c041d598 c59d3080
00000320 c10c3000 7fffffff
Jan 8 15:42:10 vfw kernel: [ 64.600285] c24b9ac0 c59d3000 00000410 c2609f2c c042f616
c59d3000 00000000 00000000
Jan 8 15:42:10 vfw kernel: [ 64.614903] c2609d60 00000001 00000000 c2609dac c68f3a00
00000000 00000286 00000007
Jan 8 15:42:10 vfw kernel: [ 64.624126] Call Trace:
Jan 8 15:42:10 vfw kernel: [ 64.638760] [<c041d598>] skb_recv_datagram+0xc8/0xd0
Jan 8 15:42:10 vfw kernel: [ 64.644494] [<c042f616>] netlink_recvmsg+0x56/0x250
Jan 8 15:42:10 vfw kernel: [ 64.656522] [<c0303042>] soft_cursor+0x192/0x1f0
Jan 8 15:42:10 vfw kernel: [ 64.660636] [<c0416383>] sock_recvmsg+0xf3/0x110
Jan 8 15:42:10 vfw kernel: [ 64.668551] [<c02fa4f9>] bit_cursor+0x349/0x550
Jan 8 15:42:10 vfw kernel: [ 64.676291] [<c0134b40>] autoremove_wake_function+0x0/0x60
Jan 8 15:42:10 vfw kernel: [ 64.682837] [<c0417772>] sys_recvfrom+0xb2/0x120
Jan 8 15:42:10 vfw kernel: [ 64.691864] [<c0337038>] write_chan+0x158/0x230
Jan 8 15:42:10 vfw kernel: [ 64.698739] [<c011c70e>] __wake_up+0x3e/0x60
Jan 8 15:42:10 vfw kernel: [ 64.708252] [<c033174d>] tty_write+0x1ed/0x240
Jan 8 15:42:10 vfw kernel: [ 64.712340] [<c0417813>] sys_recv+0x33/0x40
Jan 8 15:42:10 vfw kernel: [ 64.724514] [<c0417f34>] sys_socketcall+0x164/0x260
Jan 8 15:42:10 vfw kernel: [ 64.728817] [<c015eab1>] sys_write+0x51/0x80
Jan 8 15:42:10 vfw kernel: [ 64.740049] [<c01030b9>] syscall_call+0x7/0xb
Jan 8 15:42:10 vfw kernel: [ 64.744699] Code: 1c 24 8b 5c 24 10 89 7c 24 08 89 74 24 04 8d 7b
0c 31 f6 89 f8 e8 42 4b 0c 00 89 c2 8b 03 39 d8 74 19 89 c6 8b 00 ff 4b 08 89 03 <89> 58 04 c7 06
00 00 00 00 c7 46 04 00 00 00 00 89 f8 e8 5a 4c
__________________________________________
Yahoo! DSL ? Something to write home about.
Just $16.99/mo. or less.
dsl.yahoo.com
Hi Mikado,
On Sun, 8 Jan 2006 01:25:05 -0800 (PST)
Mikado <Mikado <[email protected]>> wrote:
| Is there anything wrong in my codes? I think the problem is the
| netlink_unicast(), because when I didn't call it, everything work well.
Check whether nl_sk equals NULL.
I don't know whether there's an assert() macro available for you, so try this:
/* [...] */
if (nl_sk == NULL)
{
printk(KERN_ALERT "nltest: nl_sk is NULL!");
goto return_free;
}
netlink_unicast(nl_sk, nl_skb, pid, 0);
return_free:
kfree_skb(nl_skb);
}
A gdb backtrace of the user space part won't give you much, since you
found out the problem lies in kernel space.
What does netlink_unicast() do?
Leslie
--
gpg --keyserver pgp.mit.edu --recv-keys 0x52D70289