From 39dad26c37fdb1382e4173172a2704fa278f7fd6 Mon Sep 17 00:00:00 2001 From: Gerrit Renker Date: Sun, 19 Aug 2007 17:12:50 -0700 Subject: [PATCH 1/6] [DCCP]: Allocation in atomic context This fixes the following bug reported in syslog: [ 4039.051658] BUG: sleeping function called from invalid context at /usr/src/davem-2.6/mm/slab.c:3032 [ 4039.051668] in_atomic():1, irqs_disabled():0 [ 4039.051670] INFO: lockdep is turned off. [ 4039.051674] [] show_trace_log_lvl+0x1a/0x30 [ 4039.051687] [] show_trace+0x12/0x14 [ 4039.051691] [] dump_stack+0x16/0x18 [ 4039.051695] [] __might_sleep+0xaf/0xbe [ 4039.051700] [] __kmalloc+0xb1/0xd0 [ 4039.051706] [] ccid2_hc_tx_alloc_seq+0x35/0xc3 [dccp_ccid2] [ 4039.051717] [] ccid2_hc_tx_packet_sent+0x27f/0x2d9 [dccp_ccid2] [ 4039.051723] [] dccp_write_xmit+0x1eb/0x338 [dccp] [ 4039.051741] [] dccp_sendmsg+0x113/0x18f [dccp] [ 4039.051750] [] inet_sendmsg+0x2e/0x4c [ 4039.051758] [] sock_aio_write+0xd5/0x107 [ 4039.051766] [] do_sync_write+0xcd/0x11c [ 4039.051772] [] vfs_write+0x118/0x11f [ 4039.051840] [] sys_write+0x3d/0x64 [ 4039.051845] [] syscall_call+0x7/0xb [ 4039.051848] ======================= The problem was that GFP_KERNEL was used; fixed by using gfp_any(). Signed-off-by: Gerrit Renker Signed-off-by: Arnaldo Carvalho de Melo Signed-off-by: David S. Miller --- net/dccp/ccids/ccid2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/dccp/ccids/ccid2.c b/net/dccp/ccids/ccid2.c index 248d20f4c7c4..d29b88fe723c 100644 --- a/net/dccp/ccids/ccid2.c +++ b/net/dccp/ccids/ccid2.c @@ -298,7 +298,7 @@ static void ccid2_hc_tx_packet_sent(struct sock *sk, int more, unsigned int len) int rc; ccid2_pr_debug("allocating more space in history\n"); - rc = ccid2_hc_tx_alloc_seq(hctx, CCID2_SEQBUF_LEN, GFP_KERNEL); + rc = ccid2_hc_tx_alloc_seq(hctx, CCID2_SEQBUF_LEN, gfp_any()); BUG_ON(rc); /* XXX what do we do? */ next = hctx->ccid2hctx_seqh->ccid2s_next; From d92a7db710c32db826a00ba9bc7a22e741d5041e Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Tue, 21 Aug 2007 00:06:37 -0700 Subject: [PATCH 2/6] [SNAP]: Check packet length before reading The snap_rcv code reads 5 bytes so we should make sure that we have 5 bytes in the head before proceeding. Based on diagnosis and fix by Evgeniy Polyakov, reported by Alan J. Wylie. Patch also kills the skb->sk assignment before kfree_skb since it's redundant. Signed-off-by: Herbert Xu Signed-off-by: David S. Miller --- net/802/psnap.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/net/802/psnap.c b/net/802/psnap.c index 04ee43e7538f..31128cb92a23 100644 --- a/net/802/psnap.c +++ b/net/802/psnap.c @@ -55,6 +55,9 @@ static int snap_rcv(struct sk_buff *skb, struct net_device *dev, .type = __constant_htons(ETH_P_SNAP), }; + if (unlikely(!pskb_may_pull(skb, 5))) + goto drop; + rcu_read_lock(); proto = find_snap_client(skb_transport_header(skb)); if (proto) { @@ -62,14 +65,18 @@ static int snap_rcv(struct sk_buff *skb, struct net_device *dev, skb->transport_header += 5; skb_pull_rcsum(skb, 5); rc = proto->rcvfunc(skb, dev, &snap_packet_type, orig_dev); - } else { - skb->sk = NULL; - kfree_skb(skb); - rc = 1; } - rcu_read_unlock(); + + if (unlikely(!proto)) + goto drop; + +out: return rc; + +drop: + kfree_skb(skb); + goto out; } /* From 8984e41d18a545320201950b8721e7ce3ac2a5e7 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Tue, 21 Aug 2007 20:59:08 -0700 Subject: [PATCH 3/6] [IPV6]: Fix kernel panic while send SCTP data with IP fragments If ICMP6 message with "Packet Too Big" is received after send SCTP DATA, kernel panic will occur when SCTP DATA is send again. This is because of a bad dest address when call to skb_copy_bits(). The messages sequence is like this: Endpoint A Endpoint B <------- SCTP DATA (size=1432) ICMP6 message -------> (Packet Too Big pmtu=1280) <------- Resend SCTP DATA (size=1432) ------------kernel panic--------------- printing eip: c05be62a *pde = 00000000 Oops: 0002 [#1] SMP Modules linked in: scomm l2cap bluetooth ipv6 dm_mirror dm_mod video output sbs battery lp floppy sg i2c_piix4 i2c_core pcnet32 mii button ac parport_pc parport ide_cd cdrom serio_raw mptspi mptscsih mptbase scsi_transport_spi sd_mod scsi_mod ext3 jbd ehci_hcd ohci_hcd uhci_hcd CPU: 0 EIP: 0060:[] Not tainted VLI EFLAGS: 00010282 (2.6.23-rc2 #1) EIP is at skb_copy_bits+0x4f/0x1ef eax: 000004d0 ebx: ce12a980 ecx: 00000134 edx: cfd5a880 esi: c8246858 edi: 00000000 ebp: c0759b14 esp: c0759adc ds: 007b es: 007b fs: 00d8 gs: 0000 ss: 0068 Process swapper (pid: 0, ti=c0759000 task=c06d0340 task.ti=c0713000) Stack: c0759b88 c0405867 ce12a980 c8bff838 c789c084 00000000 00000028 cfd5a880 d09f1890 000005dc 0000007b ce12a980 cfd5a880 c8bff838 c0759b88 d09bc521 000004d0 fffff96c 00000200 00000100 c0759b50 cfd5a880 00000246 c0759bd4 Call Trace: [] show_trace_log_lvl+0x1a/0x2f [] show_stack_log_lvl+0x9b/0xa3 [] show_registers+0x1b8/0x289 [] die+0x113/0x246 [] do_page_fault+0x4ad/0x57e [] error_code+0x72/0x78 [] ip6_output+0x8e5/0xab2 [ipv6] [] ip6_xmit+0x2ea/0x3a3 [ipv6] [] sctp_v6_xmit+0x248/0x253 [sctp] [] sctp_packet_transmit+0x53f/0x5ae [sctp] [] sctp_outq_flush+0x555/0x587 [sctp] [] sctp_retransmit+0xf8/0x10f [sctp] [] sctp_icmp_frag_needed+0x57/0x5b [sctp] [] sctp_v6_err+0xcd/0x148 [sctp] [] icmpv6_notify+0xe6/0x167 [ipv6] [] icmpv6_rcv+0x7d7/0x849 [ipv6] [] ip6_input+0x1dc/0x310 [ipv6] [] ipv6_rcv+0x294/0x2df [ipv6] [] netif_receive_skb+0x2d2/0x335 [] process_backlog+0x7f/0xd0 [] net_rx_action+0x96/0x17e [] __do_softirq+0x64/0xcd [] do_softirq+0x5c/0xac ======================= Code: 00 00 29 ca 89 d0 2b 45 e0 89 55 ec 85 c0 7e 35 39 45 08 8b 55 e4 0f 4e 45 08 8b 75 e0 8b 7d dc 89 c1 c1 e9 02 03 b2 a0 00 00 00 a5 89 c1 83 e1 03 74 02 f3 a4 29 45 08 0f 84 7b 01 00 00 01 EIP: [] skb_copy_bits+0x4f/0x1ef SS:ESP 0068:c0759adc Kernel panic - not syncing: Fatal exception in interrupt Arnaldo says: ==================== Thanks! I'm to blame for this one, problem was introduced in: b0e380b1d8a8e0aca215df97702f99815f05c094 @@ -761,7 +762,7 @@ slow_path: /* * Copy a block of the IP datagram. */ - if (skb_copy_bits(skb, ptr, frag->h.raw, len)) + if (skb_copy_bits(skb, ptr, skb_transport_header(skb), len)) BUG(); left -= len; ==================== Signed-off-by: Wei Yongjun Acked-by: YOSHIFUJI Hideaki Signed-off-by: Arnaldo Carvalho de Melo Signed-off-by: David S. Miller --- net/ipv6/ip6_output.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 50d86e94d9ed..5dead399fe64 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c @@ -794,7 +794,7 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) /* * Copy a block of the IP datagram. */ - if (skb_copy_bits(skb, ptr, skb_transport_header(skb), len)) + if (skb_copy_bits(skb, ptr, skb_transport_header(frag), len)) BUG(); left -= len; From 2c20d72aaadd41fdf0a3b6cb8514c2f7b7d263e4 Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Tue, 21 Aug 2007 00:10:50 -0700 Subject: [PATCH 4/6] [IRDA]: Avoid a label defined but not used warning in irda_init() Easily avoidable compiler warnings bug me. Building irmod without CONFIG_SYSCTL currently results in : net/irda/irmod.c:132: warning: label 'out_err_2' defined but not used But that can easily be avoided by simply moving the label inside the existing "#ifdef CONFIG_SYSCTL" one line above it. This patch moves the label and buys us one less warning with no ill effects. Signed-off-by: Jesper Juhl Signed-off-by: David S. Miller --- net/irda/irmod.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/irda/irmod.c b/net/irda/irmod.c index 1900937b3328..8ba703da2797 100644 --- a/net/irda/irmod.c +++ b/net/irda/irmod.c @@ -128,8 +128,8 @@ static int __init irda_init(void) out_err_3: #ifdef CONFIG_SYSCTL irda_sysctl_unregister(); -#endif out_err_2: +#endif #ifdef CONFIG_PROC_FS irda_proc_unregister(); #endif From 06c7af563d925d04961ce70cd9154fad8e2750c8 Mon Sep 17 00:00:00 2001 From: Konstantin Sharlaimov Date: Tue, 21 Aug 2007 00:12:44 -0700 Subject: [PATCH 5/6] [PPP]: Fix output buffer size in ppp_decompress_frame(). This patch addresses the issue with "osize too small" errors in mppe encryption. The patch fixes the issue with wrong output buffer size being passed to ppp decompression routine. -------------------- As pointed out by Suresh Mahalingam, the issue addressed by ppp-fix-osize-too-small-errors-when-decoding patch is not fully resolved yet. The size of allocated output buffer is correct, however it size passed to ppp->rcomp->decompress in ppp_generic.c if wrong. The patch fixes that. -------------------- Signed-off-by: Konstantin Sharlaimov Signed-off-by: David S. Miller --- drivers/net/ppp_generic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c index ef3325b69233..9293c82ef2af 100644 --- a/drivers/net/ppp_generic.c +++ b/drivers/net/ppp_generic.c @@ -1726,7 +1726,7 @@ ppp_decompress_frame(struct ppp *ppp, struct sk_buff *skb) } /* the decompressor still expects the A/C bytes in the hdr */ len = ppp->rcomp->decompress(ppp->rc_state, skb->data - 2, - skb->len + 2, ns->data, ppp->mru + PPP_HDRLEN); + skb->len + 2, ns->data, obuff_size); if (len < 0) { /* Pass the compressed frame to pppd as an error indication. */ From 22117ea4fef4ea1c7d97c4d68c02c96c268a511b Mon Sep 17 00:00:00 2001 From: Andy Whitcroft Date: Tue, 21 Aug 2007 21:23:39 -0700 Subject: [PATCH 6/6] [IRDA] irda_nl_get_mode: always results in failure It seems an extraneous trailing ';' has slipped in to the error handling for a name registration failure causing the error path to trigger unconditionally. Signed-off-by: Andy Whitcroft Signed-off-by: Andrew Morton Signed-off-by: Samuel Ortiz Signed-off-by: David S. Miller --- net/irda/irnetlink.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/irda/irnetlink.c b/net/irda/irnetlink.c index 694ea4d92fa8..1e429c929739 100644 --- a/net/irda/irnetlink.c +++ b/net/irda/irnetlink.c @@ -106,7 +106,7 @@ static int irda_nl_get_mode(struct sk_buff *skb, struct genl_info *info) } if(nla_put_string(msg, IRDA_NL_ATTR_IFNAME, - dev->name)); + dev->name)) goto err_out; if(nla_put_u32(msg, IRDA_NL_ATTR_MODE, irlap->mode))