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 07ba1dd136b..23b99ae2cc3 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 32891ebc9e6..4fdf4849baf 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 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 b984db77125..8f3e92d20df 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 88cfa6aacfc..5fd1e5363c1 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 2c01378d359..452e9d32668 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 d3de579e09d..e5a34c17d92 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 6bc2f06de05..f71ef9b5f42 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 439164c7a62..123c95913f2 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 8cae6e063bb..1c4c70e25cd 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 4b7be4bb4d0..6f19c4a4956 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 21f19cc719f..075da4f287b 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 4fdf4849baf..b3a70eb6d42 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 ac193ce7024..5434472420f 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 069b85ca51c..3b9ad7f6eb5 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 d0a1cee7ee5..a5e5726ec0c 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 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 170d625fad6..0a72eab1462 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 3b9ad7f6eb5..153d6619993 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 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 b8eab0dbc3d..62c3f31cdb9 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 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 62c3f31cdb9..27b844a67ec 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 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 27b844a67ec..1b940512d87 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 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 1b940512d87..b669db56469 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 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 b669db56469..d0af8bc3eee 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 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 d0af8bc3eee..91a0972ec11 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 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 0b2d265e7da..1c405dd30c6 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 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 51ca4383c38..606971645b3 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 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 e9986acdd0a..8d65d6478dc 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 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 4dee462f00d..287099f7f04 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 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 6656bb497c7..6d235b3013d 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