From ec68e97dedacc1c7fb20a4b23b7fa76bee56b5ff Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Sun, 4 Mar 2007 15:57:01 -0800 Subject: [NETFILTER]: conntrack: fix {nf,ip}_ct_iterate_cleanup endless loops Fix {nf,ip}_ct_iterate_cleanup unconfirmed list handling: - unconfirmed entries can not be killed manually, they are removed on confirmation or final destruction of the conntrack entry, which means we might iterate forever without making forward progress. This can happen in combination with the conntrack event cache, which holds a reference to the conntrack entry, which is only released when the packet makes it all the way through the stack or a different packet is handled. - taking references to an unconfirmed entry and using it outside the locked section doesn't work, the list entries are not refcounted and another CPU might already be waiting to destroy the entry What the code really wants to do is make sure the references of the hash table to the selected conntrack entries are released, so they will be destroyed once all references from skbs and the event cache are dropped. Since unconfirmed entries haven't even entered the hash yet, simply mark them as dying and skip confirmation based on that. Reported and tested by Chuck Ebbert Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- net/ipv4/netfilter/ip_conntrack_core.c | 2 +- net/netfilter/nf_conntrack_core.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'net') diff --git a/net/ipv4/netfilter/ip_conntrack_core.c b/net/ipv4/netfilter/ip_conntrack_core.c index 07ba1dd..23b99ae 100644 --- a/net/ipv4/netfilter/ip_conntrack_core.c +++ b/net/ipv4/netfilter/ip_conntrack_core.c @@ -1254,7 +1254,7 @@ get_next_corpse(int (*iter)(struct ip_conntrack *i, void *data), list_for_each_entry(h, &unconfirmed, list) { ct = tuplehash_to_ctrack(h); if (iter(ct, data)) - goto found; + set_bit(IPS_DYING_BIT, &ct->status); } write_unlock_bh(&ip_conntrack_lock); return NULL; diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c index 32891eb..4fdf484 100644 --- a/net/netfilter/nf_conntrack_core.c +++ b/net/netfilter/nf_conntrack_core.c @@ -1070,7 +1070,7 @@ get_next_corpse(int (*iter)(struct nf_conn *i, void *data), list_for_each_entry(h, &unconfirmed, list) { ct = nf_ct_tuplehash_to_ctrack(h); if (iter(ct, data)) - goto found; + set_bit(IPS_DYING_BIT, &ct->status); } write_unlock_bh(&nf_conntrack_lock); return NULL; -- cgit v1.1 From e281db5cdfc3ab077ab3e459d098cb4fde0bc57a Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Sun, 4 Mar 2007 15:57:25 -0800 Subject: [NETFILTER]: nf_conntrack/nf_nat: fix incorrect config ifdefs The nf_conntrack_netlink config option is named CONFIG_NF_CT_NETLINK, but multiple files use CONFIG_IP_NF_CONNTRACK_NETLINK or CONFIG_NF_CONNTRACK_NETLINK for ifdefs. Fix this and reformat all CONFIG_NF_CT_NETLINK ifdefs to only use a line. Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c | 6 ++---- net/ipv4/netfilter/nf_conntrack_proto_icmp.c | 6 ++---- net/ipv4/netfilter/nf_nat_core.c | 3 +-- net/ipv4/netfilter/nf_nat_proto_gre.c | 3 +-- net/ipv4/netfilter/nf_nat_proto_icmp.c | 3 +-- net/ipv4/netfilter/nf_nat_proto_tcp.c | 3 +-- net/ipv4/netfilter/nf_nat_proto_udp.c | 3 +-- net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c | 6 ++---- net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c | 6 ++---- net/netfilter/nf_conntrack_core.c | 3 +-- net/netfilter/nf_conntrack_proto_gre.c | 3 +-- net/netfilter/nf_conntrack_proto_tcp.c | 9 +++------ net/netfilter/nf_conntrack_proto_udp.c | 6 ++---- 13 files changed, 20 insertions(+), 40 deletions(-) (limited to 'net') diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c index b984db7..8f3e92d 100644 --- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c +++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c @@ -379,8 +379,7 @@ getorigdst(struct sock *sk, int optval, void __user *user, int *len) return -ENOENT; } -#if defined(CONFIG_NF_CT_NETLINK) || \ - defined(CONFIG_NF_CT_NETLINK_MODULE) +#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) #include #include @@ -435,8 +434,7 @@ struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv4 = { .print_conntrack = ipv4_print_conntrack, .prepare = ipv4_prepare, .get_features = ipv4_get_features, -#if defined(CONFIG_NF_CT_NETLINK) || \ - defined(CONFIG_NF_CT_NETLINK_MODULE) +#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) .tuple_to_nfattr = ipv4_tuple_to_nfattr, .nfattr_to_tuple = ipv4_nfattr_to_tuple, #endif diff --git a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c index 88cfa6a..5fd1e53 100644 --- a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c +++ b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c @@ -268,8 +268,7 @@ icmp_error(struct sk_buff *skb, unsigned int dataoff, return icmp_error_message(skb, ctinfo, hooknum); } -#if defined(CONFIG_NF_CT_NETLINK) || \ - defined(CONFIG_NF_CT_NETLINK_MODULE) +#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) #include #include @@ -368,8 +367,7 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_icmp = .error = icmp_error, .destroy = NULL, .me = NULL, -#if defined(CONFIG_NF_CT_NETLINK) || \ - defined(CONFIG_NF_CT_NETLINK_MODULE) +#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) .tuple_to_nfattr = icmp_tuple_to_nfattr, .nfattr_to_tuple = icmp_nfattr_to_tuple, #endif diff --git a/net/ipv4/netfilter/nf_nat_core.c b/net/ipv4/netfilter/nf_nat_core.c index 2c01378..452e9d3 100644 --- a/net/ipv4/netfilter/nf_nat_core.c +++ b/net/ipv4/netfilter/nf_nat_core.c @@ -546,8 +546,7 @@ void nf_nat_protocol_unregister(struct nf_nat_protocol *proto) } EXPORT_SYMBOL(nf_nat_protocol_unregister); -#if defined(CONFIG_IP_NF_CONNTRACK_NETLINK) || \ - defined(CONFIG_IP_NF_CONNTRACK_NETLINK_MODULE) +#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) int nf_nat_port_range_to_nfattr(struct sk_buff *skb, const struct nf_nat_range *range) diff --git a/net/ipv4/netfilter/nf_nat_proto_gre.c b/net/ipv4/netfilter/nf_nat_proto_gre.c index d3de579..e5a34c1 100644 --- a/net/ipv4/netfilter/nf_nat_proto_gre.c +++ b/net/ipv4/netfilter/nf_nat_proto_gre.c @@ -152,8 +152,7 @@ static struct nf_nat_protocol gre __read_mostly = { .manip_pkt = gre_manip_pkt, .in_range = gre_in_range, .unique_tuple = gre_unique_tuple, -#if defined(CONFIG_IP_NF_CONNTRACK_NETLINK) || \ - defined(CONFIG_IP_NF_CONNTRACK_NETLINK_MODULE) +#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) .range_to_nfattr = nf_nat_port_range_to_nfattr, .nfattr_to_range = nf_nat_port_nfattr_to_range, #endif diff --git a/net/ipv4/netfilter/nf_nat_proto_icmp.c b/net/ipv4/netfilter/nf_nat_proto_icmp.c index 6bc2f06..f71ef9b 100644 --- a/net/ipv4/netfilter/nf_nat_proto_icmp.c +++ b/net/ipv4/netfilter/nf_nat_proto_icmp.c @@ -78,8 +78,7 @@ struct nf_nat_protocol nf_nat_protocol_icmp = { .manip_pkt = icmp_manip_pkt, .in_range = icmp_in_range, .unique_tuple = icmp_unique_tuple, -#if defined(CONFIG_IP_NF_CONNTRACK_NETLINK) || \ - defined(CONFIG_IP_NF_CONNTRACK_NETLINK_MODULE) +#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) .range_to_nfattr = nf_nat_port_range_to_nfattr, .nfattr_to_range = nf_nat_port_nfattr_to_range, #endif diff --git a/net/ipv4/netfilter/nf_nat_proto_tcp.c b/net/ipv4/netfilter/nf_nat_proto_tcp.c index 439164c..123c959 100644 --- a/net/ipv4/netfilter/nf_nat_proto_tcp.c +++ b/net/ipv4/netfilter/nf_nat_proto_tcp.c @@ -144,8 +144,7 @@ struct nf_nat_protocol nf_nat_protocol_tcp = { .manip_pkt = tcp_manip_pkt, .in_range = tcp_in_range, .unique_tuple = tcp_unique_tuple, -#if defined(CONFIG_IP_NF_CONNTRACK_NETLINK) || \ - defined(CONFIG_IP_NF_CONNTRACK_NETLINK_MODULE) +#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) .range_to_nfattr = nf_nat_port_range_to_nfattr, .nfattr_to_range = nf_nat_port_nfattr_to_range, #endif diff --git a/net/ipv4/netfilter/nf_nat_proto_udp.c b/net/ipv4/netfilter/nf_nat_proto_udp.c index 8cae6e0..1c4c70e 100644 --- a/net/ipv4/netfilter/nf_nat_proto_udp.c +++ b/net/ipv4/netfilter/nf_nat_proto_udp.c @@ -134,8 +134,7 @@ struct nf_nat_protocol nf_nat_protocol_udp = { .manip_pkt = udp_manip_pkt, .in_range = udp_in_range, .unique_tuple = udp_unique_tuple, -#if defined(CONFIG_IP_NF_CONNTRACK_NETLINK) || \ - defined(CONFIG_IP_NF_CONNTRACK_NETLINK_MODULE) +#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) .range_to_nfattr = nf_nat_port_range_to_nfattr, .nfattr_to_range = nf_nat_port_nfattr_to_range, #endif diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c index 4b7be4b..6f19c4a 100644 --- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c +++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c @@ -353,8 +353,7 @@ static ctl_table nf_ct_ipv6_sysctl_table[] = { }; #endif -#if defined(CONFIG_NF_CT_NETLINK) || \ - defined(CONFIG_NF_CT_NETLINK_MODULE) +#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) #include #include @@ -403,8 +402,7 @@ struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv6 = { .print_tuple = ipv6_print_tuple, .print_conntrack = ipv6_print_conntrack, .prepare = ipv6_prepare, -#if defined(CONFIG_NF_CT_NETLINK) || \ - defined(CONFIG_NF_CT_NETLINK_MODULE) +#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) .tuple_to_nfattr = ipv6_tuple_to_nfattr, .nfattr_to_tuple = ipv6_nfattr_to_tuple, #endif diff --git a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c index 21f19cc..075da4f 100644 --- a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c +++ b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c @@ -244,8 +244,7 @@ icmpv6_error(struct sk_buff *skb, unsigned int dataoff, return icmpv6_error_message(skb, dataoff, ctinfo, hooknum); } -#if defined(CONFIG_NF_CT_NETLINK) || \ - defined(CONFIG_NF_CT_NETLINK_MODULE) +#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) #include #include @@ -327,8 +326,7 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_icmpv6 = .packet = icmpv6_packet, .new = icmpv6_new, .error = icmpv6_error, -#if defined(CONFIG_NF_CT_NETLINK) || \ - defined(CONFIG_NF_CT_NETLINK_MODULE) +#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) .tuple_to_nfattr = icmpv6_tuple_to_nfattr, .nfattr_to_tuple = icmpv6_nfattr_to_tuple, #endif diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c index 4fdf484..b3a70eb 100644 --- a/net/netfilter/nf_conntrack_core.c +++ b/net/netfilter/nf_conntrack_core.c @@ -976,8 +976,7 @@ void __nf_ct_refresh_acct(struct nf_conn *ct, } EXPORT_SYMBOL_GPL(__nf_ct_refresh_acct); -#if defined(CONFIG_NF_CT_NETLINK) || \ - defined(CONFIG_NF_CT_NETLINK_MODULE) +#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) #include #include diff --git a/net/netfilter/nf_conntrack_proto_gre.c b/net/netfilter/nf_conntrack_proto_gre.c index ac193ce..5434472 100644 --- a/net/netfilter/nf_conntrack_proto_gre.c +++ b/net/netfilter/nf_conntrack_proto_gre.c @@ -281,8 +281,7 @@ static struct nf_conntrack_l4proto nf_conntrack_l4proto_gre4 = { .new = gre_new, .destroy = gre_destroy, .me = THIS_MODULE, -#if defined(CONFIG_NF_CONNTRACK_NETLINK) || \ - defined(CONFIG_NF_CONNTRACK_NETLINK_MODULE) +#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) .tuple_to_nfattr = nf_ct_port_tuple_to_nfattr, .nfattr_to_tuple = nf_ct_port_nfattr_to_tuple, #endif diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c index 069b85c..3b9ad7f 100644 --- a/net/netfilter/nf_conntrack_proto_tcp.c +++ b/net/netfilter/nf_conntrack_proto_tcp.c @@ -1099,8 +1099,7 @@ static int tcp_new(struct nf_conn *conntrack, return 1; } -#if defined(CONFIG_NF_CT_NETLINK) || \ - defined(CONFIG_NF_CT_NETLINK_MODULE) +#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) #include #include @@ -1378,8 +1377,7 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_tcp4 = .packet = tcp_packet, .new = tcp_new, .error = tcp_error, -#if defined(CONFIG_NF_CT_NETLINK) || \ - defined(CONFIG_NF_CT_NETLINK_MODULE) +#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) .to_nfattr = tcp_to_nfattr, .from_nfattr = nfattr_to_tcp, .tuple_to_nfattr = nf_ct_port_tuple_to_nfattr, @@ -1408,8 +1406,7 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_tcp6 = .packet = tcp_packet, .new = tcp_new, .error = tcp_error, -#if defined(CONFIG_NF_CT_NETLINK) || \ - defined(CONFIG_NF_CT_NETLINK_MODULE) +#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) .to_nfattr = tcp_to_nfattr, .from_nfattr = nfattr_to_tcp, .tuple_to_nfattr = nf_ct_port_tuple_to_nfattr, diff --git a/net/netfilter/nf_conntrack_proto_udp.c b/net/netfilter/nf_conntrack_proto_udp.c index d0a1cee..a5e5726 100644 --- a/net/netfilter/nf_conntrack_proto_udp.c +++ b/net/netfilter/nf_conntrack_proto_udp.c @@ -208,8 +208,7 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_udp4 = .packet = udp_packet, .new = udp_new, .error = udp_error, -#if defined(CONFIG_NF_CT_NETLINK) || \ - defined(CONFIG_NF_CT_NETLINK_MODULE) +#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) .tuple_to_nfattr = nf_ct_port_tuple_to_nfattr, .nfattr_to_tuple = nf_ct_port_nfattr_to_tuple, #endif @@ -236,8 +235,7 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_udp6 = .packet = udp_packet, .new = udp_new, .error = udp_error, -#if defined(CONFIG_NF_CT_NETLINK) || \ - defined(CONFIG_NF_CT_NETLINK_MODULE) +#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) .tuple_to_nfattr = nf_ct_port_tuple_to_nfattr, .nfattr_to_tuple = nf_ct_port_nfattr_to_tuple, #endif -- cgit v1.1 From d3ab4298aa136d07219664d563d8decf0e75693f Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Sun, 4 Mar 2007 15:57:46 -0800 Subject: [NETFILTER]: tcp conntrack: accept SYN|URG as valid Some stacks apparently send packets with SYN|URG set. Linux accepts these packets, so TCP conntrack should to. Pointed out by Martijn Posthuma . Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- net/ipv4/netfilter/ip_conntrack_proto_tcp.c | 4 +++- net/netfilter/nf_conntrack_proto_tcp.c | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) (limited to 'net') diff --git a/net/ipv4/netfilter/ip_conntrack_proto_tcp.c b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c index 170d625..0a72eab 100644 --- a/net/ipv4/netfilter/ip_conntrack_proto_tcp.c +++ b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c @@ -812,8 +812,10 @@ void ip_conntrack_tcp_update(struct sk_buff *skb, static const u8 tcp_valid_flags[(TH_FIN|TH_SYN|TH_RST|TH_PUSH|TH_ACK|TH_URG) + 1] = { [TH_SYN] = 1, - [TH_SYN|TH_ACK] = 1, [TH_SYN|TH_PUSH] = 1, + [TH_SYN|TH_URG] = 1, + [TH_SYN|TH_PUSH|TH_URG] = 1, + [TH_SYN|TH_ACK] = 1, [TH_SYN|TH_ACK|TH_PUSH] = 1, [TH_RST] = 1, [TH_RST|TH_ACK] = 1, diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c index 3b9ad7f..153d661 100644 --- a/net/netfilter/nf_conntrack_proto_tcp.c +++ b/net/netfilter/nf_conntrack_proto_tcp.c @@ -769,8 +769,10 @@ EXPORT_SYMBOL_GPL(nf_conntrack_tcp_update); static u8 tcp_valid_flags[(TH_FIN|TH_SYN|TH_RST|TH_PUSH|TH_ACK|TH_URG) + 1] = { [TH_SYN] = 1, - [TH_SYN|TH_ACK] = 1, [TH_SYN|TH_PUSH] = 1, + [TH_SYN|TH_URG] = 1, + [TH_SYN|TH_PUSH|TH_URG] = 1, + [TH_SYN|TH_ACK] = 1, [TH_SYN|TH_ACK|TH_PUSH] = 1, [TH_RST] = 1, [TH_RST|TH_ACK] = 1, -- cgit v1.1 From ed32abeaf3a3da79b63af6a75f0bd0aa7e7eed9e Mon Sep 17 00:00:00 2001 From: Michal Miroslaw Date: Sun, 4 Mar 2007 15:58:15 -0800 Subject: [NETFILTER]: nfnetlink_log: fix reference leak Stop reference leaking in nfulnl_log_packet(). If we start a timer we are already taking another reference. Signed-off-by: Michal Miroslaw Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- net/netfilter/nfnetlink_log.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'net') diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c index b8eab0d..62c3f31 100644 --- a/net/netfilter/nfnetlink_log.c +++ b/net/netfilter/nfnetlink_log.c @@ -711,15 +711,16 @@ nfulnl_log_packet(unsigned int pf, inst->timer.expires = jiffies + (inst->flushtimeout*HZ/100); add_timer(&inst->timer); } - spin_unlock_bh(&inst->lock); +unlock_and_release: + spin_unlock_bh(&inst->lock); + instance_put(inst); return; alloc_failure: - spin_unlock_bh(&inst->lock); - instance_put(inst); UDEBUG("error allocating skb\n"); /* FIXME: statistics */ + goto unlock_and_release; } static int -- cgit v1.1 From 05f7b7b369e039458a77768619dde123d868c78d Mon Sep 17 00:00:00 2001 From: Michal Miroslaw Date: Sun, 4 Mar 2007 15:58:40 -0800 Subject: [NETFILTER]: nfnetlink_log: fix use after free Paranoia: instance_put() might have freed the inst pointer when we spin_unlock_bh(). Signed-off-by: Michal Miroslaw Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- net/netfilter/nfnetlink_log.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'net') diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c index 62c3f31..27b844a 100644 --- a/net/netfilter/nfnetlink_log.c +++ b/net/netfilter/nfnetlink_log.c @@ -393,8 +393,8 @@ static void nfulnl_timer(unsigned long data) spin_lock_bh(&inst->lock); __nfulnl_send(inst); - instance_put(inst); spin_unlock_bh(&inst->lock); + instance_put(inst); } /* This is an inline function, we don't really care about a long -- cgit v1.1 From a497097d35d37b47e885cf15bcaea01f279fe5e6 Mon Sep 17 00:00:00 2001 From: Michal Miroslaw Date: Sun, 4 Mar 2007 15:59:01 -0800 Subject: [NETFILTER]: nfnetlink_log: fix NULL pointer dereference Fix the nasty NULL dereference on multiple packets per netlink message. BUG: unable to handle kernel NULL pointer dereference at virtual address 00000004 printing eip: f8a4b3bf *pde = 00000000 Oops: 0002 [#1] SMP Modules linked in: nfnetlink_log ipt_ttl ipt_REDIRECT xt_tcpudp iptable_nat nf_nat nf_conntrack_ipv4 xt_state ipt_ipp2p xt_NFLOG xt_hashlimit ip6_tables iptable_filter xt_multiport xt_mark ipt_set iptable_raw xt_MARK iptable_mangle ip_tables cls_fw cls_u32 sch_esfq sch_htb ip_set_ipmap ip_set ipt_ULOG x_tables dm_snapshot dm_mirror loop e1000 parport_pc parport e100 floppy ide_cd cdrom CPU: 0 EIP: 0060:[] Not tainted VLI EFLAGS: 00010206 (2.6.20 #5) EIP is at __nfulnl_send+0x24/0x51 [nfnetlink_log] eax: 00000000 ebx: f2b5cbc0 ecx: c03f5f54 edx: c03f4000 esi: f2b5cbc8 edi: c03f5f54 ebp: f8a4b3ec esp: c03f5f30 ds: 007b es: 007b ss: 0068 Process swapper (pid: 0, ti=c03f4000 task=c03bece0 task.ti=c03f4000) Stack: f2b5cbc0 f8a4b401 00000100 c0444080 c012af49 00000000 f6f19100 f6f19000 c1707800 c03f5f54 c03f5f54 00000123 00000021 c03e8d08 c0426380 00000009 c0126932 00000000 00000046 c03e9980 c03e6000 0047b007 c01269bd 00000000 Call Trace: [] nfulnl_timer+0x15/0x25 [nfnetlink_log] [] run_timer_softirq+0x10a/0x164 [] __do_softirq+0x60/0xba [] do_softirq+0x31/0x35 [] do_IRQ+0x62/0x74 [] common_interrupt+0x23/0x28 [] default_idle+0x0/0x3f [] default_idle+0x2d/0x3f [] cpu_idle+0xa0/0xb9 [] start_kernel+0x1a8/0x1ac [] unknown_bootoption+0x0/0x181 ======================= Code: 5e 5f 5b 5e 5f 5d c3 53 89 c3 8d 40 1c 83 7b 1c 00 74 05 e8 2c ee 6d c7 83 7b 14 00 75 04 31 c0 eb 34 83 7b 10 01 76 09 8b 43 18 <66> c7 40 04 03 00 8b 53 34 8b 43 14 b9 40 00 00 00 e8 08 9a 84 EIP: [] __nfulnl_send+0x24/0x51 [nfnetlink_log] SS:ESP 0068:c03f5f30 <0>Kernel panic - not syncing: Fatal exception in interrupt <0>Rebooting in 5 seconds.. Panic no more! Signed-off-by: Micha Mirosaw Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- net/netfilter/nfnetlink_log.c | 1 + 1 file changed, 1 insertion(+) (limited to 'net') diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c index 27b844a..1b94051 100644 --- a/net/netfilter/nfnetlink_log.c +++ b/net/netfilter/nfnetlink_log.c @@ -560,6 +560,7 @@ __build_packet_message(struct nfulnl_instance *inst, } nlh->nlmsg_len = inst->skb->tail - old_tail; + inst->lastnlh = nlh; return 0; nlmsg_failure: -- cgit v1.1 From dd16704eba171b32ef0cded3a4f562b33b911066 Mon Sep 17 00:00:00 2001 From: Michal Miroslaw Date: Sun, 4 Mar 2007 15:59:20 -0800 Subject: [NETFILTER]: nfnetlink_log: fix possible NULL pointer dereference Eliminate possible NULL pointer dereference in nfulnl_recv_config(). Signed-off-by: Michal Miroslaw Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- net/netfilter/nfnetlink_log.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'net') diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c index 1b94051..b669db5 100644 --- a/net/netfilter/nfnetlink_log.c +++ b/net/netfilter/nfnetlink_log.c @@ -858,6 +858,9 @@ nfulnl_recv_config(struct sock *ctnl, struct sk_buff *skb, ret = -EINVAL; break; } + + if (!inst) + goto out; } else { if (!inst) { UDEBUG("no config command, and no instance for " @@ -911,6 +914,7 @@ nfulnl_recv_config(struct sock *ctnl, struct sk_buff *skb, out_put: instance_put(inst); +out: return ret; } -- cgit v1.1 From 7d90e86d31e8beeb66d6754aece890ac4a579887 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Sun, 4 Mar 2007 15:59:45 -0800 Subject: [NETFILTER]: nfnetlink_log: fix module reference counting Count module references correctly: after instance_destroy() there might be timer pending and holding a reference for this netlink instance. Based on patch by Michal Miroslaw Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- net/netfilter/nfnetlink_log.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'net') diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c index b669db5..d0af8bc 100644 --- a/net/netfilter/nfnetlink_log.c +++ b/net/netfilter/nfnetlink_log.c @@ -133,6 +133,7 @@ instance_put(struct nfulnl_instance *inst) if (inst && atomic_dec_and_test(&inst->use)) { UDEBUG("kfree(inst=%p)\n", inst); kfree(inst); + module_put(THIS_MODULE); } } @@ -228,8 +229,6 @@ _instance_destroy2(struct nfulnl_instance *inst, int lock) /* and finally put the refcount */ instance_put(inst); - - module_put(THIS_MODULE); } static inline void -- cgit v1.1 From b4d6202b3652f5dbce358b99dee7d7c80b567529 Mon Sep 17 00:00:00 2001 From: Michal Miroslaw Date: Sun, 4 Mar 2007 16:00:04 -0800 Subject: [NETFILTER]: nfnetlink_log: fix reference counting Fix reference counting (memory leak) problem in __nfulnl_send() and callers related to packet queueing. Signed-off-by: Michal Miroslaw Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- net/netfilter/nfnetlink_log.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'net') diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c index d0af8bc..91a0972 100644 --- a/net/netfilter/nfnetlink_log.c +++ b/net/netfilter/nfnetlink_log.c @@ -218,6 +218,9 @@ _instance_destroy2(struct nfulnl_instance *inst, int lock) spin_lock_bh(&inst->lock); if (inst->skb) { + /* timer "holds" one reference (we have one more) */ + if (del_timer(&inst->timer)) + instance_put(inst); if (inst->qlen) __nfulnl_send(inst); if (inst->skb) { @@ -362,9 +365,6 @@ __nfulnl_send(struct nfulnl_instance *inst) { int status; - if (timer_pending(&inst->timer)) - del_timer(&inst->timer); - if (!inst->skb) return 0; @@ -689,6 +689,9 @@ nfulnl_log_packet(unsigned int pf, * enough room in the skb left. flush to userspace. */ UDEBUG("flushing old skb\n"); + /* timer "holds" one reference (we have another one) */ + if (del_timer(&inst->timer)) + instance_put(inst); __nfulnl_send(inst); if (!(inst->skb = nfulnl_alloc_skb(nlbufsiz, size))) { -- cgit v1.1 From bc5f77434721a84705601e4d448d331c73900759 Mon Sep 17 00:00:00 2001 From: Yasuyuki Kozakai Date: Sun, 4 Mar 2007 16:00:32 -0800 Subject: [NETFILTER]: ip6_route_me_harder should take into account mark Signed-off-by: Yasuyuki Kozakai Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- net/ipv6/netfilter.c | 1 + 1 file changed, 1 insertion(+) (limited to 'net') diff --git a/net/ipv6/netfilter.c b/net/ipv6/netfilter.c index 0b2d265..1c405dd 100644 --- a/net/ipv6/netfilter.c +++ b/net/ipv6/netfilter.c @@ -15,6 +15,7 @@ int ip6_route_me_harder(struct sk_buff *skb) struct dst_entry *dst; struct flowi fl = { .oif = skb->sk ? skb->sk->sk_bound_dev_if : 0, + .mark = skb->mark, .nl_u = { .ip6_u = { .daddr = iph->daddr, -- cgit v1.1 From 64a146513f8f12ba204b7bf5cb7e9505594ead42 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 6 Mar 2007 11:21:05 -0800 Subject: [NET]: Revert incorrect accept queue backlog changes. This reverts two changes: 8488df894d05d6fa41c2bd298c335f944bb0e401 248f06726e866942b3d8ca8f411f9067713b7ff8 A backlog value of N really does mean allow "N + 1" connections to queue to a listening socket. This allows one to specify "0" as the backlog and still get 1 connection. Noticed by Gerrit Renker and Rick Jones. Signed-off-by: David S. Miller --- net/unix/af_unix.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'net') diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 51ca438..6069716 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -934,7 +934,7 @@ static long unix_wait_for_peer(struct sock *other, long timeo) sched = !sock_flag(other, SOCK_DEAD) && !(other->sk_shutdown & RCV_SHUTDOWN) && - (skb_queue_len(&other->sk_receive_queue) >= + (skb_queue_len(&other->sk_receive_queue) > other->sk_max_ack_backlog); unix_state_runlock(other); @@ -1008,7 +1008,7 @@ restart: if (other->sk_state != TCP_LISTEN) goto out_unlock; - if (skb_queue_len(&other->sk_receive_queue) >= + if (skb_queue_len(&other->sk_receive_queue) > other->sk_max_ack_backlog) { err = -EAGAIN; if (!timeo) @@ -1381,7 +1381,7 @@ restart: } if (unix_peer(other) != sk && - (skb_queue_len(&other->sk_receive_queue) >= + (skb_queue_len(&other->sk_receive_queue) > other->sk_max_ack_backlog)) { if (!timeo) { err = -EAGAIN; -- cgit v1.1 From 1e51f9513e6b021abcaefd7c76f9b5d682f83232 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 6 Mar 2007 13:44:06 -0800 Subject: [NET]: Fix compat_sock_common_getsockopt typo. This patch fixes a typo in compat_sock_common_getsockopt. Signed-off-by: Johannes Berg Acked-by: James Morris Signed-off-by: David S. Miller --- net/core/sock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'net') diff --git a/net/core/sock.c b/net/core/sock.c index e9986ac..8d65d64 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -1597,7 +1597,7 @@ int compat_sock_common_getsockopt(struct socket *sock, int level, int optname, { struct sock *sk = sock->sk; - if (sk->sk_prot->compat_setsockopt != NULL) + if (sk->sk_prot->compat_getsockopt != NULL) return sk->sk_prot->compat_getsockopt(sk, level, optname, optval, optlen); return sk->sk_prot->getsockopt(sk, level, optname, optval, optlen); -- cgit v1.1 From 4d46861be6196d0f1614724590968d8da26af82a Mon Sep 17 00:00:00 2001 From: Gerrit Renker Date: Tue, 6 Mar 2007 14:24:18 -0800 Subject: [DCCP]: Correctly split CCID half connections This fixes a bug caused by a previous patch, which causes DCCP servers in LISTEN state to not receive packets. This patch changes the logic so that * servers in either LISTEN or OPEN state get the RX half connection packets * clients in OPEN state get the TX half connection packets Signed-off-by: Gerrit Renker Signed-off-by: Arnaldo Carvalho de Melo Signed-off-by: David S. Miller --- net/dccp/input.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'net') diff --git a/net/dccp/input.c b/net/dccp/input.c index 4dee462..287099f 100644 --- a/net/dccp/input.c +++ b/net/dccp/input.c @@ -256,10 +256,10 @@ int dccp_rcv_established(struct sock *sk, struct sk_buff *skb, * (only one is active at a time); when moving to bidirectional * service, this needs to be revised. */ - if (dccp_sk(sk)->dccps_role == DCCP_ROLE_SERVER) - ccid_hc_rx_packet_recv(dp->dccps_hc_rx_ccid, sk, skb); - else + if (dccp_sk(sk)->dccps_role == DCCP_ROLE_CLIENT) ccid_hc_tx_packet_recv(dp->dccps_hc_tx_ccid, sk, skb); + else /* listening or connected server */ + ccid_hc_rx_packet_recv(dp->dccps_hc_rx_ccid, sk, skb); return __dccp_rcv_established(sk, skb, dh, len); discard: @@ -495,10 +495,10 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb, goto discard; /* XXX see the comments in dccp_rcv_established about this */ - if (dccp_sk(sk)->dccps_role == DCCP_ROLE_SERVER) - ccid_hc_rx_packet_recv(dp->dccps_hc_rx_ccid, sk, skb); - else + if (dccp_sk(sk)->dccps_role == DCCP_ROLE_CLIENT) ccid_hc_tx_packet_recv(dp->dccps_hc_tx_ccid, sk, skb); + else + ccid_hc_rx_packet_recv(dp->dccps_hc_rx_ccid, sk, skb); } /* -- cgit v1.1 From 99c72ce091ec85868a0847e598eb7562dc0d8205 Mon Sep 17 00:00:00 2001 From: Gerrit Renker Date: Tue, 6 Mar 2007 14:24:44 -0800 Subject: [DCCP]: Set RTO for newly created child socket This mirrors a recent change in tcp_open_req_child, whereby the icsk_rto of the newly created child socket was not set (but rather on the parent socket). Same fix for DCCP. Signed-off-by: Gerrit Renker Signed-off-by: Arnaldo Carvalho de Melo Signed-off-by: David S. Miller --- net/dccp/minisocks.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'net') diff --git a/net/dccp/minisocks.c b/net/dccp/minisocks.c index 6656bb4..6d235b3 100644 --- a/net/dccp/minisocks.c +++ b/net/dccp/minisocks.c @@ -103,7 +103,7 @@ struct sock *dccp_create_openreq_child(struct sock *sk, if (newsk != NULL) { const struct dccp_request_sock *dreq = dccp_rsk(req); - struct inet_connection_sock *newicsk = inet_csk(sk); + struct inet_connection_sock *newicsk = inet_csk(newsk); struct dccp_sock *newdp = dccp_sk(newsk); struct dccp_minisock *newdmsk = dccp_msk(newsk); -- cgit v1.1