From 083edca05ab1fa6efac1ba414018f7f45a4a83ff Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Mon, 24 Jul 2006 22:52:10 -0700 Subject: [NETFILTER]: H.323 helper: fix possible NULL-ptr dereference An RCF message containing a timeout results in a NULL-ptr dereference if no RRQ has been seen before. Noticed by the "SATURN tool", reported by Thomas Dillig and Isil Dillig . Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- net/ipv4/netfilter/ip_conntrack_helper_h323.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'net') diff --git a/net/ipv4/netfilter/ip_conntrack_helper_h323.c b/net/ipv4/netfilter/ip_conntrack_helper_h323.c index af35235672d5..9a39e2969712 100644 --- a/net/ipv4/netfilter/ip_conntrack_helper_h323.c +++ b/net/ipv4/netfilter/ip_conntrack_helper_h323.c @@ -1200,7 +1200,7 @@ static struct ip_conntrack_expect *find_expect(struct ip_conntrack *ct, tuple.dst.protonum = IPPROTO_TCP; exp = __ip_conntrack_expect_find(&tuple); - if (exp->master == ct) + if (exp && exp->master == ct) return exp; return NULL; } -- cgit v1.2.2 From 3bc38712e3a6e0596ccb6f8299043a826f983701 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Mon, 24 Jul 2006 22:52:47 -0700 Subject: [NETFILTER]: nf_queue: handle NF_STOP and unknown verdicts in nf_reinject In case of an unknown verdict or NF_STOP the packet leaks. Unknown verdicts can happen when userspace is buggy. Reinject the packet in case of NF_STOP, drop on unknown verdicts. Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- net/netfilter/nf_queue.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'net') diff --git a/net/netfilter/nf_queue.c b/net/netfilter/nf_queue.c index bb6fcee452ca..662a869593bf 100644 --- a/net/netfilter/nf_queue.c +++ b/net/netfilter/nf_queue.c @@ -219,21 +219,20 @@ void nf_reinject(struct sk_buff *skb, struct nf_info *info, switch (verdict & NF_VERDICT_MASK) { case NF_ACCEPT: + case NF_STOP: info->okfn(skb); + case NF_STOLEN: break; - case NF_QUEUE: if (!nf_queue(&skb, elem, info->pf, info->hook, info->indev, info->outdev, info->okfn, verdict >> NF_VERDICT_BITS)) goto next_hook; break; + default: + kfree_skb(skb); } rcu_read_unlock(); - - if (verdict == NF_DROP) - kfree_skb(skb); - kfree(info); return; } -- cgit v1.2.2 From 72b558235950538da8bf5a8de746a194831c6fe6 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Mon, 24 Jul 2006 22:53:12 -0700 Subject: [NETFILTER]: conntrack: fix SYSCTL=n compile Signed-off-by: Adrian Bunk Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- net/ipv4/netfilter/ip_conntrack_standalone.c | 4 ++-- net/netfilter/nf_conntrack_standalone.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'net') diff --git a/net/ipv4/netfilter/ip_conntrack_standalone.c b/net/ipv4/netfilter/ip_conntrack_standalone.c index 7bd3c22003a2..7a9fa04a467a 100644 --- a/net/ipv4/netfilter/ip_conntrack_standalone.c +++ b/net/ipv4/netfilter/ip_conntrack_standalone.c @@ -534,6 +534,8 @@ static struct nf_hook_ops ip_conntrack_ops[] = { /* Sysctl support */ +int ip_conntrack_checksum = 1; + #ifdef CONFIG_SYSCTL /* From ip_conntrack_core.c */ @@ -568,8 +570,6 @@ extern unsigned int ip_ct_generic_timeout; static int log_invalid_proto_min = 0; static int log_invalid_proto_max = 255; -int ip_conntrack_checksum = 1; - static struct ctl_table_header *ip_ct_sysctl_header; static ctl_table ip_ct_sysctl_table[] = { diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c index 5fcab2ef231f..4ef836699962 100644 --- a/net/netfilter/nf_conntrack_standalone.c +++ b/net/netfilter/nf_conntrack_standalone.c @@ -428,6 +428,8 @@ static struct file_operations ct_cpu_seq_fops = { /* Sysctl support */ +int nf_conntrack_checksum = 1; + #ifdef CONFIG_SYSCTL /* From nf_conntrack_core.c */ @@ -459,8 +461,6 @@ extern unsigned int nf_ct_generic_timeout; static int log_invalid_proto_min = 0; static int log_invalid_proto_max = 255; -int nf_conntrack_checksum = 1; - static struct ctl_table_header *nf_ct_sysctl_header; static ctl_table nf_ct_sysctl_table[] = { -- cgit v1.2.2 From 8cf8fb5687bb37737ea419a0b2143aab49295779 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Mon, 24 Jul 2006 22:53:35 -0700 Subject: [NETFILTER]: SNMP NAT: fix byteorder confusion Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- net/ipv4/netfilter/ip_nat_snmp_basic.c | 4 ++-- 1 file changed, 2 insertions(+), 2 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 0b1b416759cc..18b7fbdccb61 100644 --- a/net/ipv4/netfilter/ip_nat_snmp_basic.c +++ b/net/ipv4/netfilter/ip_nat_snmp_basic.c @@ -1255,9 +1255,9 @@ static int help(struct sk_buff **pskb, struct udphdr *udph = (struct udphdr *)((u_int32_t *)iph + iph->ihl); /* SNMP replies and originating SNMP traps get mangled */ - if (udph->source == ntohs(SNMP_PORT) && dir != IP_CT_DIR_REPLY) + if (udph->source == htons(SNMP_PORT) && dir != IP_CT_DIR_REPLY) return NF_ACCEPT; - if (udph->dest == ntohs(SNMP_TRAP_PORT) && dir != IP_CT_DIR_ORIGINAL) + if (udph->dest == htons(SNMP_TRAP_PORT) && dir != IP_CT_DIR_ORIGINAL) return NF_ACCEPT; /* No NAT? */ -- cgit v1.2.2 From 28658c8967da9083be83af0a37be3b190bae79da Mon Sep 17 00:00:00 2001 From: Phil Oester Date: Mon, 24 Jul 2006 22:54:14 -0700 Subject: [NETFILTER]: xt_pkttype: fix mismatches on locally generated packets Locally generated broadcast and multicast packets have pkttype set to PACKET_LOOPBACK instead of PACKET_BROADCAST or PACKET_MULTICAST. This causes the pkttype match to fail to match packets of either type. The below patch remedies this by using the daddr as a hint as to broadcast|multicast. While not pretty, this seems like the only way to solve the problem short of just noting this as a limitation of the match. This resolves netfilter bugzilla #484 Signed-off-by: Phil Oester Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- net/netfilter/xt_pkttype.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'net') diff --git a/net/netfilter/xt_pkttype.c b/net/netfilter/xt_pkttype.c index 3ac703b5cb8f..d2f5320a80bf 100644 --- a/net/netfilter/xt_pkttype.c +++ b/net/netfilter/xt_pkttype.c @@ -9,6 +9,8 @@ #include #include #include +#include +#include #include #include @@ -28,9 +30,17 @@ static int match(const struct sk_buff *skb, unsigned int protoff, int *hotdrop) { + u_int8_t type; const struct xt_pkttype_info *info = matchinfo; - return (skb->pkt_type == info->pkttype) ^ info->invert; + if (skb->pkt_type == PACKET_LOOPBACK) + type = (MULTICAST(skb->nh.iph->daddr) + ? PACKET_MULTICAST + : PACKET_BROADCAST); + else + type = skb->pkt_type; + + return (type == info->pkttype) ^ info->invert; } static struct xt_match pkttype_match = { -- cgit v1.2.2 From 10ea6ac895418bd0d23900e3330daa6ba0836d26 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Mon, 24 Jul 2006 22:54:55 -0700 Subject: [NETFILTER]: bridge netfilter: add deferred output hooks to feature-removal-schedule Add bridge netfilter deferred output hooks to feature-removal-schedule and disable them by default. Until their removal they will be activated by the physdev match when needed. Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- net/bridge/br_netfilter.c | 5 +++++ net/netfilter/xt_physdev.c | 15 +++++++++++++++ 2 files changed, 20 insertions(+) (limited to 'net') diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c index cbc8a389a0a8..05b3de888243 100644 --- a/net/bridge/br_netfilter.c +++ b/net/bridge/br_netfilter.c @@ -61,6 +61,9 @@ static int brnf_filter_vlan_tagged = 1; #define brnf_filter_vlan_tagged 1 #endif +int brnf_deferred_hooks; +EXPORT_SYMBOL_GPL(brnf_deferred_hooks); + static __be16 inline vlan_proto(const struct sk_buff *skb) { return vlan_eth_hdr(skb)->h_vlan_encapsulated_proto; @@ -890,6 +893,8 @@ static unsigned int ip_sabotage_out(unsigned int hook, struct sk_buff **pskb, return NF_ACCEPT; else if (ip->version == 6 && !brnf_call_ip6tables) return NF_ACCEPT; + else if (!brnf_deferred_hooks) + return NF_ACCEPT; #endif if (hook == NF_IP_POST_ROUTING) return NF_ACCEPT; diff --git a/net/netfilter/xt_physdev.c b/net/netfilter/xt_physdev.c index 5fe4c9df17f5..a9f4f6f3c628 100644 --- a/net/netfilter/xt_physdev.c +++ b/net/netfilter/xt_physdev.c @@ -113,6 +113,21 @@ checkentry(const char *tablename, if (!(info->bitmask & XT_PHYSDEV_OP_MASK) || info->bitmask & ~XT_PHYSDEV_OP_MASK) return 0; + if (brnf_deferred_hooks == 0 && + info->bitmask & XT_PHYSDEV_OP_OUT && + (!(info->bitmask & XT_PHYSDEV_OP_BRIDGED) || + info->invert & XT_PHYSDEV_OP_BRIDGED) && + hook_mask & ((1 << NF_IP_LOCAL_OUT) | (1 << NF_IP_FORWARD) | + (1 << NF_IP_POST_ROUTING))) { + printk(KERN_WARNING "physdev match: using --physdev-out in the " + "OUTPUT, FORWARD and POSTROUTING chains for non-bridged " + "traffic is deprecated and breaks other things, it will " + "be removed in January 2007. See Documentation/" + "feature-removal-schedule.txt for details. This doesn't " + "affect you in case you're using it for purely bridged " + "traffic.\n"); + brnf_deferred_hooks = 1; + } return 1; } -- cgit v1.2.2 From d5af981e93aff0de5ad2a1a9935a3f6aa5cd3e3c Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Mon, 24 Jul 2006 22:55:29 -0700 Subject: [NETFILTER]: Demote xt_sctp to EXPERIMENTAL After the recent problems with all the SCTP stuff it seems reasonable to mark this as experimental. Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- net/netfilter/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'net') diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig index 42a178aa30f9..a9894ddfd72a 100644 --- a/net/netfilter/Kconfig +++ b/net/netfilter/Kconfig @@ -386,8 +386,8 @@ config NETFILTER_XT_MATCH_REALM . If unsure, say `N'. config NETFILTER_XT_MATCH_SCTP - tristate '"sctp" protocol match support' - depends on NETFILTER_XTABLES + tristate '"sctp" protocol match support (EXPERIMENTAL)' + depends on NETFILTER_XTABLES && EXPERIMENTAL help With this option enabled, you will be able to use the `sctp' match in order to match on SCTP source/destination ports -- cgit v1.2.2 From 6b7fdc3ae18a0598a999156b62d55ea55220e00f Mon Sep 17 00:00:00 2001 From: Guillaume Chazarain Date: Mon, 24 Jul 2006 23:44:44 -0700 Subject: [IPV6]: Clean skb cb on IPv6 input. Clear the accumulated junk in IP6CB when starting to handle an IPV6 packet. Signed-off-by: Guillaume Chazarain Signed-off-by: David S. Miller --- net/ipv6/ip6_input.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'net') diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c index df8f051c0fce..25c2a9e03895 100644 --- a/net/ipv6/ip6_input.c +++ b/net/ipv6/ip6_input.c @@ -71,6 +71,8 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt goto out; } + memset(IP6CB(skb), 0, sizeof(struct inet6_skb_parm)); + /* * Store incoming device index. When the packet will * be queued, we cannot refer to skb->dev anymore. -- cgit v1.2.2 From d569f1d72f068992d07ab17f7ff9aea7f0d97cdb Mon Sep 17 00:00:00 2001 From: Guillaume Chazarain Date: Mon, 24 Jul 2006 23:45:16 -0700 Subject: [IPV4]: Clear the whole IPCB, this clears also IPCB(skb)->flags. Signed-off-by: Guillaume Chazarain Signed-off-by: David S. Miller --- net/ipv4/ip_input.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'net') diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c index 184c78ca79e6..212734ca238f 100644 --- a/net/ipv4/ip_input.c +++ b/net/ipv4/ip_input.c @@ -429,7 +429,7 @@ int ip_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, } /* Remove any debris in the socket control block */ - memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options)); + memset(IPCB(skb), 0, sizeof(struct inet_skb_parm)); return NF_HOOK(PF_INET, NF_IP_PRE_ROUTING, skb, dev, NULL, ip_rcv_finish); -- cgit v1.2.2 From 722874909271a807b243a797c2958e0a12992964 Mon Sep 17 00:00:00 2001 From: Alexey Kuznetsov Date: Tue, 25 Jul 2006 16:45:12 -0700 Subject: [IPV4] ipmr: ip multicast route bug fix. IP multicast route code was reusing an skb which causes use after free and double free. From: Alexey Kuznetsov Note, it is real skb_clone(), not alloc_skb(). Equeued skb contains the whole half-prepared netlink message plus room for the rest. It could be also skb_copy(), if we want to be puristic about mangling cloned data, but original copy is really not going to be used. Acked-by: Stephen Hemminger Signed-off-by: David S. Miller --- net/ipv4/ipmr.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) (limited to 'net') diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index 9ccacf57f08b..85893eef6b16 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c @@ -1578,6 +1578,7 @@ int ipmr_get_route(struct sk_buff *skb, struct rtmsg *rtm, int nowait) cache = ipmr_cache_find(rt->rt_src, rt->rt_dst); if (cache==NULL) { + struct sk_buff *skb2; struct net_device *dev; int vif; @@ -1591,12 +1592,18 @@ int ipmr_get_route(struct sk_buff *skb, struct rtmsg *rtm, int nowait) read_unlock(&mrt_lock); return -ENODEV; } - skb->nh.raw = skb_push(skb, sizeof(struct iphdr)); - skb->nh.iph->ihl = sizeof(struct iphdr)>>2; - skb->nh.iph->saddr = rt->rt_src; - skb->nh.iph->daddr = rt->rt_dst; - skb->nh.iph->version = 0; - err = ipmr_cache_unresolved(vif, skb); + skb2 = skb_clone(skb, GFP_ATOMIC); + if (!skb2) { + read_unlock(&mrt_lock); + return -ENOMEM; + } + + skb2->nh.raw = skb_push(skb2, sizeof(struct iphdr)); + skb2->nh.iph->ihl = sizeof(struct iphdr)>>2; + skb2->nh.iph->saddr = rt->rt_src; + skb2->nh.iph->daddr = rt->rt_dst; + skb2->nh.iph->version = 0; + err = ipmr_cache_unresolved(vif, skb2); read_unlock(&mrt_lock); return err; } -- cgit v1.2.2 From f59fc7f30b710d45aadf715460b3e60dbe9d3418 Mon Sep 17 00:00:00 2001 From: Tetsuo Handa Date: Tue, 25 Jul 2006 17:05:35 -0700 Subject: [IPV4/IPV6]: Setting 0 for unused port field in RAW IP recvmsg(). From: Tetsuo Handa from-linux-kernel@i-love.sakura.ne.jp The recvmsg() for raw socket seems to return random u16 value from the kernel stack memory since port field is not initialized. But I'm not sure this patch is correct. Does raw socket return any information stored in port field? [ BSD defines RAW IP recvmsg to return a sin_port value of zero. This is described in Steven's TCP/IP Illustrated Volume 2 on page 1055, which is discussing the BSD rip_input() implementation. ] Acked-by: YOSHIFUJI Hideaki Signed-off-by: David S. Miller --- net/ipv4/raw.c | 1 + net/ipv6/raw.c | 1 + 2 files changed, 2 insertions(+) (limited to 'net') diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c index bd221ec3f81e..62b2762a2420 100644 --- a/net/ipv4/raw.c +++ b/net/ipv4/raw.c @@ -609,6 +609,7 @@ static int raw_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, if (sin) { sin->sin_family = AF_INET; sin->sin_addr.s_addr = skb->nh.iph->saddr; + sin->sin_port = 0; memset(&sin->sin_zero, 0, sizeof(sin->sin_zero)); } if (inet->cmsg_flags) diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index fa1ce0ae123e..d57e61ce4a7d 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c @@ -411,6 +411,7 @@ static int rawv6_recvmsg(struct kiocb *iocb, struct sock *sk, /* Copy the address. */ if (sin6) { sin6->sin6_family = AF_INET6; + sin6->sin6_port = 0; ipv6_addr_copy(&sin6->sin6_addr, &skb->nh.ipv6h->saddr); sin6->sin6_flowinfo = 0; sin6->sin6_scope_id = 0; -- cgit v1.2.2