From 4195f81453b9727f82bb8ceae03411b7fe52a994 Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Mon, 22 May 2006 16:53:22 -0700 Subject: [NET]: Fix "ntohl(ntohs" bugs Signed-off-by: Alexey Dobriyan Signed-off-by: David S. Miller --- net/ipv4/ipcomp.c | 2 +- net/ipv4/xfrm4_policy.c | 2 +- net/ipv6/ipcomp6.c | 2 +- net/xfrm/xfrm_input.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) (limited to 'net') diff --git a/net/ipv4/ipcomp.c b/net/ipv4/ipcomp.c index cd810f41af1a..95278b22b669 100644 --- a/net/ipv4/ipcomp.c +++ b/net/ipv4/ipcomp.c @@ -210,7 +210,7 @@ static void ipcomp4_err(struct sk_buff *skb, u32 info) skb->h.icmph->code != ICMP_FRAG_NEEDED) return; - spi = ntohl(ntohs(ipch->cpi)); + spi = htonl(ntohs(ipch->cpi)); x = xfrm_state_lookup((xfrm_address_t *)&iph->daddr, spi, IPPROTO_COMP, AF_INET); if (!x) diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c index f285bbf296e2..8604c747bca5 100644 --- a/net/ipv4/xfrm4_policy.c +++ b/net/ipv4/xfrm4_policy.c @@ -221,7 +221,7 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl) if (pskb_may_pull(skb, xprth + 4 - skb->data)) { u16 *ipcomp_hdr = (u16 *)xprth; - fl->fl_ipsec_spi = ntohl(ntohs(ipcomp_hdr[1])); + fl->fl_ipsec_spi = htonl(ntohs(ipcomp_hdr[1])); } break; default: diff --git a/net/ipv6/ipcomp6.c b/net/ipv6/ipcomp6.c index 05eb67def39f..48636436028a 100644 --- a/net/ipv6/ipcomp6.c +++ b/net/ipv6/ipcomp6.c @@ -208,7 +208,7 @@ static void ipcomp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, if (type != ICMPV6_DEST_UNREACH && type != ICMPV6_PKT_TOOBIG) return; - spi = ntohl(ntohs(ipcomph->cpi)); + spi = htonl(ntohs(ipcomph->cpi)); x = xfrm_state_lookup((xfrm_address_t *)&iph->daddr, spi, IPPROTO_COMP, AF_INET6); if (!x) return; diff --git a/net/xfrm/xfrm_input.c b/net/xfrm/xfrm_input.c index b54971059f16..891a6090cc09 100644 --- a/net/xfrm/xfrm_input.c +++ b/net/xfrm/xfrm_input.c @@ -62,7 +62,7 @@ int xfrm_parse_spi(struct sk_buff *skb, u8 nexthdr, u32 *spi, u32 *seq) case IPPROTO_COMP: if (!pskb_may_pull(skb, sizeof(struct ip_comp_hdr))) return -EINVAL; - *spi = ntohl(ntohs(*(u16*)(skb->h.raw + 2))); + *spi = htonl(ntohs(*(u16*)(skb->h.raw + 2))); *seq = 0; return 0; default: -- cgit v1.2.2 From 405a42c5c8bd5731087c0ff01310731a3c1c9c24 Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Mon, 22 May 2006 16:54:08 -0700 Subject: [IRDA]: fix 16/32 bit confusion Signed-off-by: Alexey Dobriyan Signed-off-by: David S. Miller --- net/irda/iriap.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'net') diff --git a/net/irda/iriap.c b/net/irda/iriap.c index 254f90746900..2d2e2b1919f4 100644 --- a/net/irda/iriap.c +++ b/net/irda/iriap.c @@ -544,7 +544,8 @@ static void iriap_getvaluebyclass_response(struct iriap_cb *self, { struct sk_buff *tx_skb; int n; - __u32 tmp_be32, tmp_be16; + __u32 tmp_be32; + __be16 tmp_be16; __u8 *fp; IRDA_DEBUG(4, "%s()\n", __FUNCTION__); -- cgit v1.2.2 From f41d5bb1d9f49b03af7126d07a511facbe283a92 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Mon, 22 May 2006 16:55:14 -0700 Subject: [NETFILTER]: SNMP NAT: fix memory corruption Fix memory corruption caused by snmp_trap_decode: - When snmp_trap_decode fails before the id and address are allocated, the pointers contain random memory, but are freed by the caller (snmp_parse_mangle). - When snmp_trap_decode fails after allocating just the ID, it tries to free both address and ID, but the address pointer still contains random memory. The caller frees both ID and random memory again. - When snmp_trap_decode fails after allocating both, it frees both, and the callers frees both again. The corruption can be triggered remotely when the ip_nat_snmp_basic module is loaded and traffic on port 161 or 162 is NATed. Found by multiple testcases of the trap-app and trap-enc groups of the PROTOS c06-snmpv1 testsuite. Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- net/ipv4/netfilter/ip_nat_snmp_basic.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) (limited to 'net') diff --git a/net/ipv4/netfilter/ip_nat_snmp_basic.c b/net/ipv4/netfilter/ip_nat_snmp_basic.c index c62253845538..688a2f29fadf 100644 --- a/net/ipv4/netfilter/ip_nat_snmp_basic.c +++ b/net/ipv4/netfilter/ip_nat_snmp_basic.c @@ -1003,12 +1003,12 @@ static unsigned char snmp_trap_decode(struct asn1_ctx *ctx, return 1; +err_addr_free: + kfree((unsigned long *)trap->ip_address); + err_id_free: kfree(trap->id); -err_addr_free: - kfree((unsigned long *)trap->ip_address); - return 0; } @@ -1126,11 +1126,10 @@ static int snmp_parse_mangle(unsigned char *msg, struct snmp_v1_trap trap; unsigned char ret = snmp_trap_decode(&ctx, &trap, map, check); - /* Discard trap allocations regardless */ - kfree(trap.id); - kfree((unsigned long *)trap.ip_address); - - if (!ret) + if (ret) { + kfree(trap.id); + kfree((unsigned long *)trap.ip_address); + } else return ret; } else { -- cgit v1.2.2 From f2d395865faa2a7cd4620b07178e58cbb160ba08 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Mon, 22 May 2006 22:35:25 -0700 Subject: [PATCH] knfsd: Fix two problems that can cause rmmod nfsd to die Both cause the 'entries' count in the export cache to be non-zero at module removal time, so unregistering that cache fails and results in an oops. 1/ exp_pseudoroot (used for NFSv4 only) leaks a reference to an export entry. 2/ sunrpc_cache_update doesn't increment the entries count when it adds an entry. Thanks to "david m. richter" for triggering the problem and finding one of the bugs. Cc: "david m. richter" Signed-off-by: Neil Brown Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- net/sunrpc/cache.c | 1 + 1 file changed, 1 insertion(+) (limited to 'net') diff --git a/net/sunrpc/cache.c b/net/sunrpc/cache.c index 3ac4193a78ed..7026b0866b7b 100644 --- a/net/sunrpc/cache.c +++ b/net/sunrpc/cache.c @@ -159,6 +159,7 @@ struct cache_head *sunrpc_cache_update(struct cache_detail *detail, detail->update(tmp, new); tmp->next = *head; *head = tmp; + detail->entries++; cache_get(tmp); is_new = cache_fresh_locked(tmp, new->expiry_time); cache_fresh_locked(old, 0); -- cgit v1.2.2 From 7185989db4d926dbef1a2f638c464f35599c83e0 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Tue, 23 May 2006 15:07:07 -0700 Subject: [NETFILTER]: H.323 helper: fix parser error propagation The condition "> H323_ERROR_STOP" can never be true since H323_ERROR_STOP is positive and is the highest possible return code, while real errors are negative, fix the checks. Also only abort on real errors in some spots that were just interpreting any return value != 0 as error. Fixes crashes caused by use of stale data after a parsing error occured: BUG: unable to handle kernel paging request at virtual address bfffffff printing eip: c01aa0f8 *pde = 1a801067 *pte = 00000000 Oops: 0000 [#1] PREEMPT Modules linked in: ip_nat_h323 ip_conntrack_h323 nfsd exportfs sch_sfq sch_red cls_fw sch_hfsc xt_length ipt_owner xt_MARK iptable_mangle nfs lockd sunrpc pppoe pppoxx CPU: 0 EIP: 0060:[] Not tainted VLI EFLAGS: 00210646 (2.6.17-rc4 #8) EIP is at memmove+0x19/0x22 eax: d77264e9 ebx: d77264e9 ecx: e88d9b17 edx: d77264e9 esi: bfffffff edi: bfffffff ebp: de6a7680 esp: c0349db8 ds: 007b es: 007b ss: 0068 Process asterisk (pid: 3765, threadinfo=c0349000 task=da068540) Stack: <0>00000006 c0349e5e d77264e3 e09a2b4e e09a38a0 d7726052 d7726124 00000491 00000006 00000006 00000006 00000491 de6a7680 d772601e d7726032 c0349f74 e09a2dc2 00000006 c0349e5e 00000006 00000000 d76dda28 00000491 c0349f74 Call Trace: [] mangle_contents+0x62/0xfe [ip_nat] [] ip_nat_mangle_tcp_packet+0xa1/0x191 [ip_nat] [] set_addr+0x74/0x14c [ip_nat_h323] [] process_setup+0x11b/0x29e [ip_conntrack_h323] [] process_setup+0x14c/0x29e [ip_conntrack_h323] [] process_q931+0x3c/0x142 [ip_conntrack_h323] [] q931_help+0xe0/0x144 [ip_conntrack_h323] ... Found by the PROTOS c07-h2250v4 testsuite. Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- net/ipv4/netfilter/ip_conntrack_helper_h323_asn1.c | 34 ++++++++++++---------- 1 file changed, 19 insertions(+), 15 deletions(-) (limited to 'net') diff --git a/net/ipv4/netfilter/ip_conntrack_helper_h323_asn1.c b/net/ipv4/netfilter/ip_conntrack_helper_h323_asn1.c index 355a53a5b6cd..5d04438dda4b 100644 --- a/net/ipv4/netfilter/ip_conntrack_helper_h323_asn1.c +++ b/net/ipv4/netfilter/ip_conntrack_helper_h323_asn1.c @@ -528,14 +528,15 @@ int decode_seq(bitstr_t * bs, field_t * f, char *base, int level) /* Decode */ if ((err = (Decoders[son->type]) (bs, son, base, - level + 1)) > - H323_ERROR_STOP) + level + 1)) < + H323_ERROR_NONE) return err; bs->cur = beg + len; bs->bit = 0; } else if ((err = (Decoders[son->type]) (bs, son, base, - level + 1))) + level + 1)) < + H323_ERROR_NONE) return err; } @@ -584,8 +585,8 @@ int decode_seq(bitstr_t * bs, field_t * f, char *base, int level) beg = bs->cur; if ((err = (Decoders[son->type]) (bs, son, base, - level + 1)) > - H323_ERROR_STOP) + level + 1)) < + H323_ERROR_NONE) return err; bs->cur = beg + len; @@ -660,18 +661,20 @@ int decode_seqof(bitstr_t * bs, field_t * f, char *base, int level) i < effective_count ? base : NULL, - level + 1)) > - H323_ERROR_STOP) + level + 1)) < + H323_ERROR_NONE) return err; bs->cur = beg + len; bs->bit = 0; } else - if ((err = (Decoders[son->type]) (bs, son, - i < effective_count ? - base : NULL, - level + 1))) - return err; + if ((err = (Decoders[son->type]) (bs, son, + i < + effective_count ? + base : NULL, + level + 1)) < + H323_ERROR_NONE) + return err; if (base) base += son->offset; @@ -735,13 +738,14 @@ int decode_choice(bitstr_t * bs, field_t * f, char *base, int level) } beg = bs->cur; - if ((err = (Decoders[son->type]) (bs, son, base, level + 1)) > - H323_ERROR_STOP) + if ((err = (Decoders[son->type]) (bs, son, base, level + 1)) < + H323_ERROR_NONE) return err; bs->cur = beg + len; bs->bit = 0; - } else if ((err = (Decoders[son->type]) (bs, son, base, level + 1))) + } else if ((err = (Decoders[son->type]) (bs, son, base, level + 1)) < + H323_ERROR_NONE) return err; return H323_ERROR_NONE; -- cgit v1.2.2 From 4d942d8b39bf7d43ce93d85964aeb63aeace0593 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Tue, 23 May 2006 15:07:46 -0700 Subject: [NETFILTER]: H.323 helper: fix sequence extension parsing When parsing unknown sequence extensions the "son"-pointer points behind the last known extension for this type, don't try to interpret it. Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- net/ipv4/netfilter/ip_conntrack_helper_h323_asn1.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'net') diff --git a/net/ipv4/netfilter/ip_conntrack_helper_h323_asn1.c b/net/ipv4/netfilter/ip_conntrack_helper_h323_asn1.c index 5d04438dda4b..26dfecadb335 100644 --- a/net/ipv4/netfilter/ip_conntrack_helper_h323_asn1.c +++ b/net/ipv4/netfilter/ip_conntrack_helper_h323_asn1.c @@ -555,7 +555,7 @@ int decode_seq(bitstr_t * bs, field_t * f, char *base, int level) /* Decode the extension components */ for (opt = 0; opt < bmp2_len; opt++, i++, son++) { - if (son->attr & STOP) { + if (i < f->ub && son->attr & STOP) { PRINT("%*.s%s\n", (level + 1) * TAB_SIZE, " ", son->name); return H323_ERROR_STOP; -- cgit v1.2.2 From 4a063739138e2c4e933188d641f1593e01ce8285 Mon Sep 17 00:00:00 2001 From: Chris Wright Date: Tue, 23 May 2006 15:08:13 -0700 Subject: [NETFILTER]: SNMP NAT: fix memleak in snmp_object_decode If kmalloc fails, error path leaks data allocated from asn1_oid_decode(). Signed-off-by: Chris Wright Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- net/ipv4/netfilter/ip_nat_snmp_basic.c | 1 + 1 file changed, 1 insertion(+) (limited to 'net') diff --git a/net/ipv4/netfilter/ip_nat_snmp_basic.c b/net/ipv4/netfilter/ip_nat_snmp_basic.c index 688a2f29fadf..c33244263b90 100644 --- a/net/ipv4/netfilter/ip_nat_snmp_basic.c +++ b/net/ipv4/netfilter/ip_nat_snmp_basic.c @@ -768,6 +768,7 @@ static unsigned char snmp_object_decode(struct asn1_ctx *ctx, len *= sizeof(unsigned long); *obj = kmalloc(sizeof(struct snmp_object) + len, GFP_ATOMIC); if (*obj == NULL) { + kfree(lp); kfree(id); if (net_ratelimit()) printk("OOM in bsalg (%d)\n", __LINE__); -- cgit v1.2.2 From 387e2b0439026aa738a9edca15a57e5c0bcb4dfc Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Tue, 23 May 2006 15:20:25 -0700 Subject: [BRIDGE]: need to ref count the LLC sap Bridge will OOPS on removal if other application has the SAP open. The bridge SAP might be shared with other usages, so need to do reference counting on module removal rather than explicit close/delete. Since packet might arrive after or during removal, need to clear the receive function handle, so LLC only hands it to user (if any). Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- net/bridge/br.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'net') diff --git a/net/bridge/br.c b/net/bridge/br.c index 22d806cf40ca..12da21afb9ca 100644 --- a/net/bridge/br.c +++ b/net/bridge/br.c @@ -55,7 +55,7 @@ static int __init br_init(void) static void __exit br_deinit(void) { - llc_sap_close(br_stp_sap); + rcu_assign_pointer(br_stp_sap->rcv_func, NULL); #ifdef CONFIG_BRIDGE_NETFILTER br_netfilter_fini(); @@ -67,6 +67,7 @@ static void __exit br_deinit(void) synchronize_net(); + llc_sap_put(br_stp_sap); br_fdb_get_hook = NULL; br_fdb_put_hook = NULL; -- cgit v1.2.2