* [lockup] 2.6.17-rc3: netfilter/sctp: lockup in sctp_new(), do_basic_checks()
@ 2006-05-02 11:34 Ingo Molnar
2006-05-02 13:40 ` Ingo Molnar
` (2 more replies)
0 siblings, 3 replies; 16+ messages in thread
From: Ingo Molnar @ 2006-05-02 11:34 UTC (permalink / raw)
To: linux-kernel; +Cc: Andrew Morton, David S. Miller, Herbert Xu, coreteam
running an "isic" stresstest on and against a testbox [which, amongst
other things, generates random incoming and outgoing packets] on
2.6.17-rc3 (and 2.6.17-rc3-mm1) over gigabit results in a reproducible
lockup, after 5-10 minutes of runtime:
BUG: soft lockup detected on CPU#0!
[<c0104e7f>] show_trace+0xd/0xf
[<c0104e96>] dump_stack+0x15/0x17
[<c015ad02>] softlockup_tick+0xc5/0xd9
[<c0134c02>] run_local_timers+0x22/0x24
[<c0134fb7>] update_process_times+0x40/0x65
[<c011aa56>] smp_apic_timer_interrupt+0x58/0x60
[<c010492b>] apic_timer_interrupt+0x27/0x2c
[<c0f00df9>] sctp_new+0x8b/0x235
[<c0ef9666>] ip_conntrack_in+0x175/0x4ca
[<c0eb6dd7>] nf_iterate+0x31/0x94
[<c0eb6e83>] nf_hook_slow+0x49/0xda
[<c0ec2f55>] ip_rcv+0x24c/0x567
[<c0e7dec4>] netif_receive_skb+0x34b/0x397
[<c07870cb>] rtl8139_poll+0x3d8/0x5db
[<c0e7c7ad>] net_rx_action+0x9b/0x1ba
[<c0131955>] __do_softirq+0x6e/0xec
[<c0106187>] do_softirq+0x59/0xcd
=======================
[<c0131427>] local_bh_enable+0x111/0x15d
[<c0e7d8fb>] dev_queue_xmit+0x218/0x222
[<c0ec7e2a>] ip_output+0x20b/0x249
[<c0ec5711>] ip_push_pending_frames+0x331/0x3fe
[<c0ede6e3>] raw_sendmsg+0x5cf/0x678
[<c0ee62f8>] inet_sendmsg+0x39/0x46
[<c0e7406f>] sock_sendmsg+0xf2/0x10d
[<c0e741e5>] sys_sendmsg+0x15b/0x1c9
[<c0e748b5>] sys_socketcall+0x16f/0x18a
[<c1048c1b>] syscall_call+0x7/0xb
this is with FRAME_POINTERS enabled, so it's an exact stacktrace.
the lockup is at:
(gdb) list *0xc0f00df9
0xc0f00df9 is in sctp_new
(net/ipv4/netfilter/ip_conntrack_proto_sctp.c:444).
439
440 sh = skb_header_pointer(skb, iph->ihl * 4, sizeof(_sctph), &_sctph);
441 if (sh == NULL)
442 return 0;
443
444 if (do_basic_checks(conntrack, skb, map) != 0)
445 return 0;
446
447 /* If an OOTB packet has any of these chunks discard (Sec 8.4) */
448 if ((test_bit (SCTP_CID_ABORT, (void *)map))
most likely somewhere within do_basic_checks(). [whose stack entry is
obscured by the irq entry, so it's not in the stackdump.] I have SCTP
turned on:
CONFIG_NETFILTER_XT_MATCH_SCTP=y
CONFIG_IP_NF_CT_PROTO_SCTP=y
# SCTP Configuration (EXPERIMENTAL)
CONFIG_IP_SCTP=y
but otherwise it's a stock Fedora install.
the full log and configs can be found at:
http://redhat.com/~mingo/misc/crash3.log
http://redhat.com/~mingo/misc/config3
this is a v2.6.17 showstopper i guess?
Ingo
^ permalink raw reply [flat|nested] 16+ messages in thread* Re: [lockup] 2.6.17-rc3: netfilter/sctp: lockup in sctp_new(), do_basic_checks() 2006-05-02 11:34 [lockup] 2.6.17-rc3: netfilter/sctp: lockup in sctp_new(), do_basic_checks() Ingo Molnar @ 2006-05-02 13:40 ` Ingo Molnar 2006-05-02 13:45 ` Ingo Molnar 2006-05-02 13:54 ` [netfilter-core] " Patrick McHardy 2006-05-02 13:45 ` [netfilter-core] " Patrick McHardy 2006-05-02 15:34 ` Marcel Holtmann 2 siblings, 2 replies; 16+ messages in thread From: Ingo Molnar @ 2006-05-02 13:40 UTC (permalink / raw) To: linux-kernel; +Cc: Andrew Morton, David S. Miller, Herbert Xu, coreteam * Ingo Molnar <mingo@elte.hu> wrote: > running an "isic" stresstest on and against a testbox [which, amongst > other things, generates random incoming and outgoing packets] on > 2.6.17-rc3 (and 2.6.17-rc3-mm1) over gigabit results in a reproducible > lockup, after 5-10 minutes of runtime: > > BUG: soft lockup detected on CPU#0! > [<c0104e7f>] show_trace+0xd/0xf > [<c0104e96>] dump_stack+0x15/0x17 > [<c015ad02>] softlockup_tick+0xc5/0xd9 > [<c0134c02>] run_local_timers+0x22/0x24 > [<c0134fb7>] update_process_times+0x40/0x65 > [<c011aa56>] smp_apic_timer_interrupt+0x58/0x60 > [<c010492b>] apic_timer_interrupt+0x27/0x2c > [<c0f00df9>] sctp_new+0x8b/0x235 > [<c0ef9666>] ip_conntrack_in+0x175/0x4ca > [<c0eb6dd7>] nf_iterate+0x31/0x94 > [<c0eb6e83>] nf_hook_slow+0x49/0xda > [<c0ec2f55>] ip_rcv+0x24c/0x567 > [<c0e7dec4>] netif_receive_skb+0x34b/0x397 > [<c07870cb>] rtl8139_poll+0x3d8/0x5db > [<c0e7c7ad>] net_rx_action+0x9b/0x1ba > [<c0131955>] __do_softirq+0x6e/0xec > [<c0106187>] do_softirq+0x59/0xcd thinking about it, what prevents the SCTP chunk's len field from being zero, and thus causing an infinite loop in for_each_sctp_chunk()? The patch below should fix that. Ingo ---- From: Ingo Molnar <mingo@elte.hu> fix infinite loop in the SCTP-netfilter code: check SCTP chunk size to guarantee progress of for_each_sctp_chunk(). (all other uses of for_each_sctp_chunk() are preceded by do_basic_checks(), so this fix should be complete.) Signed-off-by: Ingo Molnar <mingo@elte.hu> Index: linux/net/ipv4/netfilter/ip_conntrack_proto_sctp.c =================================================================== --- linux.orig/net/ipv4/netfilter/ip_conntrack_proto_sctp.c +++ linux/net/ipv4/netfilter/ip_conntrack_proto_sctp.c @@ -227,6 +227,15 @@ static int do_basic_checks(struct ip_con flag = 0; for_each_sctp_chunk (skb, sch, _sch, offset, count) { + unsigned int len = (htons(sch->length) + 3) & ~3; + + /* + * Dont get into a loop with zero-sized or negative + * length values: + */ + if (!len || len >= skb->len) + goto fail; + DEBUGP("Chunk Num: %d Type: %d\n", count, sch->type); if (sch->type == SCTP_CID_INIT @@ -241,6 +250,7 @@ static int do_basic_checks(struct ip_con || sch->type == SCTP_CID_COOKIE_ECHO || flag) && count !=0 ) { +fail: DEBUGP("Basic checks failed\n"); return 1; } ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [lockup] 2.6.17-rc3: netfilter/sctp: lockup in sctp_new(), do_basic_checks() 2006-05-02 13:40 ` Ingo Molnar @ 2006-05-02 13:45 ` Ingo Molnar 2006-05-02 13:54 ` [netfilter-core] " Patrick McHardy 1 sibling, 0 replies; 16+ messages in thread From: Ingo Molnar @ 2006-05-02 13:45 UTC (permalink / raw) To: linux-kernel; +Cc: Andrew Morton, David S. Miller, Herbert Xu, coreteam * Ingo Molnar <mingo@elte.hu> wrote: > > running an "isic" stresstest on and against a testbox [which, amongst > > other things, generates random incoming and outgoing packets] on > > 2.6.17-rc3 (and 2.6.17-rc3-mm1) over gigabit results in a reproducible > > lockup, after 5-10 minutes of runtime: btw., just in case someone would like to build ISIC on a modern distro, the minimal fixes are below. The commandline i'm typically using for testing is: isic -s firstbox.com -d secondbox.com -m 50000 >/dev/null 2>/dev/null seems useful. Ingo --- icmpsic.c 2006-04-26 16:14:32.000000000 +0200 +++ icmpsic.c.orig 2006-04-26 16:14:33.000000000 +0200 @@ -265,7 +265,7 @@ main(int argc, char **argv) payload = (short int *)((u_char *) icmp + 4); for(cx = 0; cx <= (payload_s >> 1); cx+=1) - payload[cx] = rand() & 0xffff; + (u_short) payload[cx] = rand() & 0xffff; if ( rand() <= (RAND_MAX * ICMPCksm) ) --- isic.c 2006-04-26 16:14:32.000000000 +0200 +++ isic.c.orig 2006-04-26 16:14:33.000000000 +0200 @@ -229,8 +229,8 @@ main(int argc, char **argv) payload = (short int *)(buf + IP_H); for(cx = 0; cx <= (payload_s >> 1); cx+=1) - payload[cx] = rand() & 0xffff; - payload[payload_s] = rand() & 0xffff; + (u_int16_t) payload[cx] = rand() & 0xffff; + (u_int16_t) payload[payload_s] = rand() & 0xffff; if ( printout ) { printf("%s ->", --- tcpsic.c 2006-04-26 16:14:32.000000000 +0200 +++ tcpsic.c.orig 2006-04-26 16:14:32.000000000 +0200 @@ -317,7 +317,7 @@ main(int argc, char **argv) payload = (short int *)((u_char *) tcp + 20); for(cx = 0; cx <= (payload_s >> 1); cx+=1) - payload[cx] = rand() & 0xffff; + (u_int16_t) payload[cx] = rand() & 0xffff; if ( rand() <= (RAND_MAX * TCPCksm) ) libnet_do_checksum(l, (u_int8_t *)buf, IPPROTO_TCP, (tcp->th_off << 2) --- udpsic.c 2006-04-26 16:14:32.000000000 +0200 +++ udpsic.c.orig 2006-04-26 16:14:32.000000000 +0200 @@ -292,7 +292,7 @@ main(int argc, char **argv) payload = (short int *)((u_char *) udp + UDP_H); for(cx = 0; cx <= (payload_s >> 1); cx+=1) - payload[cx] = rand() & 0xffff; + (u_int16_t) payload[cx] = rand() & 0xffff; if ( printout ) { printf("%s,%i ->", ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [netfilter-core] Re: [lockup] 2.6.17-rc3: netfilter/sctp: lockup in sctp_new(), do_basic_checks() 2006-05-02 13:40 ` Ingo Molnar 2006-05-02 13:45 ` Ingo Molnar @ 2006-05-02 13:54 ` Patrick McHardy 2006-05-02 14:01 ` Ingo Molnar 1 sibling, 1 reply; 16+ messages in thread From: Patrick McHardy @ 2006-05-02 13:54 UTC (permalink / raw) To: Ingo Molnar Cc: linux-kernel, Andrew Morton, coreteam, David S. Miller, Herbert Xu Ingo Molnar wrote: > thinking about it, what prevents the SCTP chunk's len field from being > zero, and thus causing an infinite loop in for_each_sctp_chunk()? The > patch below should fix that. > > Ingo > > ---- > From: Ingo Molnar <mingo@elte.hu> > > fix infinite loop in the SCTP-netfilter code: check SCTP chunk size to > guarantee progress of for_each_sctp_chunk(). (all other uses of > for_each_sctp_chunk() are preceded by do_basic_checks(), so this fix > should be complete.) > > Signed-off-by: Ingo Molnar <mingo@elte.hu> > > Index: linux/net/ipv4/netfilter/ip_conntrack_proto_sctp.c > =================================================================== > --- linux.orig/net/ipv4/netfilter/ip_conntrack_proto_sctp.c > +++ linux/net/ipv4/netfilter/ip_conntrack_proto_sctp.c > @@ -227,6 +227,15 @@ static int do_basic_checks(struct ip_con > flag = 0; > > for_each_sctp_chunk (skb, sch, _sch, offset, count) { > + unsigned int len = (htons(sch->length) + 3) & ~3; > + > + /* > + * Dont get into a loop with zero-sized or negative > + * length values: > + */ > + if (!len || len >= skb->len) > + goto fail; > + I just came up with a similar fix :) I think I'm going to take my own patch though because its IMO slightly nicer. Thanks anyway. ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [netfilter-core] Re: [lockup] 2.6.17-rc3: netfilter/sctp: lockup in sctp_new(), do_basic_checks() 2006-05-02 13:54 ` [netfilter-core] " Patrick McHardy @ 2006-05-02 14:01 ` Ingo Molnar 2006-05-02 13:57 ` Patrick McHardy 0 siblings, 1 reply; 16+ messages in thread From: Ingo Molnar @ 2006-05-02 14:01 UTC (permalink / raw) To: Patrick McHardy Cc: linux-kernel, Andrew Morton, coreteam, David S. Miller, Herbert Xu * Patrick McHardy <kaber@trash.net> wrote: > Ingo Molnar wrote: > > thinking about it, what prevents the SCTP chunk's len field from being > > zero, and thus causing an infinite loop in for_each_sctp_chunk()? The > > patch below should fix that. > > > > Ingo > > > > ---- > > From: Ingo Molnar <mingo@elte.hu> > > > > fix infinite loop in the SCTP-netfilter code: check SCTP chunk size to > > guarantee progress of for_each_sctp_chunk(). (all other uses of > > for_each_sctp_chunk() are preceded by do_basic_checks(), so this fix > > should be complete.) > > > > Signed-off-by: Ingo Molnar <mingo@elte.hu> > > > > Index: linux/net/ipv4/netfilter/ip_conntrack_proto_sctp.c > > =================================================================== > > --- linux.orig/net/ipv4/netfilter/ip_conntrack_proto_sctp.c > > +++ linux/net/ipv4/netfilter/ip_conntrack_proto_sctp.c > > @@ -227,6 +227,15 @@ static int do_basic_checks(struct ip_con > > flag = 0; > > > > for_each_sctp_chunk (skb, sch, _sch, offset, count) { > > + unsigned int len = (htons(sch->length) + 3) & ~3; > > + > > + /* > > + * Dont get into a loop with zero-sized or negative > > + * length values: > > + */ > > + if (!len || len >= skb->len) > > + goto fail; > > + > > I just came up with a similar fix :) I think I'm going to take my own > patch though because its IMO slightly nicer. Thanks anyway. could you send your patch so that i can start using it instead of mine? Ingo ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [netfilter-core] Re: [lockup] 2.6.17-rc3: netfilter/sctp: lockup in sctp_new(), do_basic_checks() 2006-05-02 14:01 ` Ingo Molnar @ 2006-05-02 13:57 ` Patrick McHardy 2006-05-02 14:16 ` Ingo Molnar 0 siblings, 1 reply; 16+ messages in thread From: Patrick McHardy @ 2006-05-02 13:57 UTC (permalink / raw) To: Ingo Molnar Cc: linux-kernel, Andrew Morton, coreteam, David S. Miller, Herbert Xu [-- Attachment #1: Type: text/plain, Size: 322 bytes --] Ingo Molnar wrote: >> >>I just came up with a similar fix :) I think I'm going to take my own >>patch though because its IMO slightly nicer. Thanks anyway. > > > could you send your patch so that i can start using it instead of mine? I did a couple of minutes ago. Here it is again in case my last mail won't show up. [-- Attachment #2: x --] [-- Type: text/plain, Size: 2421 bytes --] [NETFILTER]: Fix endless loop in SCTP conntrack When a chunk length is zero, for_each_sctp_chunk() doesn't make any forward progress and loops forever. A chunk length of 0 is invalid, so just abort in that case. Reported by Ingo Molnar <mingo@elte.hu>. Signed-off-by: Patrick McHardy <kaber@trash.net> --- commit 32491b3d62bc8c3ff2400deebd46972ebc7332af tree 7249133ec32c18f4e6f989560e8d86b5e2e2cf0c parent 462f3ddd384045c731b3268a1b9c91c834a5a68a author Patrick McHardy <kaber@trash.net> Tue, 02 May 2006 15:44:30 +0200 committer Patrick McHardy <kaber@trash.net> Tue, 02 May 2006 15:44:30 +0200 net/ipv4/netfilter/ip_conntrack_proto_sctp.c | 4 ++-- net/netfilter/nf_conntrack_proto_sctp.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/net/ipv4/netfilter/ip_conntrack_proto_sctp.c b/net/ipv4/netfilter/ip_conntrack_proto_sctp.c index 5259abd..ebd4ecf 100644 --- a/net/ipv4/netfilter/ip_conntrack_proto_sctp.c +++ b/net/ipv4/netfilter/ip_conntrack_proto_sctp.c @@ -209,8 +209,8 @@ static int sctp_print_conntrack(struct s #define for_each_sctp_chunk(skb, sch, _sch, offset, count) \ for (offset = skb->nh.iph->ihl * 4 + sizeof(sctp_sctphdr_t), count = 0; \ offset < skb->len && \ - (sch = skb_header_pointer(skb, offset, sizeof(_sch), &_sch)); \ - offset += (htons(sch->length) + 3) & ~3, count++) + (sch = skb_header_pointer(skb, offset, sizeof(_sch), &_sch)) && \ + sch->length; offset += (htons(sch->length) + 3) & ~3, count++) /* Some validity checks to make sure the chunks are fine */ static int do_basic_checks(struct ip_conntrack *conntrack, diff --git a/net/netfilter/nf_conntrack_proto_sctp.c b/net/netfilter/nf_conntrack_proto_sctp.c index 9cccc32..2e34436 100644 --- a/net/netfilter/nf_conntrack_proto_sctp.c +++ b/net/netfilter/nf_conntrack_proto_sctp.c @@ -213,8 +213,8 @@ static int sctp_print_conntrack(struct s #define for_each_sctp_chunk(skb, sch, _sch, offset, dataoff, count) \ for (offset = dataoff + sizeof(sctp_sctphdr_t), count = 0; \ offset < skb->len && \ - (sch = skb_header_pointer(skb, offset, sizeof(_sch), &_sch)); \ - offset += (htons(sch->length) + 3) & ~3, count++) + (sch = skb_header_pointer(skb, offset, sizeof(_sch), &_sch)) && \ + sch->length; offset += (htons(sch->length) + 3) & ~3, count++) /* Some validity checks to make sure the chunks are fine */ static int do_basic_checks(struct nf_conn *conntrack, ^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [netfilter-core] Re: [lockup] 2.6.17-rc3: netfilter/sctp: lockup in sctp_new(), do_basic_checks() 2006-05-02 13:57 ` Patrick McHardy @ 2006-05-02 14:16 ` Ingo Molnar 2006-05-02 14:24 ` Ingo Molnar 2006-05-02 14:29 ` Patrick McHardy 0 siblings, 2 replies; 16+ messages in thread From: Ingo Molnar @ 2006-05-02 14:16 UTC (permalink / raw) To: Patrick McHardy Cc: linux-kernel, Andrew Morton, coreteam, David S. Miller, Herbert Xu * Patrick McHardy <kaber@trash.net> wrote: > I did a couple of minutes ago. Here it is again in case my last mail > won't show up. > - (sch = skb_header_pointer(skb, offset, sizeof(_sch), &_sch)); \ > - offset += (htons(sch->length) + 3) & ~3, count++) > + (sch = skb_header_pointer(skb, offset, sizeof(_sch), &_sch)) && \ > + sch->length; offset += (htons(sch->length) + 3) & ~3, count++) but this makes do_basic_checks() not fail, and the clearly bogus packet is passed further down. The reason i have put it inside the loop is to be able to return 1 for the early checks. How about the fix below? It should be cleaner and it will also return 1 if the initial offset is oversized. Ingo ---- From: Ingo Molnar <mingo@elte.hu> fix infinite loop in the SCTP-netfilter code: check SCTP chunk size to guarantee progress of for_each_sctp_chunk(). (all other uses of for_each_sctp_chunk() are preceded by do_basic_checks(), so this fix should be complete.) Signed-off-by: Ingo Molnar <mingo@elte.hu> --- net/ipv4/netfilter/ip_conntrack_proto_sctp.c | 16 +++++++++++++--- 1 files changed, 13 insertions(+), 3 deletions(-) Index: linux/net/ipv4/netfilter/ip_conntrack_proto_sctp.c =================================================================== --- linux.orig/net/ipv4/netfilter/ip_conntrack_proto_sctp.c +++ linux/net/ipv4/netfilter/ip_conntrack_proto_sctp.c @@ -224,6 +224,13 @@ static int do_basic_checks(struct ip_con DEBUGP(__FUNCTION__); DEBUGP("\n"); + /* + * Dont trust the initial offset: + */ + offset = skb->nh.iph->ihl * 4 + sizeof(sctp_sctphdr_t); + if (offset >= skb->len) + return 1; + flag = 0; for_each_sctp_chunk (skb, sch, _sch, offset, count) { @@ -235,12 +242,15 @@ static int do_basic_checks(struct ip_con flag = 1; } - /* Cookie Ack/Echo chunks not the first OR - Init / Init Ack / Shutdown compl chunks not the only chunks */ + /* + * Cookie Ack/Echo chunks not the first OR + * Init / Init Ack / Shutdown compl chunks not the only chunks + * OR zero-length. + */ if ((sch->type == SCTP_CID_COOKIE_ACK || sch->type == SCTP_CID_COOKIE_ECHO || flag) - && count !=0 ) { + && count !=0 || !sched->length) { DEBUGP("Basic checks failed\n"); return 1; } ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [netfilter-core] Re: [lockup] 2.6.17-rc3: netfilter/sctp: lockup in sctp_new(), do_basic_checks() 2006-05-02 14:16 ` Ingo Molnar @ 2006-05-02 14:24 ` Ingo Molnar 2006-05-02 14:29 ` Patrick McHardy 1 sibling, 0 replies; 16+ messages in thread From: Ingo Molnar @ 2006-05-02 14:24 UTC (permalink / raw) To: Patrick McHardy Cc: linux-kernel, Andrew Morton, coreteam, David S. Miller, Herbert Xu * Ingo Molnar <mingo@elte.hu> wrote: > but this makes do_basic_checks() not fail, and the clearly bogus > packet is passed further down. The reason i have put it inside the > loop is to be able to return 1 for the early checks. How about the fix > below? It should be cleaner and it will also return 1 if the initial > offset is oversized. that should be: ---- From: Ingo Molnar <mingo@elte.hu> fix infinite loop in the SCTP-netfilter code: check SCTP chunk size to guarantee progress of for_each_sctp_chunk(). (all other uses of for_each_sctp_chunk() are preceded by do_basic_checks(), so this fix should be complete.) Signed-off-by: Ingo Molnar <mingo@elte.hu> --- net/ipv4/netfilter/ip_conntrack_proto_sctp.c | 18 ++++++++++++++---- 1 files changed, 14 insertions(+), 4 deletions(-) Index: linux/net/ipv4/netfilter/ip_conntrack_proto_sctp.c =================================================================== --- linux.orig/net/ipv4/netfilter/ip_conntrack_proto_sctp.c +++ linux/net/ipv4/netfilter/ip_conntrack_proto_sctp.c @@ -224,6 +224,13 @@ static int do_basic_checks(struct ip_con DEBUGP(__FUNCTION__); DEBUGP("\n"); + /* + * Dont trust the initial offset: + */ + offset = skb->nh.iph->ihl * 4 + sizeof(sctp_sctphdr_t); + if (offset >= skb->len) + return 1; + flag = 0; for_each_sctp_chunk (skb, sch, _sch, offset, count) { @@ -235,12 +242,15 @@ static int do_basic_checks(struct ip_con flag = 1; } - /* Cookie Ack/Echo chunks not the first OR - Init / Init Ack / Shutdown compl chunks not the only chunks */ - if ((sch->type == SCTP_CID_COOKIE_ACK + /* + * Cookie Ack/Echo chunks not the first OR + * Init / Init Ack / Shutdown compl chunks not the only chunks + * OR zero-length. + */ + if (((sch->type == SCTP_CID_COOKIE_ACK || sch->type == SCTP_CID_COOKIE_ECHO || flag) - && count !=0 ) { + && count != 0) || !sch->length) { DEBUGP("Basic checks failed\n"); return 1; } ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [netfilter-core] Re: [lockup] 2.6.17-rc3: netfilter/sctp: lockup in sctp_new(), do_basic_checks() 2006-05-02 14:16 ` Ingo Molnar 2006-05-02 14:24 ` Ingo Molnar @ 2006-05-02 14:29 ` Patrick McHardy 2006-05-02 14:38 ` Ingo Molnar 1 sibling, 1 reply; 16+ messages in thread From: Patrick McHardy @ 2006-05-02 14:29 UTC (permalink / raw) To: Ingo Molnar Cc: linux-kernel, Andrew Morton, coreteam, David S. Miller, Herbert Xu [-- Attachment #1: Type: text/plain, Size: 1503 bytes --] Ingo Molnar wrote: > * Patrick McHardy <kaber@trash.net> wrote: > > >>I did a couple of minutes ago. Here it is again in case my last mail >>won't show up. > > >>- (sch = skb_header_pointer(skb, offset, sizeof(_sch), &_sch)); \ >>- offset += (htons(sch->length) + 3) & ~3, count++) >>+ (sch = skb_header_pointer(skb, offset, sizeof(_sch), &_sch)) && \ >>+ sch->length; offset += (htons(sch->length) + 3) & ~3, count++) > > > but this makes do_basic_checks() not fail, and the clearly bogus packet > is passed further down. The reason i have put it inside the loop is to > be able to return 1 for the early checks. How about the fix below? It > should be cleaner and it will also return 1 if the initial offset is > oversized. Right, that is better. > Index: linux/net/ipv4/netfilter/ip_conntrack_proto_sctp.c > =================================================================== > --- linux.orig/net/ipv4/netfilter/ip_conntrack_proto_sctp.c > +++ linux/net/ipv4/netfilter/ip_conntrack_proto_sctp.c > @@ -224,6 +224,13 @@ static int do_basic_checks(struct ip_con > DEBUGP(__FUNCTION__); > DEBUGP("\n"); > > + /* > + * Dont trust the initial offset: > + */ > + offset = skb->nh.iph->ihl * 4 + sizeof(sctp_sctphdr_t); > + if (offset >= skb->len) > + return 1; > + That part is unnecessary, the presence of one sctp_sctphdr_t has already been verified by skb_header_pointer() in sctp_new(). How about this patch (based on your patch, but typos fixed and also covers nf_conntrack)? [-- Attachment #2: x --] [-- Type: text/plain, Size: 2524 bytes --] [NETFILTER]: SCTP conntrack: fix infinite loop fix infinite loop in the SCTP-netfilter code: check SCTP chunk size to guarantee progress of for_each_sctp_chunk(). (all other uses of for_each_sctp_chunk() are preceded by do_basic_checks(), so this fix should be complete.) Based on patch from Ingo Molnar <mingo@elte.hu> Signed-off-by: Patrick McHardy <kaber@trash.net> --- commit c14803e9e8446122312523a6b6959e7312379b2e tree 651d4f6f1cd07703d3ec6b9367c441312e969e9e parent 462f3ddd384045c731b3268a1b9c91c834a5a68a author Patrick McHardy <kaber@trash.net> Tue, 02 May 2006 16:28:26 +0200 committer Patrick McHardy <kaber@trash.net> Tue, 02 May 2006 16:28:26 +0200 net/ipv4/netfilter/ip_conntrack_proto_sctp.c | 11 +++++++---- net/netfilter/nf_conntrack_proto_sctp.c | 11 +++++++---- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/net/ipv4/netfilter/ip_conntrack_proto_sctp.c b/net/ipv4/netfilter/ip_conntrack_proto_sctp.c index 5259abd..a563534 100644 --- a/net/ipv4/netfilter/ip_conntrack_proto_sctp.c +++ b/net/ipv4/netfilter/ip_conntrack_proto_sctp.c @@ -235,12 +235,15 @@ static int do_basic_checks(struct ip_con flag = 1; } - /* Cookie Ack/Echo chunks not the first OR - Init / Init Ack / Shutdown compl chunks not the only chunks */ - if ((sch->type == SCTP_CID_COOKIE_ACK + /* + * Cookie Ack/Echo chunks not the first OR + * Init / Init Ack / Shutdown compl chunks not the only chunks + * OR zero-length. + */ + if (((sch->type == SCTP_CID_COOKIE_ACK || sch->type == SCTP_CID_COOKIE_ECHO || flag) - && count !=0 ) { + && count !=0) || !sch->length) { DEBUGP("Basic checks failed\n"); return 1; } diff --git a/net/netfilter/nf_conntrack_proto_sctp.c b/net/netfilter/nf_conntrack_proto_sctp.c index 9cccc32..730f5d6 100644 --- a/net/netfilter/nf_conntrack_proto_sctp.c +++ b/net/netfilter/nf_conntrack_proto_sctp.c @@ -240,12 +240,15 @@ static int do_basic_checks(struct nf_con flag = 1; } - /* Cookie Ack/Echo chunks not the first OR - Init / Init Ack / Shutdown compl chunks not the only chunks */ - if ((sch->type == SCTP_CID_COOKIE_ACK + /* + * Cookie Ack/Echo chunks not the first OR + * Init / Init Ack / Shutdown compl chunks not the only chunks + * OR zero-length. + */ + if (((sch->type == SCTP_CID_COOKIE_ACK || sch->type == SCTP_CID_COOKIE_ECHO || flag) - && count !=0 ) { + && count !=0) || !sch->length) { DEBUGP("Basic checks failed\n"); return 1; } ^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [netfilter-core] Re: [lockup] 2.6.17-rc3: netfilter/sctp: lockup in sctp_new(), do_basic_checks() 2006-05-02 14:29 ` Patrick McHardy @ 2006-05-02 14:38 ` Ingo Molnar 2006-05-02 14:35 ` Patrick McHardy 2006-05-02 14:42 ` Ingo Molnar 0 siblings, 2 replies; 16+ messages in thread From: Ingo Molnar @ 2006-05-02 14:38 UTC (permalink / raw) To: Patrick McHardy Cc: linux-kernel, Andrew Morton, coreteam, David S. Miller, Herbert Xu * Patrick McHardy <kaber@trash.net> wrote: > > + /* > > + * Dont trust the initial offset: > > + */ > > + offset = skb->nh.iph->ihl * 4 + sizeof(sctp_sctphdr_t); > > + if (offset >= skb->len) > > + return 1; > > + > > That part is unnecessary, the presence of one sctp_sctphdr_t > has already been verified by skb_header_pointer() in sctp_new(). ok. > How about this patch (based on your patch, but typos fixed and also > covers nf_conntrack)? sure, fine with me! Ingo ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [netfilter-core] Re: [lockup] 2.6.17-rc3: netfilter/sctp: lockup in sctp_new(), do_basic_checks() 2006-05-02 14:38 ` Ingo Molnar @ 2006-05-02 14:35 ` Patrick McHardy 2006-05-02 14:42 ` Ingo Molnar 1 sibling, 0 replies; 16+ messages in thread From: Patrick McHardy @ 2006-05-02 14:35 UTC (permalink / raw) To: Ingo Molnar Cc: linux-kernel, Andrew Morton, coreteam, David S. Miller, Herbert Xu Ingo Molnar wrote: > * Patrick McHardy <kaber@trash.net> wrote: > >>How about this patch (based on your patch, but typos fixed and also >>covers nf_conntrack)? > > > sure, fine with me! OK, thanks. I'll pass it on to Dave soon. ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [netfilter-core] Re: [lockup] 2.6.17-rc3: netfilter/sctp: lockup in sctp_new(), do_basic_checks() 2006-05-02 14:38 ` Ingo Molnar 2006-05-02 14:35 ` Patrick McHardy @ 2006-05-02 14:42 ` Ingo Molnar 2006-05-02 14:40 ` Patrick McHardy 1 sibling, 1 reply; 16+ messages in thread From: Ingo Molnar @ 2006-05-02 14:42 UTC (permalink / raw) To: Patrick McHardy Cc: linux-kernel, Andrew Morton, coreteam, David S. Miller, Herbert Xu * Ingo Molnar <mingo@elte.hu> wrote: > > How about this patch (based on your patch, but typos fixed and also > > covers nf_conntrack)? > > sure, fine with me! find updated patch below - quilt complained about 3 cases of whitespace-at-end-of-line. (btw., this file at quite a distance from proper Documentation/CodingStyle.) Ingo Index: linux/net/ipv4/netfilter/ip_conntrack_proto_sctp.c =================================================================== --- linux.orig/net/ipv4/netfilter/ip_conntrack_proto_sctp.c +++ linux/net/ipv4/netfilter/ip_conntrack_proto_sctp.c @@ -235,12 +235,15 @@ static int do_basic_checks(struct ip_con flag = 1; } - /* Cookie Ack/Echo chunks not the first OR - Init / Init Ack / Shutdown compl chunks not the only chunks */ - if ((sch->type == SCTP_CID_COOKIE_ACK + /* + * Cookie Ack/Echo chunks not the first OR + * Init / Init Ack / Shutdown compl chunks not the only chunks + * OR zero-length. + */ + if (((sch->type == SCTP_CID_COOKIE_ACK || sch->type == SCTP_CID_COOKIE_ECHO || flag) - && count !=0 ) { + && count !=0) || !sch->length) { DEBUGP("Basic checks failed\n"); return 1; } Index: linux/net/netfilter/nf_conntrack_proto_sctp.c =================================================================== --- linux.orig/net/netfilter/nf_conntrack_proto_sctp.c +++ linux/net/netfilter/nf_conntrack_proto_sctp.c @@ -240,12 +240,15 @@ static int do_basic_checks(struct nf_con flag = 1; } - /* Cookie Ack/Echo chunks not the first OR - Init / Init Ack / Shutdown compl chunks not the only chunks */ - if ((sch->type == SCTP_CID_COOKIE_ACK + /* + * Cookie Ack/Echo chunks not the first OR + * Init / Init Ack / Shutdown compl chunks not the only chunks + * OR zero-length. + */ + if (((sch->type == SCTP_CID_COOKIE_ACK || sch->type == SCTP_CID_COOKIE_ECHO || flag) - && count !=0 ) { + && count !=0) || !sch->length) { DEBUGP("Basic checks failed\n"); return 1; } ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [netfilter-core] Re: [lockup] 2.6.17-rc3: netfilter/sctp: lockup in sctp_new(), do_basic_checks() 2006-05-02 14:42 ` Ingo Molnar @ 2006-05-02 14:40 ` Patrick McHardy 0 siblings, 0 replies; 16+ messages in thread From: Patrick McHardy @ 2006-05-02 14:40 UTC (permalink / raw) To: Ingo Molnar Cc: linux-kernel, Andrew Morton, coreteam, David S. Miller, Herbert Xu Ingo Molnar wrote: > * Ingo Molnar <mingo@elte.hu> wrote: > > >>>How about this patch (based on your patch, but typos fixed and also >>>covers nf_conntrack)? >> >>sure, fine with me! > > > find updated patch below - quilt complained about 3 cases of > whitespace-at-end-of-line. (btw., this file at quite a distance from > proper Documentation/CodingStyle.) My scripts take care of whitespace when exporting patches for pushing upstream. And yes, it really could use some cleanup - unfortunately its not even the worst one of the netfilter files. ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [netfilter-core] [lockup] 2.6.17-rc3: netfilter/sctp: lockup in sctp_new(), do_basic_checks() 2006-05-02 11:34 [lockup] 2.6.17-rc3: netfilter/sctp: lockup in sctp_new(), do_basic_checks() Ingo Molnar 2006-05-02 13:40 ` Ingo Molnar @ 2006-05-02 13:45 ` Patrick McHardy 2006-05-02 15:34 ` Marcel Holtmann 2 siblings, 0 replies; 16+ messages in thread From: Patrick McHardy @ 2006-05-02 13:45 UTC (permalink / raw) To: Ingo Molnar Cc: linux-kernel, Andrew Morton, coreteam, David S. Miller, Herbert Xu [-- Attachment #1: Type: text/plain, Size: 1601 bytes --] Ingo Molnar wrote: > running an "isic" stresstest on and against a testbox [which, amongst > other things, generates random incoming and outgoing packets] on > 2.6.17-rc3 (and 2.6.17-rc3-mm1) over gigabit results in a reproducible > lockup, after 5-10 minutes of runtime: > > BUG: soft lockup detected on CPU#0! > [<c0104e7f>] show_trace+0xd/0xf > [<c0104e96>] dump_stack+0x15/0x17 > [<c015ad02>] softlockup_tick+0xc5/0xd9 > [<c0134c02>] run_local_timers+0x22/0x24 > [<c0134fb7>] update_process_times+0x40/0x65 > [<c011aa56>] smp_apic_timer_interrupt+0x58/0x60 > [<c010492b>] apic_timer_interrupt+0x27/0x2c > [<c0f00df9>] sctp_new+0x8b/0x235 > [...] > > this is with FRAME_POINTERS enabled, so it's an exact stacktrace. > > the lockup is at: > > (gdb) list *0xc0f00df9 > 0xc0f00df9 is in sctp_new > (net/ipv4/netfilter/ip_conntrack_proto_sctp.c:444). > 439 > 440 sh = skb_header_pointer(skb, iph->ihl * 4, sizeof(_sctph), &_sctph); > 441 if (sh == NULL) > 442 return 0; > 443 > 444 if (do_basic_checks(conntrack, skb, map) != 0) > 445 return 0; > 446 > 447 /* If an OOTB packet has any of these chunks discard (Sec 8.4) */ > 448 if ((test_bit (SCTP_CID_ABORT, (void *)map)) > > most likely somewhere within do_basic_checks(). [whose stack entry is > obscured by the irq entry, so it's not in the stackdump.] I have SCTP > turned on: Yes, it seems like it doesn't make any forward progress in for_each_sctp_chunk() because the chunk length is zero. Can you try this patch please? [-- Attachment #2: x --] [-- Type: text/plain, Size: 2421 bytes --] [NETFILTER]: Fix endless loop in SCTP conntrack When a chunk length is zero, for_each_sctp_chunk() doesn't make any forward progress and loops forever. A chunk length of 0 is invalid, so just abort in that case. Reported by Ingo Molnar <mingo@elte.hu>. Signed-off-by: Patrick McHardy <kaber@trash.net> --- commit 32491b3d62bc8c3ff2400deebd46972ebc7332af tree 7249133ec32c18f4e6f989560e8d86b5e2e2cf0c parent 462f3ddd384045c731b3268a1b9c91c834a5a68a author Patrick McHardy <kaber@trash.net> Tue, 02 May 2006 15:44:30 +0200 committer Patrick McHardy <kaber@trash.net> Tue, 02 May 2006 15:44:30 +0200 net/ipv4/netfilter/ip_conntrack_proto_sctp.c | 4 ++-- net/netfilter/nf_conntrack_proto_sctp.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/net/ipv4/netfilter/ip_conntrack_proto_sctp.c b/net/ipv4/netfilter/ip_conntrack_proto_sctp.c index 5259abd..ebd4ecf 100644 --- a/net/ipv4/netfilter/ip_conntrack_proto_sctp.c +++ b/net/ipv4/netfilter/ip_conntrack_proto_sctp.c @@ -209,8 +209,8 @@ static int sctp_print_conntrack(struct s #define for_each_sctp_chunk(skb, sch, _sch, offset, count) \ for (offset = skb->nh.iph->ihl * 4 + sizeof(sctp_sctphdr_t), count = 0; \ offset < skb->len && \ - (sch = skb_header_pointer(skb, offset, sizeof(_sch), &_sch)); \ - offset += (htons(sch->length) + 3) & ~3, count++) + (sch = skb_header_pointer(skb, offset, sizeof(_sch), &_sch)) && \ + sch->length; offset += (htons(sch->length) + 3) & ~3, count++) /* Some validity checks to make sure the chunks are fine */ static int do_basic_checks(struct ip_conntrack *conntrack, diff --git a/net/netfilter/nf_conntrack_proto_sctp.c b/net/netfilter/nf_conntrack_proto_sctp.c index 9cccc32..2e34436 100644 --- a/net/netfilter/nf_conntrack_proto_sctp.c +++ b/net/netfilter/nf_conntrack_proto_sctp.c @@ -213,8 +213,8 @@ static int sctp_print_conntrack(struct s #define for_each_sctp_chunk(skb, sch, _sch, offset, dataoff, count) \ for (offset = dataoff + sizeof(sctp_sctphdr_t), count = 0; \ offset < skb->len && \ - (sch = skb_header_pointer(skb, offset, sizeof(_sch), &_sch)); \ - offset += (htons(sch->length) + 3) & ~3, count++) + (sch = skb_header_pointer(skb, offset, sizeof(_sch), &_sch)) && \ + sch->length; offset += (htons(sch->length) + 3) & ~3, count++) /* Some validity checks to make sure the chunks are fine */ static int do_basic_checks(struct nf_conn *conntrack, ^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [lockup] 2.6.17-rc3: netfilter/sctp: lockup in sctp_new(), do_basic_checks() 2006-05-02 11:34 [lockup] 2.6.17-rc3: netfilter/sctp: lockup in sctp_new(), do_basic_checks() Ingo Molnar 2006-05-02 13:40 ` Ingo Molnar 2006-05-02 13:45 ` [netfilter-core] " Patrick McHardy @ 2006-05-02 15:34 ` Marcel Holtmann 2006-05-02 15:55 ` [netfilter-core] " Patrick McHardy 2 siblings, 1 reply; 16+ messages in thread From: Marcel Holtmann @ 2006-05-02 15:34 UTC (permalink / raw) To: Ingo Molnar Cc: linux-kernel, Andrew Morton, David S. Miller, Herbert Xu, coreteam Hi Ingo, > running an "isic" stresstest on and against a testbox [which, amongst > other things, generates random incoming and outgoing packets] on > 2.6.17-rc3 (and 2.6.17-rc3-mm1) over gigabit results in a reproducible > lockup, after 5-10 minutes of runtime: does this lockup the local machine you run the stresstest on or the remote machine you run the test against? Regards Marcel ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [netfilter-core] Re: [lockup] 2.6.17-rc3: netfilter/sctp: lockup in sctp_new(), do_basic_checks() 2006-05-02 15:34 ` Marcel Holtmann @ 2006-05-02 15:55 ` Patrick McHardy 0 siblings, 0 replies; 16+ messages in thread From: Patrick McHardy @ 2006-05-02 15:55 UTC (permalink / raw) To: Marcel Holtmann Cc: Ingo Molnar, Andrew Morton, Herbert Xu, coreteam, linux-kernel, David S. Miller Marcel Holtmann wrote: > Hi Ingo, > > >>running an "isic" stresstest on and against a testbox [which, amongst >>other things, generates random incoming and outgoing packets] on >>2.6.17-rc3 (and 2.6.17-rc3-mm1) over gigabit results in a reproducible >>lockup, after 5-10 minutes of runtime: > > > does this lockup the local machine you run the stresstest on or the > remote machine you run the test against? It would lock up any machine with the SCTP conntrack module loaded. I'll prepare a patch for -stable as well. ^ permalink raw reply [flat|nested] 16+ messages in thread
end of thread, other threads:[~2006-05-02 15:55 UTC | newest] Thread overview: 16+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2006-05-02 11:34 [lockup] 2.6.17-rc3: netfilter/sctp: lockup in sctp_new(), do_basic_checks() Ingo Molnar 2006-05-02 13:40 ` Ingo Molnar 2006-05-02 13:45 ` Ingo Molnar 2006-05-02 13:54 ` [netfilter-core] " Patrick McHardy 2006-05-02 14:01 ` Ingo Molnar 2006-05-02 13:57 ` Patrick McHardy 2006-05-02 14:16 ` Ingo Molnar 2006-05-02 14:24 ` Ingo Molnar 2006-05-02 14:29 ` Patrick McHardy 2006-05-02 14:38 ` Ingo Molnar 2006-05-02 14:35 ` Patrick McHardy 2006-05-02 14:42 ` Ingo Molnar 2006-05-02 14:40 ` Patrick McHardy 2006-05-02 13:45 ` [netfilter-core] " Patrick McHardy 2006-05-02 15:34 ` Marcel Holtmann 2006-05-02 15:55 ` [netfilter-core] " Patrick McHardy
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox