diff options
-rw-r--r-- | net/ipv4/netfilter/arp_tables.c | 22 | ||||
-rw-r--r-- | net/ipv4/netfilter/ip_tables.c | 46 | ||||
-rw-r--r-- | net/ipv4/netfilter/ipt_CLUSTERIP.c | 20 | ||||
-rw-r--r-- | net/ipv4/netfilter/ipt_ECN.c | 8 | ||||
-rw-r--r-- | net/ipv4/netfilter/ipt_LOG.c | 22 | ||||
-rw-r--r-- | net/ipv4/netfilter/ipt_MASQUERADE.c | 4 | ||||
-rw-r--r-- | net/ipv4/netfilter/ipt_REJECT.c | 4 | ||||
-rw-r--r-- | net/ipv4/netfilter/ipt_ULOG.c | 6 | ||||
-rw-r--r-- | net/ipv4/netfilter/ipt_ecn.c | 4 | ||||
-rw-r--r-- | net/ipv4/netfilter/iptable_mangle.c | 4 | ||||
-rw-r--r-- | net/ipv4/netfilter/iptable_security.c | 4 | ||||
-rw-r--r-- | net/ipv4/netfilter/nf_conntrack_proto_icmp.c | 28 | ||||
-rw-r--r-- | net/ipv4/netfilter/nf_nat_standalone.c | 10 | ||||
-rw-r--r-- | net/ipv6/netfilter/ip6_tables.c | 42 | ||||
-rw-r--r-- | net/ipv6/netfilter/ip6t_LOG.c | 4 | ||||
-rw-r--r-- | net/ipv6/netfilter/ip6t_REJECT.c | 4 | ||||
-rw-r--r-- | net/ipv6/netfilter/ip6t_ah.c | 19 | ||||
-rw-r--r-- | net/ipv6/netfilter/ip6t_frag.c | 47 | ||||
-rw-r--r-- | net/ipv6/netfilter/ip6t_rt.c | 9 | ||||
-rw-r--r-- | net/ipv6/netfilter/ip6table_filter.c | 4 | ||||
-rw-r--r-- | net/ipv6/netfilter/ip6table_mangle.c | 14 | ||||
-rw-r--r-- | net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c | 12 |
22 files changed, 163 insertions, 174 deletions
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c index 27774c99d888..06632762ba5f 100644 --- a/net/ipv4/netfilter/arp_tables.c +++ b/net/ipv4/netfilter/arp_tables.c | |||
@@ -384,11 +384,11 @@ static int mark_source_chains(struct xt_table_info *newinfo, | |||
384 | |= ((1 << hook) | (1 << NF_ARP_NUMHOOKS)); | 384 | |= ((1 << hook) | (1 << NF_ARP_NUMHOOKS)); |
385 | 385 | ||
386 | /* Unconditional return/END. */ | 386 | /* Unconditional return/END. */ |
387 | if ((e->target_offset == sizeof(struct arpt_entry) | 387 | if ((e->target_offset == sizeof(struct arpt_entry) && |
388 | && (strcmp(t->target.u.user.name, | 388 | (strcmp(t->target.u.user.name, |
389 | ARPT_STANDARD_TARGET) == 0) | 389 | ARPT_STANDARD_TARGET) == 0) && |
390 | && t->verdict < 0 | 390 | t->verdict < 0 && unconditional(&e->arp)) || |
391 | && unconditional(&e->arp)) || visited) { | 391 | visited) { |
392 | unsigned int oldpos, size; | 392 | unsigned int oldpos, size; |
393 | 393 | ||
394 | if ((strcmp(t->target.u.user.name, | 394 | if ((strcmp(t->target.u.user.name, |
@@ -427,8 +427,8 @@ static int mark_source_chains(struct xt_table_info *newinfo, | |||
427 | int newpos = t->verdict; | 427 | int newpos = t->verdict; |
428 | 428 | ||
429 | if (strcmp(t->target.u.user.name, | 429 | if (strcmp(t->target.u.user.name, |
430 | ARPT_STANDARD_TARGET) == 0 | 430 | ARPT_STANDARD_TARGET) == 0 && |
431 | && newpos >= 0) { | 431 | newpos >= 0) { |
432 | if (newpos > newinfo->size - | 432 | if (newpos > newinfo->size - |
433 | sizeof(struct arpt_entry)) { | 433 | sizeof(struct arpt_entry)) { |
434 | duprintf("mark_source_chains: " | 434 | duprintf("mark_source_chains: " |
@@ -559,8 +559,8 @@ static inline int check_entry_size_and_hooks(struct arpt_entry *e, | |||
559 | { | 559 | { |
560 | unsigned int h; | 560 | unsigned int h; |
561 | 561 | ||
562 | if ((unsigned long)e % __alignof__(struct arpt_entry) != 0 | 562 | if ((unsigned long)e % __alignof__(struct arpt_entry) != 0 || |
563 | || (unsigned char *)e + sizeof(struct arpt_entry) >= limit) { | 563 | (unsigned char *)e + sizeof(struct arpt_entry) >= limit) { |
564 | duprintf("Bad offset %p\n", e); | 564 | duprintf("Bad offset %p\n", e); |
565 | return -EINVAL; | 565 | return -EINVAL; |
566 | } | 566 | } |
@@ -1251,8 +1251,8 @@ check_compat_entry_size_and_hooks(struct compat_arpt_entry *e, | |||
1251 | int ret, off, h; | 1251 | int ret, off, h; |
1252 | 1252 | ||
1253 | duprintf("check_compat_entry_size_and_hooks %p\n", e); | 1253 | duprintf("check_compat_entry_size_and_hooks %p\n", e); |
1254 | if ((unsigned long)e % __alignof__(struct compat_arpt_entry) != 0 | 1254 | if ((unsigned long)e % __alignof__(struct compat_arpt_entry) != 0 || |
1255 | || (unsigned char *)e + sizeof(struct compat_arpt_entry) >= limit) { | 1255 | (unsigned char *)e + sizeof(struct compat_arpt_entry) >= limit) { |
1256 | duprintf("Bad offset %p, limit = %p\n", e, limit); | 1256 | duprintf("Bad offset %p, limit = %p\n", e, limit); |
1257 | return -EINVAL; | 1257 | return -EINVAL; |
1258 | } | 1258 | } |
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c index cde755d5eeab..572330a552ef 100644 --- a/net/ipv4/netfilter/ip_tables.c +++ b/net/ipv4/netfilter/ip_tables.c | |||
@@ -89,9 +89,9 @@ ip_packet_match(const struct iphdr *ip, | |||
89 | #define FWINV(bool, invflg) ((bool) ^ !!(ipinfo->invflags & (invflg))) | 89 | #define FWINV(bool, invflg) ((bool) ^ !!(ipinfo->invflags & (invflg))) |
90 | 90 | ||
91 | if (FWINV((ip->saddr&ipinfo->smsk.s_addr) != ipinfo->src.s_addr, | 91 | if (FWINV((ip->saddr&ipinfo->smsk.s_addr) != ipinfo->src.s_addr, |
92 | IPT_INV_SRCIP) | 92 | IPT_INV_SRCIP) || |
93 | || FWINV((ip->daddr&ipinfo->dmsk.s_addr) != ipinfo->dst.s_addr, | 93 | FWINV((ip->daddr&ipinfo->dmsk.s_addr) != ipinfo->dst.s_addr, |
94 | IPT_INV_DSTIP)) { | 94 | IPT_INV_DSTIP)) { |
95 | dprintf("Source or dest mismatch.\n"); | 95 | dprintf("Source or dest mismatch.\n"); |
96 | 96 | ||
97 | dprintf("SRC: %pI4. Mask: %pI4. Target: %pI4.%s\n", | 97 | dprintf("SRC: %pI4. Mask: %pI4. Target: %pI4.%s\n", |
@@ -122,8 +122,8 @@ ip_packet_match(const struct iphdr *ip, | |||
122 | } | 122 | } |
123 | 123 | ||
124 | /* Check specific protocol */ | 124 | /* Check specific protocol */ |
125 | if (ipinfo->proto | 125 | if (ipinfo->proto && |
126 | && FWINV(ip->protocol != ipinfo->proto, IPT_INV_PROTO)) { | 126 | FWINV(ip->protocol != ipinfo->proto, IPT_INV_PROTO)) { |
127 | dprintf("Packet protocol %hi does not match %hi.%s\n", | 127 | dprintf("Packet protocol %hi does not match %hi.%s\n", |
128 | ip->protocol, ipinfo->proto, | 128 | ip->protocol, ipinfo->proto, |
129 | ipinfo->invflags&IPT_INV_PROTO ? " (INV)":""); | 129 | ipinfo->invflags&IPT_INV_PROTO ? " (INV)":""); |
@@ -246,11 +246,11 @@ get_chainname_rulenum(struct ipt_entry *s, struct ipt_entry *e, | |||
246 | } else if (s == e) { | 246 | } else if (s == e) { |
247 | (*rulenum)++; | 247 | (*rulenum)++; |
248 | 248 | ||
249 | if (s->target_offset == sizeof(struct ipt_entry) | 249 | if (s->target_offset == sizeof(struct ipt_entry) && |
250 | && strcmp(t->target.u.kernel.target->name, | 250 | strcmp(t->target.u.kernel.target->name, |
251 | IPT_STANDARD_TARGET) == 0 | 251 | IPT_STANDARD_TARGET) == 0 && |
252 | && t->verdict < 0 | 252 | t->verdict < 0 && |
253 | && unconditional(&s->ip)) { | 253 | unconditional(&s->ip)) { |
254 | /* Tail of chains: STANDARD target (return/policy) */ | 254 | /* Tail of chains: STANDARD target (return/policy) */ |
255 | *comment = *chainname == hookname | 255 | *comment = *chainname == hookname |
256 | ? comments[NF_IP_TRACE_COMMENT_POLICY] | 256 | ? comments[NF_IP_TRACE_COMMENT_POLICY] |
@@ -388,8 +388,8 @@ ipt_do_table(struct sk_buff *skb, | |||
388 | back = get_entry(table_base, back->comefrom); | 388 | back = get_entry(table_base, back->comefrom); |
389 | continue; | 389 | continue; |
390 | } | 390 | } |
391 | if (table_base + v != ipt_next_entry(e) | 391 | if (table_base + v != ipt_next_entry(e) && |
392 | && !(e->ip.flags & IPT_F_GOTO)) { | 392 | !(e->ip.flags & IPT_F_GOTO)) { |
393 | /* Save old back ptr in next entry */ | 393 | /* Save old back ptr in next entry */ |
394 | struct ipt_entry *next = ipt_next_entry(e); | 394 | struct ipt_entry *next = ipt_next_entry(e); |
395 | next->comefrom = (void *)back - table_base; | 395 | next->comefrom = (void *)back - table_base; |
@@ -473,11 +473,11 @@ mark_source_chains(struct xt_table_info *newinfo, | |||
473 | e->comefrom |= ((1 << hook) | (1 << NF_INET_NUMHOOKS)); | 473 | e->comefrom |= ((1 << hook) | (1 << NF_INET_NUMHOOKS)); |
474 | 474 | ||
475 | /* Unconditional return/END. */ | 475 | /* Unconditional return/END. */ |
476 | if ((e->target_offset == sizeof(struct ipt_entry) | 476 | if ((e->target_offset == sizeof(struct ipt_entry) && |
477 | && (strcmp(t->target.u.user.name, | 477 | (strcmp(t->target.u.user.name, |
478 | IPT_STANDARD_TARGET) == 0) | 478 | IPT_STANDARD_TARGET) == 0) && |
479 | && t->verdict < 0 | 479 | t->verdict < 0 && unconditional(&e->ip)) || |
480 | && unconditional(&e->ip)) || visited) { | 480 | visited) { |
481 | unsigned int oldpos, size; | 481 | unsigned int oldpos, size; |
482 | 482 | ||
483 | if ((strcmp(t->target.u.user.name, | 483 | if ((strcmp(t->target.u.user.name, |
@@ -524,8 +524,8 @@ mark_source_chains(struct xt_table_info *newinfo, | |||
524 | int newpos = t->verdict; | 524 | int newpos = t->verdict; |
525 | 525 | ||
526 | if (strcmp(t->target.u.user.name, | 526 | if (strcmp(t->target.u.user.name, |
527 | IPT_STANDARD_TARGET) == 0 | 527 | IPT_STANDARD_TARGET) == 0 && |
528 | && newpos >= 0) { | 528 | newpos >= 0) { |
529 | if (newpos > newinfo->size - | 529 | if (newpos > newinfo->size - |
530 | sizeof(struct ipt_entry)) { | 530 | sizeof(struct ipt_entry)) { |
531 | duprintf("mark_source_chains: " | 531 | duprintf("mark_source_chains: " |
@@ -735,8 +735,8 @@ check_entry_size_and_hooks(struct ipt_entry *e, | |||
735 | { | 735 | { |
736 | unsigned int h; | 736 | unsigned int h; |
737 | 737 | ||
738 | if ((unsigned long)e % __alignof__(struct ipt_entry) != 0 | 738 | if ((unsigned long)e % __alignof__(struct ipt_entry) != 0 || |
739 | || (unsigned char *)e + sizeof(struct ipt_entry) >= limit) { | 739 | (unsigned char *)e + sizeof(struct ipt_entry) >= limit) { |
740 | duprintf("Bad offset %p\n", e); | 740 | duprintf("Bad offset %p\n", e); |
741 | return -EINVAL; | 741 | return -EINVAL; |
742 | } | 742 | } |
@@ -1548,8 +1548,8 @@ check_compat_entry_size_and_hooks(struct compat_ipt_entry *e, | |||
1548 | int ret, off, h; | 1548 | int ret, off, h; |
1549 | 1549 | ||
1550 | duprintf("check_compat_entry_size_and_hooks %p\n", e); | 1550 | duprintf("check_compat_entry_size_and_hooks %p\n", e); |
1551 | if ((unsigned long)e % __alignof__(struct compat_ipt_entry) != 0 | 1551 | if ((unsigned long)e % __alignof__(struct compat_ipt_entry) != 0 || |
1552 | || (unsigned char *)e + sizeof(struct compat_ipt_entry) >= limit) { | 1552 | (unsigned char *)e + sizeof(struct compat_ipt_entry) >= limit) { |
1553 | duprintf("Bad offset %p, limit = %p\n", e, limit); | 1553 | duprintf("Bad offset %p, limit = %p\n", e, limit); |
1554 | return -EINVAL; | 1554 | return -EINVAL; |
1555 | } | 1555 | } |
diff --git a/net/ipv4/netfilter/ipt_CLUSTERIP.c b/net/ipv4/netfilter/ipt_CLUSTERIP.c index 2e4f98b85524..40ca2d240abb 100644 --- a/net/ipv4/netfilter/ipt_CLUSTERIP.c +++ b/net/ipv4/netfilter/ipt_CLUSTERIP.c | |||
@@ -303,9 +303,9 @@ clusterip_tg(struct sk_buff *skb, const struct xt_target_param *par) | |||
303 | 303 | ||
304 | /* special case: ICMP error handling. conntrack distinguishes between | 304 | /* special case: ICMP error handling. conntrack distinguishes between |
305 | * error messages (RELATED) and information requests (see below) */ | 305 | * error messages (RELATED) and information requests (see below) */ |
306 | if (ip_hdr(skb)->protocol == IPPROTO_ICMP | 306 | if (ip_hdr(skb)->protocol == IPPROTO_ICMP && |
307 | && (ctinfo == IP_CT_RELATED | 307 | (ctinfo == IP_CT_RELATED || |
308 | || ctinfo == IP_CT_RELATED+IP_CT_IS_REPLY)) | 308 | ctinfo == IP_CT_RELATED + IP_CT_IS_REPLY)) |
309 | return XT_CONTINUE; | 309 | return XT_CONTINUE; |
310 | 310 | ||
311 | /* ip_conntrack_icmp guarantees us that we only have ICMP_ECHO, | 311 | /* ip_conntrack_icmp guarantees us that we only have ICMP_ECHO, |
@@ -362,8 +362,8 @@ static bool clusterip_tg_check(const struct xt_tgchk_param *par) | |||
362 | return false; | 362 | return false; |
363 | 363 | ||
364 | } | 364 | } |
365 | if (e->ip.dmsk.s_addr != htonl(0xffffffff) | 365 | if (e->ip.dmsk.s_addr != htonl(0xffffffff) || |
366 | || e->ip.dst.s_addr == 0) { | 366 | e->ip.dst.s_addr == 0) { |
367 | printk(KERN_ERR "CLUSTERIP: Please specify destination IP\n"); | 367 | printk(KERN_ERR "CLUSTERIP: Please specify destination IP\n"); |
368 | return false; | 368 | return false; |
369 | } | 369 | } |
@@ -495,14 +495,14 @@ arp_mangle(unsigned int hook, | |||
495 | struct clusterip_config *c; | 495 | struct clusterip_config *c; |
496 | 496 | ||
497 | /* we don't care about non-ethernet and non-ipv4 ARP */ | 497 | /* we don't care about non-ethernet and non-ipv4 ARP */ |
498 | if (arp->ar_hrd != htons(ARPHRD_ETHER) | 498 | if (arp->ar_hrd != htons(ARPHRD_ETHER) || |
499 | || arp->ar_pro != htons(ETH_P_IP) | 499 | arp->ar_pro != htons(ETH_P_IP) || |
500 | || arp->ar_pln != 4 || arp->ar_hln != ETH_ALEN) | 500 | arp->ar_pln != 4 || arp->ar_hln != ETH_ALEN) |
501 | return NF_ACCEPT; | 501 | return NF_ACCEPT; |
502 | 502 | ||
503 | /* we only want to mangle arp requests and replies */ | 503 | /* we only want to mangle arp requests and replies */ |
504 | if (arp->ar_op != htons(ARPOP_REPLY) | 504 | if (arp->ar_op != htons(ARPOP_REPLY) && |
505 | && arp->ar_op != htons(ARPOP_REQUEST)) | 505 | arp->ar_op != htons(ARPOP_REQUEST)) |
506 | return NF_ACCEPT; | 506 | return NF_ACCEPT; |
507 | 507 | ||
508 | payload = (void *)(arp+1); | 508 | payload = (void *)(arp+1); |
diff --git a/net/ipv4/netfilter/ipt_ECN.c b/net/ipv4/netfilter/ipt_ECN.c index f7e2fa0974dc..549e206cdd42 100644 --- a/net/ipv4/netfilter/ipt_ECN.c +++ b/net/ipv4/netfilter/ipt_ECN.c | |||
@@ -85,8 +85,8 @@ ecn_tg(struct sk_buff *skb, const struct xt_target_param *par) | |||
85 | if (!set_ect_ip(skb, einfo)) | 85 | if (!set_ect_ip(skb, einfo)) |
86 | return NF_DROP; | 86 | return NF_DROP; |
87 | 87 | ||
88 | if (einfo->operation & (IPT_ECN_OP_SET_ECE | IPT_ECN_OP_SET_CWR) | 88 | if (einfo->operation & (IPT_ECN_OP_SET_ECE | IPT_ECN_OP_SET_CWR) && |
89 | && ip_hdr(skb)->protocol == IPPROTO_TCP) | 89 | ip_hdr(skb)->protocol == IPPROTO_TCP) |
90 | if (!set_ect_tcp(skb, einfo)) | 90 | if (!set_ect_tcp(skb, einfo)) |
91 | return NF_DROP; | 91 | return NF_DROP; |
92 | 92 | ||
@@ -108,8 +108,8 @@ static bool ecn_tg_check(const struct xt_tgchk_param *par) | |||
108 | einfo->ip_ect); | 108 | einfo->ip_ect); |
109 | return false; | 109 | return false; |
110 | } | 110 | } |
111 | if ((einfo->operation & (IPT_ECN_OP_SET_ECE|IPT_ECN_OP_SET_CWR)) | 111 | if ((einfo->operation & (IPT_ECN_OP_SET_ECE|IPT_ECN_OP_SET_CWR)) && |
112 | && (e->ip.proto != IPPROTO_TCP || (e->ip.invflags & XT_INV_PROTO))) { | 112 | (e->ip.proto != IPPROTO_TCP || (e->ip.invflags & XT_INV_PROTO))) { |
113 | printk(KERN_WARNING "ECN: cannot use TCP operations on a " | 113 | printk(KERN_WARNING "ECN: cannot use TCP operations on a " |
114 | "non-tcp rule\n"); | 114 | "non-tcp rule\n"); |
115 | return false; | 115 | return false; |
diff --git a/net/ipv4/netfilter/ipt_LOG.c b/net/ipv4/netfilter/ipt_LOG.c index acc44c69eb68..ee128efa1c8d 100644 --- a/net/ipv4/netfilter/ipt_LOG.c +++ b/net/ipv4/netfilter/ipt_LOG.c | |||
@@ -74,8 +74,8 @@ static void dump_packet(const struct nf_loginfo *info, | |||
74 | if (ntohs(ih->frag_off) & IP_OFFSET) | 74 | if (ntohs(ih->frag_off) & IP_OFFSET) |
75 | printk("FRAG:%u ", ntohs(ih->frag_off) & IP_OFFSET); | 75 | printk("FRAG:%u ", ntohs(ih->frag_off) & IP_OFFSET); |
76 | 76 | ||
77 | if ((logflags & IPT_LOG_IPOPT) | 77 | if ((logflags & IPT_LOG_IPOPT) && |
78 | && ih->ihl * 4 > sizeof(struct iphdr)) { | 78 | ih->ihl * 4 > sizeof(struct iphdr)) { |
79 | const unsigned char *op; | 79 | const unsigned char *op; |
80 | unsigned char _opt[4 * 15 - sizeof(struct iphdr)]; | 80 | unsigned char _opt[4 * 15 - sizeof(struct iphdr)]; |
81 | unsigned int i, optsize; | 81 | unsigned int i, optsize; |
@@ -146,8 +146,8 @@ static void dump_packet(const struct nf_loginfo *info, | |||
146 | /* Max length: 11 "URGP=65535 " */ | 146 | /* Max length: 11 "URGP=65535 " */ |
147 | printk("URGP=%u ", ntohs(th->urg_ptr)); | 147 | printk("URGP=%u ", ntohs(th->urg_ptr)); |
148 | 148 | ||
149 | if ((logflags & IPT_LOG_TCPOPT) | 149 | if ((logflags & IPT_LOG_TCPOPT) && |
150 | && th->doff * 4 > sizeof(struct tcphdr)) { | 150 | th->doff * 4 > sizeof(struct tcphdr)) { |
151 | unsigned char _opt[4 * 15 - sizeof(struct tcphdr)]; | 151 | unsigned char _opt[4 * 15 - sizeof(struct tcphdr)]; |
152 | const unsigned char *op; | 152 | const unsigned char *op; |
153 | unsigned int i, optsize; | 153 | unsigned int i, optsize; |
@@ -238,9 +238,9 @@ static void dump_packet(const struct nf_loginfo *info, | |||
238 | printk("TYPE=%u CODE=%u ", ich->type, ich->code); | 238 | printk("TYPE=%u CODE=%u ", ich->type, ich->code); |
239 | 239 | ||
240 | /* Max length: 25 "INCOMPLETE [65535 bytes] " */ | 240 | /* Max length: 25 "INCOMPLETE [65535 bytes] " */ |
241 | if (ich->type <= NR_ICMP_TYPES | 241 | if (ich->type <= NR_ICMP_TYPES && |
242 | && required_len[ich->type] | 242 | required_len[ich->type] && |
243 | && skb->len-iphoff-ih->ihl*4 < required_len[ich->type]) { | 243 | skb->len-iphoff-ih->ihl*4 < required_len[ich->type]) { |
244 | printk("INCOMPLETE [%u bytes] ", | 244 | printk("INCOMPLETE [%u bytes] ", |
245 | skb->len - iphoff - ih->ihl*4); | 245 | skb->len - iphoff - ih->ihl*4); |
246 | break; | 246 | break; |
@@ -276,8 +276,8 @@ static void dump_packet(const struct nf_loginfo *info, | |||
276 | } | 276 | } |
277 | 277 | ||
278 | /* Max length: 10 "MTU=65535 " */ | 278 | /* Max length: 10 "MTU=65535 " */ |
279 | if (ich->type == ICMP_DEST_UNREACH | 279 | if (ich->type == ICMP_DEST_UNREACH && |
280 | && ich->code == ICMP_FRAG_NEEDED) | 280 | ich->code == ICMP_FRAG_NEEDED) |
281 | printk("MTU=%u ", ntohs(ich->un.frag.mtu)); | 281 | printk("MTU=%u ", ntohs(ich->un.frag.mtu)); |
282 | } | 282 | } |
283 | break; | 283 | break; |
@@ -407,8 +407,8 @@ ipt_log_packet(u_int8_t pf, | |||
407 | if (in && !out) { | 407 | if (in && !out) { |
408 | /* MAC logging for input chain only. */ | 408 | /* MAC logging for input chain only. */ |
409 | printk("MAC="); | 409 | printk("MAC="); |
410 | if (skb->dev && skb->dev->hard_header_len | 410 | if (skb->dev && skb->dev->hard_header_len && |
411 | && skb->mac_header != skb->network_header) { | 411 | skb->mac_header != skb->network_header) { |
412 | int i; | 412 | int i; |
413 | const unsigned char *p = skb_mac_header(skb); | 413 | const unsigned char *p = skb_mac_header(skb); |
414 | for (i = 0; i < skb->dev->hard_header_len; i++,p++) | 414 | for (i = 0; i < skb->dev->hard_header_len; i++,p++) |
diff --git a/net/ipv4/netfilter/ipt_MASQUERADE.c b/net/ipv4/netfilter/ipt_MASQUERADE.c index dada0863946d..650b54042b01 100644 --- a/net/ipv4/netfilter/ipt_MASQUERADE.c +++ b/net/ipv4/netfilter/ipt_MASQUERADE.c | |||
@@ -59,8 +59,8 @@ masquerade_tg(struct sk_buff *skb, const struct xt_target_param *par) | |||
59 | ct = nf_ct_get(skb, &ctinfo); | 59 | ct = nf_ct_get(skb, &ctinfo); |
60 | nat = nfct_nat(ct); | 60 | nat = nfct_nat(ct); |
61 | 61 | ||
62 | NF_CT_ASSERT(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED | 62 | NF_CT_ASSERT(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED || |
63 | || ctinfo == IP_CT_RELATED + IP_CT_IS_REPLY)); | 63 | ctinfo == IP_CT_RELATED + IP_CT_IS_REPLY)); |
64 | 64 | ||
65 | /* Source address is 0.0.0.0 - locally generated packet that is | 65 | /* Source address is 0.0.0.0 - locally generated packet that is |
66 | * probably not supposed to be masqueraded. | 66 | * probably not supposed to be masqueraded. |
diff --git a/net/ipv4/netfilter/ipt_REJECT.c b/net/ipv4/netfilter/ipt_REJECT.c index c93ae44bff2a..5113b8f1a379 100644 --- a/net/ipv4/netfilter/ipt_REJECT.c +++ b/net/ipv4/netfilter/ipt_REJECT.c | |||
@@ -184,8 +184,8 @@ static bool reject_tg_check(const struct xt_tgchk_param *par) | |||
184 | return false; | 184 | return false; |
185 | } else if (rejinfo->with == IPT_TCP_RESET) { | 185 | } else if (rejinfo->with == IPT_TCP_RESET) { |
186 | /* Must specify that it's a TCP packet */ | 186 | /* Must specify that it's a TCP packet */ |
187 | if (e->ip.proto != IPPROTO_TCP | 187 | if (e->ip.proto != IPPROTO_TCP || |
188 | || (e->ip.invflags & XT_INV_PROTO)) { | 188 | (e->ip.invflags & XT_INV_PROTO)) { |
189 | printk("ipt_REJECT: TCP_RESET invalid for non-tcp\n"); | 189 | printk("ipt_REJECT: TCP_RESET invalid for non-tcp\n"); |
190 | return false; | 190 | return false; |
191 | } | 191 | } |
diff --git a/net/ipv4/netfilter/ipt_ULOG.c b/net/ipv4/netfilter/ipt_ULOG.c index d32cc4bb328a..399061c3fd7d 100644 --- a/net/ipv4/netfilter/ipt_ULOG.c +++ b/net/ipv4/netfilter/ipt_ULOG.c | |||
@@ -226,9 +226,9 @@ static void ipt_ulog_packet(unsigned int hooknum, | |||
226 | else | 226 | else |
227 | *(pm->prefix) = '\0'; | 227 | *(pm->prefix) = '\0'; |
228 | 228 | ||
229 | if (in && in->hard_header_len > 0 | 229 | if (in && in->hard_header_len > 0 && |
230 | && skb->mac_header != skb->network_header | 230 | skb->mac_header != skb->network_header && |
231 | && in->hard_header_len <= ULOG_MAC_LEN) { | 231 | in->hard_header_len <= ULOG_MAC_LEN) { |
232 | memcpy(pm->mac, skb_mac_header(skb), in->hard_header_len); | 232 | memcpy(pm->mac, skb_mac_header(skb), in->hard_header_len); |
233 | pm->mac_len = in->hard_header_len; | 233 | pm->mac_len = in->hard_header_len; |
234 | } else | 234 | } else |
diff --git a/net/ipv4/netfilter/ipt_ecn.c b/net/ipv4/netfilter/ipt_ecn.c index 6289b64144c6..2a1e56b71908 100644 --- a/net/ipv4/netfilter/ipt_ecn.c +++ b/net/ipv4/netfilter/ipt_ecn.c | |||
@@ -96,8 +96,8 @@ static bool ecn_mt_check(const struct xt_mtchk_param *par) | |||
96 | if (info->invert & IPT_ECN_OP_MATCH_MASK) | 96 | if (info->invert & IPT_ECN_OP_MATCH_MASK) |
97 | return false; | 97 | return false; |
98 | 98 | ||
99 | if (info->operation & (IPT_ECN_OP_MATCH_ECE|IPT_ECN_OP_MATCH_CWR) | 99 | if (info->operation & (IPT_ECN_OP_MATCH_ECE|IPT_ECN_OP_MATCH_CWR) && |
100 | && ip->proto != IPPROTO_TCP) { | 100 | ip->proto != IPPROTO_TCP) { |
101 | printk(KERN_WARNING "ipt_ecn: can't match TCP bits in rule for" | 101 | printk(KERN_WARNING "ipt_ecn: can't match TCP bits in rule for" |
102 | " non-tcp packets\n"); | 102 | " non-tcp packets\n"); |
103 | return false; | 103 | return false; |
diff --git a/net/ipv4/netfilter/iptable_mangle.c b/net/ipv4/netfilter/iptable_mangle.c index 036047f9b0f2..fae78c3076c4 100644 --- a/net/ipv4/netfilter/iptable_mangle.c +++ b/net/ipv4/netfilter/iptable_mangle.c | |||
@@ -130,8 +130,8 @@ ipt_local_hook(unsigned int hook, | |||
130 | u_int32_t mark; | 130 | u_int32_t mark; |
131 | 131 | ||
132 | /* root is playing with raw sockets. */ | 132 | /* root is playing with raw sockets. */ |
133 | if (skb->len < sizeof(struct iphdr) | 133 | if (skb->len < sizeof(struct iphdr) || |
134 | || ip_hdrlen(skb) < sizeof(struct iphdr)) | 134 | ip_hdrlen(skb) < sizeof(struct iphdr)) |
135 | return NF_ACCEPT; | 135 | return NF_ACCEPT; |
136 | 136 | ||
137 | /* Save things which could affect route */ | 137 | /* Save things which could affect route */ |
diff --git a/net/ipv4/netfilter/iptable_security.c b/net/ipv4/netfilter/iptable_security.c index 99eb76c65d25..3bd3d6388da5 100644 --- a/net/ipv4/netfilter/iptable_security.c +++ b/net/ipv4/netfilter/iptable_security.c | |||
@@ -94,8 +94,8 @@ ipt_local_out_hook(unsigned int hook, | |||
94 | int (*okfn)(struct sk_buff *)) | 94 | int (*okfn)(struct sk_buff *)) |
95 | { | 95 | { |
96 | /* Somebody is playing with raw sockets. */ | 96 | /* Somebody is playing with raw sockets. */ |
97 | if (skb->len < sizeof(struct iphdr) | 97 | if (skb->len < sizeof(struct iphdr) || |
98 | || ip_hdrlen(skb) < sizeof(struct iphdr)) | 98 | ip_hdrlen(skb) < sizeof(struct iphdr)) |
99 | return NF_ACCEPT; | 99 | return NF_ACCEPT; |
100 | return ipt_do_table(skb, hook, in, out, | 100 | return ipt_do_table(skb, hook, in, out, |
101 | dev_net(out)->ipv4.iptable_security); | 101 | dev_net(out)->ipv4.iptable_security); |
diff --git a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c index d71ba7677344..e3dd93623df8 100644 --- a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c +++ b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c | |||
@@ -54,8 +54,8 @@ static const u_int8_t invmap[] = { | |||
54 | static bool icmp_invert_tuple(struct nf_conntrack_tuple *tuple, | 54 | static bool icmp_invert_tuple(struct nf_conntrack_tuple *tuple, |
55 | const struct nf_conntrack_tuple *orig) | 55 | const struct nf_conntrack_tuple *orig) |
56 | { | 56 | { |
57 | if (orig->dst.u.icmp.type >= sizeof(invmap) | 57 | if (orig->dst.u.icmp.type >= sizeof(invmap) || |
58 | || !invmap[orig->dst.u.icmp.type]) | 58 | !invmap[orig->dst.u.icmp.type]) |
59 | return false; | 59 | return false; |
60 | 60 | ||
61 | tuple->src.u.icmp.id = orig->src.u.icmp.id; | 61 | tuple->src.u.icmp.id = orig->src.u.icmp.id; |
@@ -101,8 +101,8 @@ static bool icmp_new(struct nf_conn *ct, const struct sk_buff *skb, | |||
101 | [ICMP_ADDRESS] = 1 | 101 | [ICMP_ADDRESS] = 1 |
102 | }; | 102 | }; |
103 | 103 | ||
104 | if (ct->tuplehash[0].tuple.dst.u.icmp.type >= sizeof(valid_new) | 104 | if (ct->tuplehash[0].tuple.dst.u.icmp.type >= sizeof(valid_new) || |
105 | || !valid_new[ct->tuplehash[0].tuple.dst.u.icmp.type]) { | 105 | !valid_new[ct->tuplehash[0].tuple.dst.u.icmp.type]) { |
106 | /* Can't create a new ICMP `conn' with this. */ | 106 | /* Can't create a new ICMP `conn' with this. */ |
107 | pr_debug("icmp: can't create new conn with type %u\n", | 107 | pr_debug("icmp: can't create new conn with type %u\n", |
108 | ct->tuplehash[0].tuple.dst.u.icmp.type); | 108 | ct->tuplehash[0].tuple.dst.u.icmp.type); |
@@ -201,11 +201,11 @@ icmp_error(struct net *net, struct sk_buff *skb, unsigned int dataoff, | |||
201 | } | 201 | } |
202 | 202 | ||
203 | /* Need to track icmp error message? */ | 203 | /* Need to track icmp error message? */ |
204 | if (icmph->type != ICMP_DEST_UNREACH | 204 | if (icmph->type != ICMP_DEST_UNREACH && |
205 | && icmph->type != ICMP_SOURCE_QUENCH | 205 | icmph->type != ICMP_SOURCE_QUENCH && |
206 | && icmph->type != ICMP_TIME_EXCEEDED | 206 | icmph->type != ICMP_TIME_EXCEEDED && |
207 | && icmph->type != ICMP_PARAMETERPROB | 207 | icmph->type != ICMP_PARAMETERPROB && |
208 | && icmph->type != ICMP_REDIRECT) | 208 | icmph->type != ICMP_REDIRECT) |
209 | return NF_ACCEPT; | 209 | return NF_ACCEPT; |
210 | 210 | ||
211 | return icmp_error_message(net, skb, ctinfo, hooknum); | 211 | return icmp_error_message(net, skb, ctinfo, hooknum); |
@@ -238,17 +238,17 @@ static const struct nla_policy icmp_nla_policy[CTA_PROTO_MAX+1] = { | |||
238 | static int icmp_nlattr_to_tuple(struct nlattr *tb[], | 238 | static int icmp_nlattr_to_tuple(struct nlattr *tb[], |
239 | struct nf_conntrack_tuple *tuple) | 239 | struct nf_conntrack_tuple *tuple) |
240 | { | 240 | { |
241 | if (!tb[CTA_PROTO_ICMP_TYPE] | 241 | if (!tb[CTA_PROTO_ICMP_TYPE] || |
242 | || !tb[CTA_PROTO_ICMP_CODE] | 242 | !tb[CTA_PROTO_ICMP_CODE] || |
243 | || !tb[CTA_PROTO_ICMP_ID]) | 243 | !tb[CTA_PROTO_ICMP_ID]) |
244 | return -EINVAL; | 244 | return -EINVAL; |
245 | 245 | ||
246 | tuple->dst.u.icmp.type = nla_get_u8(tb[CTA_PROTO_ICMP_TYPE]); | 246 | tuple->dst.u.icmp.type = nla_get_u8(tb[CTA_PROTO_ICMP_TYPE]); |
247 | tuple->dst.u.icmp.code = nla_get_u8(tb[CTA_PROTO_ICMP_CODE]); | 247 | tuple->dst.u.icmp.code = nla_get_u8(tb[CTA_PROTO_ICMP_CODE]); |
248 | tuple->src.u.icmp.id = nla_get_be16(tb[CTA_PROTO_ICMP_ID]); | 248 | tuple->src.u.icmp.id = nla_get_be16(tb[CTA_PROTO_ICMP_ID]); |
249 | 249 | ||
250 | if (tuple->dst.u.icmp.type >= sizeof(invmap) | 250 | if (tuple->dst.u.icmp.type >= sizeof(invmap) || |
251 | || !invmap[tuple->dst.u.icmp.type]) | 251 | !invmap[tuple->dst.u.icmp.type]) |
252 | return -EINVAL; | 252 | return -EINVAL; |
253 | 253 | ||
254 | return 0; | 254 | return 0; |
diff --git a/net/ipv4/netfilter/nf_nat_standalone.c b/net/ipv4/netfilter/nf_nat_standalone.c index 5f41d017ddd8..5678e9562c15 100644 --- a/net/ipv4/netfilter/nf_nat_standalone.c +++ b/net/ipv4/netfilter/nf_nat_standalone.c | |||
@@ -197,11 +197,11 @@ nf_nat_out(unsigned int hooknum, | |||
197 | (ct = nf_ct_get(skb, &ctinfo)) != NULL) { | 197 | (ct = nf_ct_get(skb, &ctinfo)) != NULL) { |
198 | enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo); | 198 | enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo); |
199 | 199 | ||
200 | if (ct->tuplehash[dir].tuple.src.u3.ip != | 200 | if ((ct->tuplehash[dir].tuple.src.u3.ip != |
201 | ct->tuplehash[!dir].tuple.dst.u3.ip | 201 | ct->tuplehash[!dir].tuple.dst.u3.ip) || |
202 | || ct->tuplehash[dir].tuple.src.u.all != | 202 | (ct->tuplehash[dir].tuple.src.u.all != |
203 | ct->tuplehash[!dir].tuple.dst.u.all | 203 | ct->tuplehash[!dir].tuple.dst.u.all) |
204 | ) | 204 | ) |
205 | return ip_xfrm_me_harder(skb) == 0 ? ret : NF_DROP; | 205 | return ip_xfrm_me_harder(skb) == 0 ? ret : NF_DROP; |
206 | } | 206 | } |
207 | #endif | 207 | #endif |
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c index cc9f8ef303fd..480d7f8c9802 100644 --- a/net/ipv6/netfilter/ip6_tables.c +++ b/net/ipv6/netfilter/ip6_tables.c | |||
@@ -105,9 +105,9 @@ ip6_packet_match(const struct sk_buff *skb, | |||
105 | #define FWINV(bool, invflg) ((bool) ^ !!(ip6info->invflags & (invflg))) | 105 | #define FWINV(bool, invflg) ((bool) ^ !!(ip6info->invflags & (invflg))) |
106 | 106 | ||
107 | if (FWINV(ipv6_masked_addr_cmp(&ipv6->saddr, &ip6info->smsk, | 107 | if (FWINV(ipv6_masked_addr_cmp(&ipv6->saddr, &ip6info->smsk, |
108 | &ip6info->src), IP6T_INV_SRCIP) | 108 | &ip6info->src), IP6T_INV_SRCIP) || |
109 | || FWINV(ipv6_masked_addr_cmp(&ipv6->daddr, &ip6info->dmsk, | 109 | FWINV(ipv6_masked_addr_cmp(&ipv6->daddr, &ip6info->dmsk, |
110 | &ip6info->dst), IP6T_INV_DSTIP)) { | 110 | &ip6info->dst), IP6T_INV_DSTIP)) { |
111 | dprintf("Source or dest mismatch.\n"); | 111 | dprintf("Source or dest mismatch.\n"); |
112 | /* | 112 | /* |
113 | dprintf("SRC: %u. Mask: %u. Target: %u.%s\n", ip->saddr, | 113 | dprintf("SRC: %u. Mask: %u. Target: %u.%s\n", ip->saddr, |
@@ -277,11 +277,11 @@ get_chainname_rulenum(struct ip6t_entry *s, struct ip6t_entry *e, | |||
277 | } else if (s == e) { | 277 | } else if (s == e) { |
278 | (*rulenum)++; | 278 | (*rulenum)++; |
279 | 279 | ||
280 | if (s->target_offset == sizeof(struct ip6t_entry) | 280 | if (s->target_offset == sizeof(struct ip6t_entry) && |
281 | && strcmp(t->target.u.kernel.target->name, | 281 | strcmp(t->target.u.kernel.target->name, |
282 | IP6T_STANDARD_TARGET) == 0 | 282 | IP6T_STANDARD_TARGET) == 0 && |
283 | && t->verdict < 0 | 283 | t->verdict < 0 && |
284 | && unconditional(&s->ipv6)) { | 284 | unconditional(&s->ipv6)) { |
285 | /* Tail of chains: STANDARD target (return/policy) */ | 285 | /* Tail of chains: STANDARD target (return/policy) */ |
286 | *comment = *chainname == hookname | 286 | *comment = *chainname == hookname |
287 | ? comments[NF_IP6_TRACE_COMMENT_POLICY] | 287 | ? comments[NF_IP6_TRACE_COMMENT_POLICY] |
@@ -418,8 +418,8 @@ ip6t_do_table(struct sk_buff *skb, | |||
418 | back = get_entry(table_base, back->comefrom); | 418 | back = get_entry(table_base, back->comefrom); |
419 | continue; | 419 | continue; |
420 | } | 420 | } |
421 | if (table_base + v != ip6t_next_entry(e) | 421 | if (table_base + v != ip6t_next_entry(e) && |
422 | && !(e->ipv6.flags & IP6T_F_GOTO)) { | 422 | !(e->ipv6.flags & IP6T_F_GOTO)) { |
423 | /* Save old back ptr in next entry */ | 423 | /* Save old back ptr in next entry */ |
424 | struct ip6t_entry *next = ip6t_next_entry(e); | 424 | struct ip6t_entry *next = ip6t_next_entry(e); |
425 | next->comefrom = (void *)back - table_base; | 425 | next->comefrom = (void *)back - table_base; |
@@ -505,11 +505,11 @@ mark_source_chains(struct xt_table_info *newinfo, | |||
505 | e->comefrom |= ((1 << hook) | (1 << NF_INET_NUMHOOKS)); | 505 | e->comefrom |= ((1 << hook) | (1 << NF_INET_NUMHOOKS)); |
506 | 506 | ||
507 | /* Unconditional return/END. */ | 507 | /* Unconditional return/END. */ |
508 | if ((e->target_offset == sizeof(struct ip6t_entry) | 508 | if ((e->target_offset == sizeof(struct ip6t_entry) && |
509 | && (strcmp(t->target.u.user.name, | 509 | (strcmp(t->target.u.user.name, |
510 | IP6T_STANDARD_TARGET) == 0) | 510 | IP6T_STANDARD_TARGET) == 0) && |
511 | && t->verdict < 0 | 511 | t->verdict < 0 && |
512 | && unconditional(&e->ipv6)) || visited) { | 512 | unconditional(&e->ipv6)) || visited) { |
513 | unsigned int oldpos, size; | 513 | unsigned int oldpos, size; |
514 | 514 | ||
515 | if ((strcmp(t->target.u.user.name, | 515 | if ((strcmp(t->target.u.user.name, |
@@ -556,8 +556,8 @@ mark_source_chains(struct xt_table_info *newinfo, | |||
556 | int newpos = t->verdict; | 556 | int newpos = t->verdict; |
557 | 557 | ||
558 | if (strcmp(t->target.u.user.name, | 558 | if (strcmp(t->target.u.user.name, |
559 | IP6T_STANDARD_TARGET) == 0 | 559 | IP6T_STANDARD_TARGET) == 0 && |
560 | && newpos >= 0) { | 560 | newpos >= 0) { |
561 | if (newpos > newinfo->size - | 561 | if (newpos > newinfo->size - |
562 | sizeof(struct ip6t_entry)) { | 562 | sizeof(struct ip6t_entry)) { |
563 | duprintf("mark_source_chains: " | 563 | duprintf("mark_source_chains: " |
@@ -767,8 +767,8 @@ check_entry_size_and_hooks(struct ip6t_entry *e, | |||
767 | { | 767 | { |
768 | unsigned int h; | 768 | unsigned int h; |
769 | 769 | ||
770 | if ((unsigned long)e % __alignof__(struct ip6t_entry) != 0 | 770 | if ((unsigned long)e % __alignof__(struct ip6t_entry) != 0 || |
771 | || (unsigned char *)e + sizeof(struct ip6t_entry) >= limit) { | 771 | (unsigned char *)e + sizeof(struct ip6t_entry) >= limit) { |
772 | duprintf("Bad offset %p\n", e); | 772 | duprintf("Bad offset %p\n", e); |
773 | return -EINVAL; | 773 | return -EINVAL; |
774 | } | 774 | } |
@@ -1584,8 +1584,8 @@ check_compat_entry_size_and_hooks(struct compat_ip6t_entry *e, | |||
1584 | int ret, off, h; | 1584 | int ret, off, h; |
1585 | 1585 | ||
1586 | duprintf("check_compat_entry_size_and_hooks %p\n", e); | 1586 | duprintf("check_compat_entry_size_and_hooks %p\n", e); |
1587 | if ((unsigned long)e % __alignof__(struct compat_ip6t_entry) != 0 | 1587 | if ((unsigned long)e % __alignof__(struct compat_ip6t_entry) != 0 || |
1588 | || (unsigned char *)e + sizeof(struct compat_ip6t_entry) >= limit) { | 1588 | (unsigned char *)e + sizeof(struct compat_ip6t_entry) >= limit) { |
1589 | duprintf("Bad offset %p, limit = %p\n", e, limit); | 1589 | duprintf("Bad offset %p, limit = %p\n", e, limit); |
1590 | return -EINVAL; | 1590 | return -EINVAL; |
1591 | } | 1591 | } |
diff --git a/net/ipv6/netfilter/ip6t_LOG.c b/net/ipv6/netfilter/ip6t_LOG.c index 7018cac4fddc..b285fdf19050 100644 --- a/net/ipv6/netfilter/ip6t_LOG.c +++ b/net/ipv6/netfilter/ip6t_LOG.c | |||
@@ -249,8 +249,8 @@ static void dump_packet(const struct nf_loginfo *info, | |||
249 | /* Max length: 11 "URGP=65535 " */ | 249 | /* Max length: 11 "URGP=65535 " */ |
250 | printk("URGP=%u ", ntohs(th->urg_ptr)); | 250 | printk("URGP=%u ", ntohs(th->urg_ptr)); |
251 | 251 | ||
252 | if ((logflags & IP6T_LOG_TCPOPT) | 252 | if ((logflags & IP6T_LOG_TCPOPT) && |
253 | && th->doff * 4 > sizeof(struct tcphdr)) { | 253 | th->doff * 4 > sizeof(struct tcphdr)) { |
254 | u_int8_t _opt[60 - sizeof(struct tcphdr)]; | 254 | u_int8_t _opt[60 - sizeof(struct tcphdr)]; |
255 | const u_int8_t *op; | 255 | const u_int8_t *op; |
256 | unsigned int i; | 256 | unsigned int i; |
diff --git a/net/ipv6/netfilter/ip6t_REJECT.c b/net/ipv6/netfilter/ip6t_REJECT.c index 5a7f00cd15ce..8311ca31816a 100644 --- a/net/ipv6/netfilter/ip6t_REJECT.c +++ b/net/ipv6/netfilter/ip6t_REJECT.c | |||
@@ -223,8 +223,8 @@ static bool reject_tg6_check(const struct xt_tgchk_param *par) | |||
223 | return false; | 223 | return false; |
224 | } else if (rejinfo->with == IP6T_TCP_RESET) { | 224 | } else if (rejinfo->with == IP6T_TCP_RESET) { |
225 | /* Must specify that it's a TCP packet */ | 225 | /* Must specify that it's a TCP packet */ |
226 | if (e->ipv6.proto != IPPROTO_TCP | 226 | if (e->ipv6.proto != IPPROTO_TCP || |
227 | || (e->ipv6.invflags & XT_INV_PROTO)) { | 227 | (e->ipv6.invflags & XT_INV_PROTO)) { |
228 | printk("ip6t_REJECT: TCP_RESET illegal for non-tcp\n"); | 228 | printk("ip6t_REJECT: TCP_RESET illegal for non-tcp\n"); |
229 | return false; | 229 | return false; |
230 | } | 230 | } |
diff --git a/net/ipv6/netfilter/ip6t_ah.c b/net/ipv6/netfilter/ip6t_ah.c index 3a82f24746b9..ac0b7c629d78 100644 --- a/net/ipv6/netfilter/ip6t_ah.c +++ b/net/ipv6/netfilter/ip6t_ah.c | |||
@@ -77,17 +77,14 @@ static bool ah_mt6(const struct sk_buff *skb, const struct xt_match_param *par) | |||
77 | ahinfo->hdrres, ah->reserved, | 77 | ahinfo->hdrres, ah->reserved, |
78 | !(ahinfo->hdrres && ah->reserved)); | 78 | !(ahinfo->hdrres && ah->reserved)); |
79 | 79 | ||
80 | return (ah != NULL) | 80 | return (ah != NULL) && |
81 | && | 81 | spi_match(ahinfo->spis[0], ahinfo->spis[1], |
82 | spi_match(ahinfo->spis[0], ahinfo->spis[1], | 82 | ntohl(ah->spi), |
83 | ntohl(ah->spi), | 83 | !!(ahinfo->invflags & IP6T_AH_INV_SPI)) && |
84 | !!(ahinfo->invflags & IP6T_AH_INV_SPI)) | 84 | (!ahinfo->hdrlen || |
85 | && | 85 | (ahinfo->hdrlen == hdrlen) ^ |
86 | (!ahinfo->hdrlen || | 86 | !!(ahinfo->invflags & IP6T_AH_INV_LEN)) && |
87 | (ahinfo->hdrlen == hdrlen) ^ | 87 | !(ahinfo->hdrres && ah->reserved); |
88 | !!(ahinfo->invflags & IP6T_AH_INV_LEN)) | ||
89 | && | ||
90 | !(ahinfo->hdrres && ah->reserved); | ||
91 | } | 88 | } |
92 | 89 | ||
93 | static bool ah_mt6_check(const struct xt_mtchk_param *par) | 90 | static bool ah_mt6_check(const struct xt_mtchk_param *par) |
diff --git a/net/ipv6/netfilter/ip6t_frag.c b/net/ipv6/netfilter/ip6t_frag.c index 673aa0a5084e..7b91c2598ed5 100644 --- a/net/ipv6/netfilter/ip6t_frag.c +++ b/net/ipv6/netfilter/ip6t_frag.c | |||
@@ -70,41 +70,36 @@ frag_mt6(const struct sk_buff *skb, const struct xt_match_param *par) | |||
70 | pr_debug("res %02X %02X%04X %02X ", | 70 | pr_debug("res %02X %02X%04X %02X ", |
71 | fraginfo->flags & IP6T_FRAG_RES, fh->reserved, | 71 | fraginfo->flags & IP6T_FRAG_RES, fh->reserved, |
72 | ntohs(fh->frag_off) & 0x6, | 72 | ntohs(fh->frag_off) & 0x6, |
73 | !((fraginfo->flags & IP6T_FRAG_RES) | 73 | !((fraginfo->flags & IP6T_FRAG_RES) && |
74 | && (fh->reserved || (ntohs(fh->frag_off) & 0x06)))); | 74 | (fh->reserved || (ntohs(fh->frag_off) & 0x06)))); |
75 | pr_debug("first %02X %02X %02X ", | 75 | pr_debug("first %02X %02X %02X ", |
76 | fraginfo->flags & IP6T_FRAG_FST, | 76 | fraginfo->flags & IP6T_FRAG_FST, |
77 | ntohs(fh->frag_off) & ~0x7, | 77 | ntohs(fh->frag_off) & ~0x7, |
78 | !((fraginfo->flags & IP6T_FRAG_FST) | 78 | !((fraginfo->flags & IP6T_FRAG_FST) && |
79 | && (ntohs(fh->frag_off) & ~0x7))); | 79 | (ntohs(fh->frag_off) & ~0x7))); |
80 | pr_debug("mf %02X %02X %02X ", | 80 | pr_debug("mf %02X %02X %02X ", |
81 | fraginfo->flags & IP6T_FRAG_MF, | 81 | fraginfo->flags & IP6T_FRAG_MF, |
82 | ntohs(fh->frag_off) & IP6_MF, | 82 | ntohs(fh->frag_off) & IP6_MF, |
83 | !((fraginfo->flags & IP6T_FRAG_MF) | 83 | !((fraginfo->flags & IP6T_FRAG_MF) && |
84 | && !((ntohs(fh->frag_off) & IP6_MF)))); | 84 | !((ntohs(fh->frag_off) & IP6_MF)))); |
85 | pr_debug("last %02X %02X %02X\n", | 85 | pr_debug("last %02X %02X %02X\n", |
86 | fraginfo->flags & IP6T_FRAG_NMF, | 86 | fraginfo->flags & IP6T_FRAG_NMF, |
87 | ntohs(fh->frag_off) & IP6_MF, | 87 | ntohs(fh->frag_off) & IP6_MF, |
88 | !((fraginfo->flags & IP6T_FRAG_NMF) | 88 | !((fraginfo->flags & IP6T_FRAG_NMF) && |
89 | && (ntohs(fh->frag_off) & IP6_MF))); | 89 | (ntohs(fh->frag_off) & IP6_MF))); |
90 | 90 | ||
91 | return (fh != NULL) | 91 | return (fh != NULL) && |
92 | && | 92 | id_match(fraginfo->ids[0], fraginfo->ids[1], |
93 | id_match(fraginfo->ids[0], fraginfo->ids[1], | 93 | ntohl(fh->identification), |
94 | ntohl(fh->identification), | 94 | !!(fraginfo->invflags & IP6T_FRAG_INV_IDS)) && |
95 | !!(fraginfo->invflags & IP6T_FRAG_INV_IDS)) | 95 | !((fraginfo->flags & IP6T_FRAG_RES) && |
96 | && | 96 | (fh->reserved || (ntohs(fh->frag_off) & 0x6))) && |
97 | !((fraginfo->flags & IP6T_FRAG_RES) | 97 | !((fraginfo->flags & IP6T_FRAG_FST) && |
98 | && (fh->reserved || (ntohs(fh->frag_off) & 0x6))) | 98 | (ntohs(fh->frag_off) & ~0x7)) && |
99 | && | 99 | !((fraginfo->flags & IP6T_FRAG_MF) && |
100 | !((fraginfo->flags & IP6T_FRAG_FST) | 100 | !(ntohs(fh->frag_off) & IP6_MF)) && |
101 | && (ntohs(fh->frag_off) & ~0x7)) | 101 | !((fraginfo->flags & IP6T_FRAG_NMF) && |
102 | && | 102 | (ntohs(fh->frag_off) & IP6_MF)); |
103 | !((fraginfo->flags & IP6T_FRAG_MF) | ||
104 | && !(ntohs(fh->frag_off) & IP6_MF)) | ||
105 | && | ||
106 | !((fraginfo->flags & IP6T_FRAG_NMF) | ||
107 | && (ntohs(fh->frag_off) & IP6_MF)); | ||
108 | } | 103 | } |
109 | 104 | ||
110 | static bool frag_mt6_check(const struct xt_mtchk_param *par) | 105 | static bool frag_mt6_check(const struct xt_mtchk_param *par) |
diff --git a/net/ipv6/netfilter/ip6t_rt.c b/net/ipv6/netfilter/ip6t_rt.c index 356b8d6f6baa..b77307fc8743 100644 --- a/net/ipv6/netfilter/ip6t_rt.c +++ b/net/ipv6/netfilter/ip6t_rt.c | |||
@@ -92,16 +92,13 @@ static bool rt_mt6(const struct sk_buff *skb, const struct xt_match_param *par) | |||
92 | !((rtinfo->flags & IP6T_RT_RES) && | 92 | !((rtinfo->flags & IP6T_RT_RES) && |
93 | (((const struct rt0_hdr *)rh)->reserved))); | 93 | (((const struct rt0_hdr *)rh)->reserved))); |
94 | 94 | ||
95 | ret = (rh != NULL) | 95 | ret = (rh != NULL) && |
96 | && | ||
97 | (segsleft_match(rtinfo->segsleft[0], rtinfo->segsleft[1], | 96 | (segsleft_match(rtinfo->segsleft[0], rtinfo->segsleft[1], |
98 | rh->segments_left, | 97 | rh->segments_left, |
99 | !!(rtinfo->invflags & IP6T_RT_INV_SGS))) | 98 | !!(rtinfo->invflags & IP6T_RT_INV_SGS))) && |
100 | && | ||
101 | (!(rtinfo->flags & IP6T_RT_LEN) || | 99 | (!(rtinfo->flags & IP6T_RT_LEN) || |
102 | ((rtinfo->hdrlen == hdrlen) ^ | 100 | ((rtinfo->hdrlen == hdrlen) ^ |
103 | !!(rtinfo->invflags & IP6T_RT_INV_LEN))) | 101 | !!(rtinfo->invflags & IP6T_RT_INV_LEN))) && |
104 | && | ||
105 | (!(rtinfo->flags & IP6T_RT_TYP) || | 102 | (!(rtinfo->flags & IP6T_RT_TYP) || |
106 | ((rtinfo->rt_type == rh->type) ^ | 103 | ((rtinfo->rt_type == rh->type) ^ |
107 | !!(rtinfo->invflags & IP6T_RT_INV_TYP))); | 104 | !!(rtinfo->invflags & IP6T_RT_INV_TYP))); |
diff --git a/net/ipv6/netfilter/ip6table_filter.c b/net/ipv6/netfilter/ip6table_filter.c index 6f4383ad86f9..ad378efd0eb8 100644 --- a/net/ipv6/netfilter/ip6table_filter.c +++ b/net/ipv6/netfilter/ip6table_filter.c | |||
@@ -79,8 +79,8 @@ ip6t_local_out_hook(unsigned int hook, | |||
79 | { | 79 | { |
80 | #if 0 | 80 | #if 0 |
81 | /* root is playing with raw sockets. */ | 81 | /* root is playing with raw sockets. */ |
82 | if (skb->len < sizeof(struct iphdr) | 82 | if (skb->len < sizeof(struct iphdr) || |
83 | || ip_hdrlen(skb) < sizeof(struct iphdr)) { | 83 | ip_hdrlen(skb) < sizeof(struct iphdr)) { |
84 | if (net_ratelimit()) | 84 | if (net_ratelimit()) |
85 | printk("ip6t_hook: happy cracking.\n"); | 85 | printk("ip6t_hook: happy cracking.\n"); |
86 | return NF_ACCEPT; | 86 | return NF_ACCEPT; |
diff --git a/net/ipv6/netfilter/ip6table_mangle.c b/net/ipv6/netfilter/ip6table_mangle.c index 0ad91433ed61..a929c19d30e3 100644 --- a/net/ipv6/netfilter/ip6table_mangle.c +++ b/net/ipv6/netfilter/ip6table_mangle.c | |||
@@ -102,8 +102,8 @@ ip6t_local_out_hook(unsigned int hook, | |||
102 | 102 | ||
103 | #if 0 | 103 | #if 0 |
104 | /* root is playing with raw sockets. */ | 104 | /* root is playing with raw sockets. */ |
105 | if (skb->len < sizeof(struct iphdr) | 105 | if (skb->len < sizeof(struct iphdr) || |
106 | || ip_hdrlen(skb) < sizeof(struct iphdr)) { | 106 | ip_hdrlen(skb) < sizeof(struct iphdr)) { |
107 | if (net_ratelimit()) | 107 | if (net_ratelimit()) |
108 | printk("ip6t_hook: happy cracking.\n"); | 108 | printk("ip6t_hook: happy cracking.\n"); |
109 | return NF_ACCEPT; | 109 | return NF_ACCEPT; |
@@ -122,11 +122,11 @@ ip6t_local_out_hook(unsigned int hook, | |||
122 | ret = ip6t_do_table(skb, hook, in, out, | 122 | ret = ip6t_do_table(skb, hook, in, out, |
123 | dev_net(out)->ipv6.ip6table_mangle); | 123 | dev_net(out)->ipv6.ip6table_mangle); |
124 | 124 | ||
125 | if (ret != NF_DROP && ret != NF_STOLEN | 125 | if (ret != NF_DROP && ret != NF_STOLEN && |
126 | && (memcmp(&ipv6_hdr(skb)->saddr, &saddr, sizeof(saddr)) | 126 | (memcmp(&ipv6_hdr(skb)->saddr, &saddr, sizeof(saddr)) || |
127 | || memcmp(&ipv6_hdr(skb)->daddr, &daddr, sizeof(daddr)) | 127 | memcmp(&ipv6_hdr(skb)->daddr, &daddr, sizeof(daddr)) || |
128 | || skb->mark != mark | 128 | skb->mark != mark || |
129 | || ipv6_hdr(skb)->hop_limit != hop_limit)) | 129 | ipv6_hdr(skb)->hop_limit != hop_limit)) |
130 | return ip6_route_me_harder(skb) == 0 ? ret : NF_DROP; | 130 | return ip6_route_me_harder(skb) == 0 ? ret : NF_DROP; |
131 | 131 | ||
132 | return ret; | 132 | return ret; |
diff --git a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c index 642dcb127bab..0f3df45718ac 100644 --- a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c +++ b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c | |||
@@ -244,18 +244,18 @@ static const struct nla_policy icmpv6_nla_policy[CTA_PROTO_MAX+1] = { | |||
244 | static int icmpv6_nlattr_to_tuple(struct nlattr *tb[], | 244 | static int icmpv6_nlattr_to_tuple(struct nlattr *tb[], |
245 | struct nf_conntrack_tuple *tuple) | 245 | struct nf_conntrack_tuple *tuple) |
246 | { | 246 | { |
247 | if (!tb[CTA_PROTO_ICMPV6_TYPE] | 247 | if (!tb[CTA_PROTO_ICMPV6_TYPE] || |
248 | || !tb[CTA_PROTO_ICMPV6_CODE] | 248 | !tb[CTA_PROTO_ICMPV6_CODE] || |
249 | || !tb[CTA_PROTO_ICMPV6_ID]) | 249 | !tb[CTA_PROTO_ICMPV6_ID]) |
250 | return -EINVAL; | 250 | return -EINVAL; |
251 | 251 | ||
252 | tuple->dst.u.icmp.type = nla_get_u8(tb[CTA_PROTO_ICMPV6_TYPE]); | 252 | tuple->dst.u.icmp.type = nla_get_u8(tb[CTA_PROTO_ICMPV6_TYPE]); |
253 | tuple->dst.u.icmp.code = nla_get_u8(tb[CTA_PROTO_ICMPV6_CODE]); | 253 | tuple->dst.u.icmp.code = nla_get_u8(tb[CTA_PROTO_ICMPV6_CODE]); |
254 | tuple->src.u.icmp.id = nla_get_be16(tb[CTA_PROTO_ICMPV6_ID]); | 254 | tuple->src.u.icmp.id = nla_get_be16(tb[CTA_PROTO_ICMPV6_ID]); |
255 | 255 | ||
256 | if (tuple->dst.u.icmp.type < 128 | 256 | if (tuple->dst.u.icmp.type < 128 || |
257 | || tuple->dst.u.icmp.type - 128 >= sizeof(invmap) | 257 | tuple->dst.u.icmp.type - 128 >= sizeof(invmap) || |
258 | || !invmap[tuple->dst.u.icmp.type - 128]) | 258 | !invmap[tuple->dst.u.icmp.type - 128]) |
259 | return -EINVAL; | 259 | return -EINVAL; |
260 | 260 | ||
261 | return 0; | 261 | return 0; |