From: Ben Pfaff <blp@nicira.com>
To: Jamal Hadi Salim <hadi@cyberus.ca>
Cc: netdev@vger.kernel.org
Subject: tc: RTM_GETQDISC causes kernel OOPS
Date: Fri, 21 May 2010 15:42:43 -0700 [thread overview]
Message-ID: <20100521224243.GD10247@nicira.com> (raw)
Hi. While working on some library code for working with qdiscs and
classes I came upon a kernel OOPS. Originally I came across it with a
2.6.26 kernel, but I can also reproduce it with unmodified v2.6.34 from
kernel.org.
At the end of this mail I'm appending both an example of the OOPS and a
simple test program that reliably reproduces the problem for me when I
invoke it with "lo" as argument. The program does not need to be run as
root.
After the OOPS, a lot of networking and other system functions stop
working, so it seems to me a serious issue.
The null pointer dereference that causes the OOPS is the dereference of
the return value of qdisc_dev() in tc_fill_qdisc() in
net/sched/sch_api.c line 1163:
1161 tcm->tcm__pad1 = 0;
1162 tcm->tcm__pad2 = 0;
1163 tcm->tcm_ifindex = qdisc_dev(q)->ifindex;
1164 tcm->tcm_parent = clid;
1165 tcm->tcm_handle = q->handle;
I am pretty sure about that, because if I add "WARN_ON(!qdisc_dev(q));"
just before line 1163 then that warning triggers.
Thanks,
Ben.
----------------------------------------------------------------------
BUG: unable to handle kernel NULL pointer dereference at 00000050
IP: [<c12280c0>] tc_fill_qdisc+0x68/0x1e5
*pde = 00000000
Oops: 0000 [#1] SMP
last sysfs file:
Modules linked in:
Pid: 600, comm: qdisc Not tainted 2.6.34 #16 /
EIP: 0060:[<c12280c0>] EFLAGS: 00010282 CPU: 0
EIP is at tc_fill_qdisc+0x68/0x1e5
EAX: 00000000 EBX: ffffffff ECX: 00000000 EDX: c7222070
ESI: c14576e0 EDI: c7115200 EBP: c7239ca0 ESP: c7239c3c
DS: 007b ES: 007b FS: 00d8 GS: 0033 SS: 0068
Process qdisc (pid: 600, ti=c7239000 task=c720b700 task.ti=c7239000)
Stack:
00000024 00000014 00000000 c14323a0 c7222060 c7222060 c10a7abd 00001030
<0> 000000d0 c7222060 000000d0 c1228329 000000d0 00000fc4 000000d0 c7115200
<0> 000000d0 00000ec0 c7239cac c12104b1 00000ec0 c1457a98 c7115200 00000258
Call Trace:
[<c10a7abd>] ? __kmalloc_track_caller+0x122/0x131
[<c1228329>] ? qdisc_notify+0x2a/0xc8
[<c12104b1>] ? __alloc_skb+0x4e/0x115
[<c122838a>] ? qdisc_notify+0x8b/0xc8
[<c12287ea>] ? tc_get_qdisc+0x143/0x15d
[<c12286a7>] ? tc_get_qdisc+0x0/0x15d
[<c1220c28>] ? rtnetlink_rcv_msg+0x195/0x1af
[<c1220a93>] ? rtnetlink_rcv_msg+0x0/0x1af
[<c12329e2>] ? netlink_rcv_skb+0x30/0x75
[<c1220a8b>] ? rtnetlink_rcv+0x1e/0x26
[<c123281b>] ? netlink_unicast+0xc4/0x11a
[<c1232eda>] ? netlink_sendmsg+0x223/0x230
[<c120978c>] ? sock_sendmsg+0xa8/0xbf
[<c10514fc>] ? print_lock_contention_bug+0x14/0xd7
[<c101ebe4>] ? __wake_up+0x15/0x3b
[<c101ebe4>] ? __wake_up+0x15/0x3b
[<c101ec00>] ? __wake_up+0x31/0x3b
[<c10acda4>] ? fget_light+0x2d/0xaf
[<c109488d>] ? might_fault+0x47/0x81
[<c120acf9>] ? sys_sendto+0xa4/0xc0
[<c116b82c>] ? _copy_from_user+0x2e/0x108
[<c120ad92>] ? sys_connect+0x63/0x6e
[<c120ad2d>] ? sys_send+0x18/0x1a
[<c120aedb>] ? sys_socketcall+0xd4/0x1a5
[<c12ca931>] ? syscall_call+0x7/0xb
Code: 50 8b 55 08 89 f8 6a 14 ff 75 14 e8 49 fa ff ff 89 c2 83 c2 10 89 45 ac c6 42 01 00 66 c7 42 02 00 00 c6 40 10 00 8b 46 40 8b 00 <8b> 40 50 89 5a 0c 89 42 04 8b 46 20 89 42 08 8b 46 28 89 42 10
EIP: [<c12280c0>] tc_fill_qdisc+0x68/0x1e5 SS:ESP 0068:c7239c3c
CR2: 0000000000000050
---[ end trace 6fb85bbc66de8f42 ]---
----------------------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>
#include <linux/rtnetlink.h>
#include <linux/pkt_sched.h>
#include <net/if.h>
int
main(int argc, char *argv[])
{
struct {
struct nlmsghdr nlmsg;
struct tcmsg tcmsg;
} msg;
struct sockaddr_nl local, remote;
int ifindex;
int fd;
if (argc != 2) {
fprintf(stderr,
"usage: %s <netdev>\n"
"where <netdev> is a network device, e.g. \"lo\"\n",
argv[0]);
return EXIT_FAILURE;
}
/* Get ifindex. */
ifindex = if_nametoindex(argv[1]);
if (!ifindex) {
fprintf(stderr, "no network device named \"%s\"", argv[1]);
return EXIT_FAILURE;
}
/* Make rtnetlink socket. */
fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
if (fd < 0) {
perror("socket");
return EXIT_FAILURE;
}
/* Bind local address as our selected pid. */
memset(&local, 0, sizeof local);
local.nl_family = AF_NETLINK;
local.nl_pid = getpid();
if (bind(fd, (struct sockaddr *) &local, sizeof local) < 0) {
perror("bind");
return EXIT_FAILURE;
}
/* Bind remote address as the kernel (pid 0). */
memset(&remote, 0, sizeof remote);
remote.nl_family = AF_NETLINK;
remote.nl_pid = 0;
if (connect(fd, (struct sockaddr *) &remote, sizeof remote) < 0) {
perror("connect");
return EXIT_FAILURE;
}
/* Send "get" request. */
memset(&msg, 0, sizeof msg);
msg.nlmsg.nlmsg_len = sizeof msg;
msg.nlmsg.nlmsg_type = RTM_GETQDISC;
msg.nlmsg.nlmsg_flags = NLM_F_REQUEST | NLM_F_ECHO | NLM_F_ACK;
msg.nlmsg.nlmsg_seq = 1;
msg.nlmsg.nlmsg_pid = getpid();
msg.tcmsg.tcm_family = AF_UNSPEC;
msg.tcmsg.tcm_ifindex = ifindex;
msg.tcmsg.tcm_handle = 0;
msg.tcmsg.tcm_parent = TC_H_ROOT;
if (send(fd, &msg, sizeof msg, 0) < 0) {
perror("send");
return EXIT_FAILURE;
}
return 0;
}
next reply other threads:[~2010-05-21 23:13 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-05-21 22:42 Ben Pfaff [this message]
2010-05-22 7:18 ` tc: RTM_GETQDISC causes kernel OOPS Eric Dumazet
2010-05-22 9:51 ` Patrick McHardy
2010-05-22 12:31 ` jamal
2010-05-23 6:37 ` [PATCH] net_sched: Fix qdisc_notify() Eric Dumazet
2010-05-24 6:11 ` David Miller
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20100521224243.GD10247@nicira.com \
--to=blp@nicira.com \
--cc=hadi@cyberus.ca \
--cc=netdev@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.