From be8d0d7903af85d396449b34366e7f5b0c9cc58b Mon Sep 17 00:00:00 2001 From: Roel Kluin <12o3l@tiscali.nl> Date: Tue, 29 Apr 2008 03:15:10 -0700 Subject: netfilter: xt_TCPOPTSTRIP: signed tcphoff for ipv6_skip_exthdr() retval if tcphoff remains unsigned, a negative ipv6_skip_exthdr() return value will go unnoticed, Signed-off-by: Roel Kluin <12o3l@tiscali.nl> Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- net/netfilter/xt_TCPOPTSTRIP.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'net/netfilter') diff --git a/net/netfilter/xt_TCPOPTSTRIP.c b/net/netfilter/xt_TCPOPTSTRIP.c index 3b2aa56833b..9685b6fcbc8 100644 --- a/net/netfilter/xt_TCPOPTSTRIP.c +++ b/net/netfilter/xt_TCPOPTSTRIP.c @@ -90,7 +90,7 @@ tcpoptstrip_tg6(struct sk_buff *skb, const struct net_device *in, const struct xt_target *target, const void *targinfo) { struct ipv6hdr *ipv6h = ipv6_hdr(skb); - unsigned int tcphoff; + int tcphoff; u_int8_t nexthdr; nexthdr = ipv6h->nexthdr; -- cgit v1.2.3 From 0e93bb9459f56b50a2f71f2c230f4ad00ec40a73 Mon Sep 17 00:00:00 2001 From: Pavel Emelyanov Date: Tue, 29 Apr 2008 03:15:35 -0700 Subject: netfilter: x_tables: fix net namespace leak when reading /proc/net/xxx_tables_names The seq_open_net() call should be accompanied with seq_release_net() one. Signed-off-by: Pavel Emelyanov Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- net/netfilter/x_tables.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'net/netfilter') diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c index f52f7f810ac..11b22abc2b7 100644 --- a/net/netfilter/x_tables.c +++ b/net/netfilter/x_tables.c @@ -787,7 +787,7 @@ static const struct file_operations xt_table_ops = { .open = xt_table_open, .read = seq_read, .llseek = seq_lseek, - .release = seq_release, + .release = seq_release_net, }; static void *xt_match_seq_start(struct seq_file *seq, loff_t *pos) -- cgit v1.2.3 From 9a732ed6d0e126d4c8a818f42a13f3df11755bee Mon Sep 17 00:00:00 2001 From: Arnaud Ebalard Date: Tue, 29 Apr 2008 03:16:34 -0700 Subject: netfilter: {nfnetlink,ip,ip6}_queue: fix skb_over_panic when enlarging packets While reinjecting *bigger* modified versions of IPv6 packets using libnetfilter_queue, things work fine on a 2.6.24 kernel (2.6.22 too) but I get the following on recents kernels (2.6.25, trace below is against today's net-2.6 git tree): skb_over_panic: text:c04fddb0 len:696 put:632 head:f7592c00 data:f7592c00 tail:0xf7592eb8 end:0xf7592e80 dev:eth0 ------------[ cut here ]------------ invalid opcode: 0000 [#1] PREEMPT Process sendd (pid: 3657, ti=f6014000 task=f77c31d0 task.ti=f6014000) Stack: c071e638 c04fddb0 000002b8 00000278 f7592c00 f7592c00 f7592eb8 f7592e80 f763c000 f6bc5200 f7592c40 f6015c34 c04cdbfc f6bc5200 00000278 f6015c60 c04fddb0 00000020 f72a10c0 f751b420 00000001 0000000a 000002b8 c065582c Call Trace: [] ? nfqnl_recv_verdict+0x1c0/0x2e0 [] ? skb_put+0x3c/0x40 [] ? nfqnl_recv_verdict+0x1c0/0x2e0 [] ? nfnetlink_rcv_msg+0xf5/0x160 [] ? nfnetlink_rcv_msg+0x1e/0x160 [] ? nfnetlink_rcv_msg+0x0/0x160 [] ? netlink_rcv_skb+0x77/0xa0 [] ? nfnetlink_rcv+0x1c/0x30 [] ? netlink_unicast+0x243/0x2b0 [] ? memcpy_fromiovec+0x4a/0x70 [] ? netlink_sendmsg+0x1c6/0x270 [] ? sock_sendmsg+0xc4/0xf0 [] ? set_next_entity+0x1d/0x50 [] ? autoremove_wake_function+0x0/0x40 [] ? __wake_up_common+0x3e/0x70 [] ? n_tty_receive_buf+0x34f/0x1280 [] ? __wake_up+0x68/0x70 [] ? copy_from_user+0x37/0x70 [] ? verify_iovec+0x2c/0x90 [] ? sys_sendmsg+0x10a/0x230 [] ? __dequeue_entity+0x2a/0xa0 [] ? set_next_entity+0x1d/0x50 [] ? pty_write+0x47/0x60 [] ? tty_default_put_char+0x1b/0x20 [] ? __wake_up+0x49/0x70 [] ? tty_ldisc_deref+0x39/0x90 [] ? tty_write+0x1a0/0x1b0 [] ? sys_socketcall+0x7f/0x260 [] ? sysenter_past_esp+0x6a/0x91 [] ? snd_intel8x0m_probe+0x270/0x6e0 ======================= Code: 00 00 89 5c 24 14 8b 98 9c 00 00 00 89 54 24 0c 89 5c 24 10 8b 40 50 89 4c 24 04 c7 04 24 38 e6 71 c0 89 44 24 08 e8 c4 46 c5 ff <0f> 0b eb fe 55 89 e5 56 89 d6 53 89 c3 83 ec 0c 8b 40 50 39 d0 EIP: [] skb_over_panic+0x5c/0x60 SS:ESP 0068:f6015bf8 Looking at the code, I ended up in nfq_mangle() function (called by nfqnl_recv_verdict()) which performs a call to skb_copy_expand() due to the increased size of data passed to the function. AFAICT, it should ask for 'diff' instead of 'diff - skb_tailroom(e->skb)'. Because the resulting sk_buff has not enough space to support the skb_put(skb, diff) call a few lines later, this results in the call to skb_over_panic(). The patch below asks for allocation of a copy with enough space for mangled packet and the same amount of headroom as old sk_buff. While looking at how the regression appeared (e2b58a67), I noticed the same pattern in ipq_mangle_ipv6() and ipq_mangle_ipv4(). The patch corrects those locations too. Tested with bigger reinjected IPv6 packets (nfqnl_mangle() path), things are ok (2.6.25 and today's net-2.6 git tree). Signed-off-by: Arnaud Ebalard Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- net/ipv4/netfilter/ip_queue.c | 5 ++--- net/ipv6/netfilter/ip6_queue.c | 5 ++--- net/netfilter/nfnetlink_queue.c | 5 ++--- 3 files changed, 6 insertions(+), 9 deletions(-) (limited to 'net/netfilter') diff --git a/net/ipv4/netfilter/ip_queue.c b/net/ipv4/netfilter/ip_queue.c index 719be29f750..26a37cedcf2 100644 --- a/net/ipv4/netfilter/ip_queue.c +++ b/net/ipv4/netfilter/ip_queue.c @@ -296,9 +296,8 @@ ipq_mangle_ipv4(ipq_verdict_msg_t *v, struct nf_queue_entry *e) if (v->data_len > 0xFFFF) return -EINVAL; if (diff > skb_tailroom(e->skb)) { - nskb = skb_copy_expand(e->skb, 0, - diff - skb_tailroom(e->skb), - GFP_ATOMIC); + nskb = skb_copy_expand(e->skb, skb_headroom(e->skb), + diff, GFP_ATOMIC); if (!nskb) { printk(KERN_WARNING "ip_queue: error " "in mangle, dropping packet\n"); diff --git a/net/ipv6/netfilter/ip6_queue.c b/net/ipv6/netfilter/ip6_queue.c index 92a36c9e540..2eff3ae8977 100644 --- a/net/ipv6/netfilter/ip6_queue.c +++ b/net/ipv6/netfilter/ip6_queue.c @@ -298,9 +298,8 @@ ipq_mangle_ipv6(ipq_verdict_msg_t *v, struct nf_queue_entry *e) if (v->data_len > 0xFFFF) return -EINVAL; if (diff > skb_tailroom(e->skb)) { - nskb = skb_copy_expand(e->skb, 0, - diff - skb_tailroom(e->skb), - GFP_ATOMIC); + nskb = skb_copy_expand(e->skb, skb_headroom(e->skb), + diff, GFP_ATOMIC); if (!nskb) { printk(KERN_WARNING "ip6_queue: OOM " "in mangle, dropping packet\n"); diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c index 2c9fe5c1289..3447025ce06 100644 --- a/net/netfilter/nfnetlink_queue.c +++ b/net/netfilter/nfnetlink_queue.c @@ -454,9 +454,8 @@ nfqnl_mangle(void *data, int data_len, struct nf_queue_entry *e) if (data_len > 0xFFFF) return -EINVAL; if (diff > skb_tailroom(e->skb)) { - nskb = skb_copy_expand(e->skb, 0, - diff - skb_tailroom(e->skb), - GFP_ATOMIC); + nskb = skb_copy_expand(e->skb, skb_headroom(e->skb), + diff, GFP_ATOMIC); if (!nskb) { printk(KERN_WARNING "nf_queue: OOM " "in mangle, dropping packet\n"); -- cgit v1.2.3 From 443a70d50bdc212e1292778e264ce3d0a85b896f Mon Sep 17 00:00:00 2001 From: Philip Craig Date: Tue, 29 Apr 2008 03:35:10 -0700 Subject: netfilter: nf_conntrack: padding breaks conntrack hash on ARM commit 0794935e "[NETFILTER]: nf_conntrack: optimize hash_conntrack()" results in ARM platforms hashing uninitialised padding. This padding doesn't exist on other architectures. Fix this by replacing NF_CT_TUPLE_U_BLANK() with memset() to ensure everything is initialised. There were only 4 bytes that NF_CT_TUPLE_U_BLANK() wasn't clearing anyway (or 12 bytes on ARM). Signed-off-by: Philip Craig Signed-off-by: David S. Miller --- include/net/netfilter/nf_conntrack_tuple.h | 10 ---------- net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c | 2 +- net/netfilter/nf_conntrack_core.c | 4 ++-- 3 files changed, 3 insertions(+), 13 deletions(-) (limited to 'net/netfilter') diff --git a/include/net/netfilter/nf_conntrack_tuple.h b/include/net/netfilter/nf_conntrack_tuple.h index 1bb7087833d..a6874ba22d5 100644 --- a/include/net/netfilter/nf_conntrack_tuple.h +++ b/include/net/netfilter/nf_conntrack_tuple.h @@ -107,16 +107,6 @@ struct nf_conntrack_tuple_mask } src; }; -/* This is optimized opposed to a memset of the whole structure. Everything we - * really care about is the source/destination unions */ -#define NF_CT_TUPLE_U_BLANK(tuple) \ - do { \ - (tuple)->src.u.all = 0; \ - (tuple)->dst.u.all = 0; \ - memset(&(tuple)->src.u3, 0, sizeof((tuple)->src.u3)); \ - memset(&(tuple)->dst.u3, 0, sizeof((tuple)->dst.u3)); \ - } while (0) - #ifdef __KERNEL__ static inline void nf_ct_dump_tuple_ip(const struct nf_conntrack_tuple *t) diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c index cacb9cb27da..5a955c44036 100644 --- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c +++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c @@ -303,7 +303,7 @@ getorigdst(struct sock *sk, int optval, void __user *user, int *len) const struct nf_conntrack_tuple_hash *h; struct nf_conntrack_tuple tuple; - NF_CT_TUPLE_U_BLANK(&tuple); + memset(&tuple, 0, sizeof(tuple)); tuple.src.u3.ip = inet->rcv_saddr; tuple.src.u.tcp.port = inet->sport; tuple.dst.u3.ip = inet->daddr; diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c index 4eac65c74ed..c4b1799da5d 100644 --- a/net/netfilter/nf_conntrack_core.c +++ b/net/netfilter/nf_conntrack_core.c @@ -104,7 +104,7 @@ nf_ct_get_tuple(const struct sk_buff *skb, const struct nf_conntrack_l3proto *l3proto, const struct nf_conntrack_l4proto *l4proto) { - NF_CT_TUPLE_U_BLANK(tuple); + memset(tuple, 0, sizeof(*tuple)); tuple->src.l3num = l3num; if (l3proto->pkt_to_tuple(skb, nhoff, tuple) == 0) @@ -151,7 +151,7 @@ nf_ct_invert_tuple(struct nf_conntrack_tuple *inverse, const struct nf_conntrack_l3proto *l3proto, const struct nf_conntrack_l4proto *l4proto) { - NF_CT_TUPLE_U_BLANK(inverse); + memset(inverse, 0, sizeof(*inverse)); inverse->src.l3num = orig->src.l3num; if (l3proto->invert_tuple(inverse, orig) == 0) -- cgit v1.2.3