[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <20080520174912.GA6231@alice>
Date: Tue, 20 May 2008 19:49:12 +0200
From: Eric Sesterhenn <snakebyte@....de>
To: netdev@...r.kernel.org
Subject: oops in skb_under_panic with linux-next
hi,
i saw the following oops with linux-next from today
running icmpv6fuzz -r 2187
I was able to reproduce this, but didnt try rebooting and reproducing
since i am currently not at home
[ 5354.117714] invalid cmsg type: 1035331808
[ 5354.117896] icmpv6: msg of unknown type
[ 5354.161756] skb_under_panic: text:c056ccf7 len:1256 put:864
head:c21db5e0 data:c21db338 tail:0xc21db698 end:0xc21db6a0 dev:<NULL>
[ 5354.170788] ------------[ cut here ]------------
[ 5354.170909] kernel BUG at net/core/skbuff.c:149!
[ 5354.170986] invalid opcode: 0000 [#2] PREEMPT DEBUG_PAGEALLOC
[ 5354.171210] Modules linked in: nfsd exportfs
[ 5354.171344]
[ 5354.171344] Pid: 2187, comm: icmpv6fuzz Tainted: G D
(2.6.26-rc3 #26)
[ 5354.171344] EIP: 0060:[<c04cfbfc>] EFLAGS: 00010282 CPU: 0
[ 5354.171344] EIP is at skb_under_panic+0x5c/0x60
[ 5354.171344] EAX: 00000088 EBX: c21db5e0 ECX: 10000000 EDX: 00000000
[ 5354.171344] ESI: 00000000 EDI: c617dc30 EBP: c3d1cc48 ESP: c3d1cc1c
[ 5354.171344] DS: 007b ES: 007b FS: 0000 GS: 0033 SS: 0068
[ 5354.171344] Process icmpv6fuzz (pid: 2187, ti=c3d1c000 task=c45c1f80
task.ti=c3d1c000)
[ 5354.171344] Stack: c076f6ec c056ccf7 000004e8 00000360 c21db5e0
c21db338 c21db698 c21db6a0
[ 5354.171344] c07383b3 cb9008c0 c61b50fc c3d1cc54 c04d0c0a
c3d1ccb3 c3d1cc70 c056ccf7
[ 5354.171344] 0000003c 00000005 cb9008c0 cf199584 c617dc30
c3d1cc80 c056cd53 c61b50fc
[ 5354.171344] Call Trace:
[ 5354.171344] [<c056ccf7>] ? ipv6_push_exthdr+0x27/0x60
[ 5354.171344] [<c04d0c0a>] ? skb_push+0x2a/0x40
[ 5354.171344] [<c056ccf7>] ? ipv6_push_exthdr+0x27/0x60
[ 5354.171344] [<c056cd53>] ? ipv6_push_frag_opts+0x23/0x30
[ 5354.171344] [<c054b678>] ? ip6_push_pending_frames+0x1c8/0x410
[ 5354.171344] [<c04d02ac>] ? skb_store_bits+0x11c/0x230
[ 5354.171344] [<c0560ddc>] ? rawv6_sendmsg+0xa8c/0xce0
[ 5354.171344] [<c017a3f1>] ? check_bytes_and_report+0x21/0xc0
[ 5354.171344] [<c017a0d3>] ? slab_pad_check+0x73/0x110
[ 5354.171344] [<c0521714>] ? inet_sendmsg+0x34/0x60
[ 5354.171344] [<c04cae44>] ? sock_sendmsg+0xc4/0xf0
[ 5354.171344] [<c017b813>] ? __slab_free+0x63/0x2e0
[ 5354.171344] [<c0138420>] ? autoremove_wake_function+0x0/0x40
[ 5354.171344] [<c04caf9f>] ? sys_sendmsg+0x12f/0x230
[ 5354.171344] [<c036daa6>] ? copy_from_user+0x46/0x80
[ 5354.171344] [<c04cb145>] ? sys_sendto+0xa5/0xd0
[ 5354.171344] [<c04cce8f>] ? release_sock+0xbf/0xd0
[ 5354.171344] [<c05fe0af>] ? _spin_unlock_bh+0x2f/0x40
[ 5354.171344] [<c04cc36e>] ? sock_ioctl+0x6e/0x1b0
[ 5354.171344] [<c04cbffd>] ? sys_socketcall+0x13d/0x260
[ 5354.171344] [<c0103d7d>] ? sysenter_past_esp+0x6a/0xb1
[ 5354.171344] =======================
[ 5354.171344] Code: 00 00 89 5c 24 14 8b 98 90 00 00 00 89 54 24 0c 89
5c 24 10 8b 40 50 89 4c 24 04 c7 04 24 ec f6 76 c0 89 44 24 08 e8 a4 69
c5 ff <0f> 0b eb fe 55 89 e5 56 53 bb b3 83 73 c0 83 ec 24 8b 70 14 85
[ 5354.171344] EIP: [<c04cfbfc>] skb_under_panic+0x5c/0x60 SS:ESP
0068:c3d1cc1c
[ 5354.253156] ---[ end trace 0ab24c034e0bf829 ]---
here is the sourcecode for icmpv6fuzz in case this makes the bughunting
easier
/*
* ICMPv6 or ICMPv4 socket fuzzer.
*
* Copyright (c) 2006, Clément Lecigne
*/
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/param.h>
#include <net/if.h>
//#include <net/if_var.h>
#include <sys/uio.h>
//#include <netinet6/ip6_mroute.h>
//#include <netinet6/in6_var.h>
#define SIOCGETMIFCNT_IN6 SIOCPROTOPRIVATE /* IP protocol privates */
#define SIOCGETSGCNT_IN6 (SIOCPROTOPRIVATE+1)
#define SIOCGETRPF (SIOCPROTOPRIVATE+2)
/* functions */
unsigned int randaddr(void);
void randsoopt(int);
void randgoopt(int);
void randioctl(int);
void usage(char *);
/*
* boucle until we hit a valid socket option
*/
void randsoopt(int sock)
{
unsigned int optval;
int optlen, optname, level, ret, on = rand() % 2;
do
{
switch (rand() % 5)
{
case 0:
level = IPPROTO_IPV6;
break;
case 1:
level = SOL_SOCKET;
break;
case 2:
level = IPPROTO_RAW;
break;
case 3:
level = rand() & 0xFF;
break;
case 4:
level = IPPROTO_IP;
break;
}
if (rand() % 6)
{
optlen = rand();
optval = (unsigned int)randaddr();
}
else
{
/*
* In some cases, kernel excepts that
* optlen == sizeof (int) and that's
* the first bound checking.
*/
optlen = sizeof (int);
on = rand();
optval = (unsigned int)&on;
}
if (rand() % 8)
optname = rand() % 255;
else
optname = rand();
#if 0
/*
* anti well know FreeBSD mbufs exhaustion.
*/
if (optname == 25 || optname == IPV6_IPSEC_POLICY ||
optname == IPV6_FW_ADD || optname == IPV6_FW_FLUSH
|| optname == IPV6_FW_DEL || optname == IPV6_FW_ZERO)
continue;
/*printf("level : %d - optname : %d - optlen : %d\n",
level, optname, optlen);*/
#endif
ret = setsockopt(sock, level, optname, (void *)optval, optlen);
}while(ret == -1);
return;
}
/*
* ioctl ipv6 socket fuzzer.
*/
void randioctl(int sock)
{
unsigned long reqs[] = { SIOCGETSGCNT_IN6, SIOCGETMIFCNT_IN6,
SIOCGETRPF};
/*
GSCOPE6DEF, SIOCGLIFADDR, SIOCSIFPHYADDR_IN6, SIOCGIFNETMASK_IN6,
SIOCAIFADDR_IN6, SIOCGIFDSTADDR_IN6, SIOCSIFALIFETIME_IN6,
SIOCGIFADDR_IN6, SIOCGIFDSTADDR_IN6, SIOCGIFNETMASK_IN6, SIOCGIFAFLAG_IN6,
SIOCGIFSTAT_IN6, SIOCGIFSTAT_ICMP6, SIOCGIFALIFETIME_IN6, SIOCSIFALIFETIME_IN6,
SIOCAIFADDR_IN6, SIOCDIFADDR_IN6 }; */
unsigned int arg;
int ret;
unsigned long request;
if (rand() % 8)
request = reqs[rand() % (sizeof (reqs) / sizeof (reqs[0]))];
else
request = rand() + rand();
if (rand() % 2)
{
arg = randaddr();
ret = ioctl(sock, request, (caddr_t)arg);
}
else
{
arg = rand();
ret = ioctl(sock, request, (int)arg);
}
}
/*
* return a random address
*/
unsigned int randaddr(void)
{
char *p = malloc(1);
unsigned int heap = (unsigned int)p;
free(p);
switch (rand() % 4)
{
case 0:
return (heap + (rand() & 0xFFF));
case 1:
return ((unsigned int)&heap + (rand() & 0xFFF));
case 2:
return (0xc0000000 + (rand() & 0xFFFF));
case 3:
return (rand());
}
return (0);
}
int main(int ac, char **av)
{
int32_t cc, s, occ, i, j, a, try, count, opts;
u_int32_t seed, maxsize;
u_int8_t ip6;
char c, *buf;
struct addrinfo *res, hints;
struct sockaddr_in6 from;
socklen_t fromlen;
struct msghdr msg;
struct cmsghdr *cmsg = NULL;
struct iovec iov;
/* default values */
seed = getpid();
count = 50;
occ = 10000;
maxsize = 4096;
opts = 50;
ip6 = 1;
fromlen = sizeof(from);
if (getuid())
{
fprintf(stderr, " - you must be root.\n");
exit(EXIT_FAILURE);
}
while ((c = getopt(ac, av, "r:n:c:m:o:46")) != EOF)
{
switch (c)
{
case '6':
ip6 = 1;
break;
case '4':
ip6 = 0;
break;
case 'r':
seed = atoi(optarg);
break;
case 'n':
occ = atoi(optarg);
break;
case 'c':
count = atoi(optarg);
break;
case 'm':
maxsize = atoi(optarg);
break;
case 'o':
opts = atoi(optarg);
break;
default:
usage(av[0]);
break;
}
}
printf("seeding with %u\n", seed);
srand(seed);
buf = malloc(maxsize);
if (buf == NULL)
{
printf("%s: out of memory.\n", av[0]);
exit(EXIT_FAILURE);
}
memset(&hints, 0, sizeof(hints));
hints.ai_flags = AI_CANONNAME;
hints.ai_socktype = SOCK_RAW;
if(ip6)
{
hints.ai_family = AF_INET6;
hints.ai_protocol = IPPROTO_ICMPV6;
getaddrinfo("::1", NULL, &hints, &res);
}
else
{
hints.ai_family = AF_INET;
hints.ai_protocol = IPPROTO_ICMP;
getaddrinfo("127.0.0.1", NULL, &hints, &res);
}
for (i = 0; i < occ; i++)
{
printf(".\n");
s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
//cc = bind(s, res->ai_addr, res->ai_addrlen);
for (j = 0; j < opts; j++)
{
randsoopt(s);
//randgoopt(s);
randioctl(s);
for (a = 0; a < 32; a++)
buf[a] = rand() % 255;
try = 0;
do
{
switch(rand() % 3)
{
case 0:
cc = sendto(s, buf, rand() % maxsize, 0,
(struct sockaddr *)res->ai_addr, res->ai_addrlen);
break;
case 1:
case 2:
msg.msg_controllen = (rand() % 2) ? rand() & maxsize : 0;
if (msg.msg_controllen)
{
if (msg.msg_controllen < sizeof (struct cmsghdr))
cmsg = (struct cmsghdr *)malloc(sizeof (struct cmsghdr));
else
cmsg = (struct cmsghdr *)malloc(msg.msg_controllen);
if (cmsg == NULL) goto nocmsghdr;
msg.msg_control = cmsg;
cmsg->cmsg_level = (rand() % 2) ? IPPROTO_IPV6 : rand();
cmsg->cmsg_type = (rand() % 2) ? rand() % 255 : rand();
cmsg->cmsg_len = (rand() % 2) ? msg.msg_controllen : rand();
}
else
{
nocmsghdr:
msg.msg_control = (rand() % 5) ? NULL : (void*)randaddr();
msg.msg_controllen = (rand() % 2) ? rand() : 0;
}
iov.iov_len = (rand() % 2) ? rand() : rand() & maxsize;
iov.iov_base = (rand() % 2) ? (void*)randaddr() : &buf;
msg.msg_iov = (rand() % 2) ? (void*)randaddr() : &iov;
if (rand() % 5)
{
msg.msg_name = res->ai_addr;
msg.msg_namelen = res->ai_addrlen;
}
else
{
msg.msg_name = (caddr_t)randaddr();
msg.msg_namelen = rand();
}
msg.msg_flags = rand();
cc = sendmsg (s, &msg, rand());
}
if (cmsg != NULL)
{
// free(cmsg);
// cmsg = NULL;
}
try++;
} while(cc == -1 && try != count);
recvmsg(s, &msg, MSG_DONTWAIT);
}
close(s);
}
free(buf);
freeaddrinfo(res);
exit(EXIT_SUCCESS);
}
/*
* usage
*/
void usage(char *prog)
{
printf("usage: %s [-4] [-6] [-r seed] [-c sendto-timeout]\n"
" [-m maxsize] [-o maxsetsockopt] [-n occ]\n", prog);
exit(EXIT_FAILURE);
}
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Powered by blists - more mailing lists