: Verify NAT manips have been applied before reversing them in icmp_reply_translation
Subsystems (2)
PATCH 5/18 : Verify NAT manips have been applied before reversing them in icmp_reply_translation
ICMP errors may be generated for packets that don't have all NAT manips applied yet. Verify manips have been applied before reversing them.
# This is a BitKeeper generated diff -Nru style patch. #
# ChangeSet
# 2004/12/05 22:39:52+01:00 [email protected]
# [NETFILTER]: Verify NAT manips have been applied before reversing them in icmp_reply_translation
#
# ICMP errors may be generated for packets that don't have # all NAT manips applied yet. Verify manips have been applied # before reversing them. # # Signed-off-by: Patrick McHardy <[email protected]> # # net/ipv4/netfilter/ip_nat_core.c # 2004/12/05 22:39:50+01:00 [email protected] +34 -0 # [NETFILTER]: Verify NAT manips have been applied before reversing them in icmp_reply_translation # # ICMP errors may be generated for packets that don't have # all NAT manips applied yet. Verify manips have been applied # before reversing them. # # Signed-off-by: Patrick McHardy <[email protected]> # # net/ipv4/netfilter/ip_fw_compat_masq.c # 2004/12/05 22:39:50+01:00 [email protected] +1 -1 # [NETFILTER]: Verify NAT manips have been applied before reversing them in icmp_reply_translation # # ICMP errors may be generated for packets that don't have # all NAT manips applied yet. Verify manips have been applied # before reversing them. # # Signed-off-by: Patrick McHardy <[email protected]> # # net/ipv4/netfilter/ip_conntrack_standalone.c # 2004/12/05 22:39:50+01:00 [email protected] +1 -0 # [NETFILTER]: Verify NAT manips have been applied before reversing them in icmp_reply_translation # # ICMP errors may be generated for packets that don't have # all NAT manips applied yet. Verify manips have been applied # before reversing them. # # Signed-off-by: Patrick McHardy <[email protected]> # # net/ipv4/netfilter/ip_conntrack_core.c # 2004/12/05 22:39:50+01:00 [email protected] +5 -5 # [NETFILTER]: Verify NAT manips have been applied before reversing them in icmp_reply_translation # # ICMP errors may be generated for packets that don't have # all NAT manips applied yet. Verify manips have been applied # before reversing them. # # Signed-off-by: Patrick McHardy <[email protected]> # # include/linux/netfilter_ipv4/ip_conntrack_core.h # 2004/12/05 22:39:50+01:00 [email protected] +3 -3 # [NETFILTER]: Verify NAT manips have been applied before reversing them in icmp_reply_translation # # ICMP errors may be generated for packets that don't have # all NAT manips applied yet. Verify manips have been applied # before reversing them. # # Signed-off-by: Patrick McHardy <[email protected]> # diff -Nru a/include/linux/netfilter_ipv4/ip_conntrack_core.h b/include/linux/netfilter_ipv4/ip_conntrack_core.h --- a/include/linux/netfilter_ipv4/ip_conntrack_core.h 2004-12-20 06:59:29 +01:00 +++ b/include/linux/netfilter_ipv4/ip_conntrack_core.h 2004-12-20 06:59:29 +01:00 @@ -25,9 +25,9 @@ extern struct ip_conntrack *icmp_error_track(struct sk_buff *skb, enum ip_conntrack_info *ctinfo, unsigned int hooknum); -extern int get_tuple(const struct iphdr *iph, size_t len, - struct ip_conntrack_tuple *tuple, - struct ip_conntrack_protocol *protocol); +extern int ip_ct_get_tuple(const struct iphdr *iph, size_t len, + struct ip_conntrack_tuple *tuple, + struct ip_conntrack_protocol *protocol);
/* Find a connection corresponding to a tuple. */ struct ip_conntrack_tuple_hash *
net/ipv4/netfilter/ip_conntrack_core.c +5 -5
@@ -122,9 +122,9 @@ }inline int -get_tuple (const struct iphdr *iph,size_t len, -struct ip_conntrack_tuple *tuple, -struct ip_conntrack_protocol *protocol) +ip_ct_get_tuple (const struct iphdr *iph,size_t len, +struct ip_conntrack_tuple *tuple, +struct ip_conntrack_protocol *protocol) {int ret;
@@ -546,7 +546,7 @@ innerproto =ip_ct_find_proto (inner->protocol);/* Are they talking about one of our connections? */ if (inner->ihl *4 +8 > datalen - || !get_tuple (inner, datalen, &origtuple, innerproto)) { + || !ip_ct_get_tuple (inner, datalen, &origtuple, innerproto)) {DEBUGP ("icmp_error: ! get_tuple p=%u (%u*4+%u dlen=%u)\n" , inner->protocol, inner->ihl,8 , datalen);
@@ -757,7 +757,7 @@IP_NF_ASSERT ((skb->nh.iph->frag_off &htons (IP_OFFSET )) ==0 ); -if (!get_tuple (skb->nh.iph, skb->len, &tuple, proto)) +if (!ip_ct_get_tuple (skb->nh.iph, skb->len, &tuple, proto))return NULL ;/* look for tuple match */
net/ipv4/netfilter/ip_conntrack_standalone.c +1 -0
@@ -468,6 +468,7 @@EXPORT_SYMBOL (ip_conntrack_protocol_register);EXPORT_SYMBOL (ip_conntrack_protocol_unregister);EXPORT_SYMBOL (invert_tuplepr); +EXPORT_SYMBOL (ip_ct_get_tuple);EXPORT_SYMBOL (ip_conntrack_alter_reply);EXPORT_SYMBOL (ip_conntrack_destroyed);EXPORT_SYMBOL (ip_conntrack_get);
net/ipv4/netfilter/ip_fw_compat_masq.c +1 -1
@@ -157,7 +157,7 @@case IPPROTO_UDP :IP_NF_ASSERT (((*pskb)->nh.iph->frag_off &htons (IP_OFFSET )) ==0 ); -if (!get_tuple (iph, (*pskb)->len, &tuple, protocol)) { +if (!ip_ct_get_tuple (iph, (*pskb)->len, &tuple, protocol)) {if (net_ratelimit ())printk ("ip_fw_compat_masq: Can't get tuple\n" );return NF_ACCEPT ;
net/ipv4/netfilter/ip_nat_core.c +34 -0
@@ -860,6 +860,23 @@/* not reached */ } +static inline int tuple_src_equal_dst (const struct ip_conntrack_tuple *t1, +const struct ip_conntrack_tuple *t2) +{ +if (t1->dst.protonum != t2->dst.protonum || t1->src.ip != t2->dst.ip) +return 0 ; +if (t1->dst.protonum !=IPPROTO_ICMP ) +return t1->src.u.all == t2->dst.u.all; +else { +struct ip_conntrack_tuple inv; + +/* ICMP tuples are asymetric */ +invert_tuplepr (&inv, t1); +return inv.src.u.all == t2->src.u.all && + inv.dst.u.all == t2->dst.u.all; + } +} + unsigned int icmp_reply_translation(struct sk_buff *skb, struct ip_conntrack *conntrack,
@@ -872,6 +889,7 @@size_t datalen = skb->len - ((void *)inner - (void *)iph);unsigned int i;struct ip_nat_info *info = &conntrack->nat.info; +struct ip_conntrack_tuple *cttuple, innertuple;IP_NF_ASSERT (skb->len >= iph->ihl*4 +sizeof (struct icmphdr ));/* Must be RELATED */
@@ -906,6 +924,11 @@such addresses are not too uncommon, as Alan Cox points out) */ +if (!ip_ct_get_tuple (inner, datalen, &innertuple, +ip_ct_find_proto (inner->protocol))) +return 0 ; + cttuple = &conntrack->tuplehash[dir].tuple; +READ_LOCK (&ip_nat_lock);for (i =0 ; i < info->num_manips; i++) { DEBUGP("icmp_reply: manip %u dir %s hook %u\n",
@@ -928,6 +951,17 @@if (info->manips[i].hooknum != hooknum)continue ; + +/* ICMP errors may be generated locally for packets that +* don't have all NAT manips applied yet. Verify manips +* have been applied before reversing them */ +if (info->manips[i].maniptype ==IP_NAT_MANIP_SRC ) { +if (!tuple_src_equal_dst (cttuple, &innertuple)) +continue ; + }else { +if (!tuple_src_equal_dst (&innertuple, cttuple)) +continue ; + }DEBUGP ("icmp_reply: inner %s -> %u.%u.%u.%u %u\n" , info->manips[i].maniptype == IP_NAT_MANIP_SRC