aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/ipv4/netfilter/arp_tables.c22
-rw-r--r--net/ipv4/netfilter/ip_tables.c46
-rw-r--r--net/ipv4/netfilter/ipt_CLUSTERIP.c20
-rw-r--r--net/ipv4/netfilter/ipt_ECN.c8
-rw-r--r--net/ipv4/netfilter/ipt_LOG.c22
-rw-r--r--net/ipv4/netfilter/ipt_MASQUERADE.c4
-rw-r--r--net/ipv4/netfilter/ipt_REJECT.c4
-rw-r--r--net/ipv4/netfilter/ipt_ULOG.c6
-rw-r--r--net/ipv4/netfilter/ipt_ecn.c4
-rw-r--r--net/ipv4/netfilter/iptable_mangle.c4
-rw-r--r--net/ipv4/netfilter/iptable_security.c4
-rw-r--r--net/ipv4/netfilter/nf_conntrack_proto_icmp.c28
-rw-r--r--net/ipv4/netfilter/nf_nat_standalone.c10
-rw-r--r--net/ipv6/netfilter/ip6_tables.c42
-rw-r--r--net/ipv6/netfilter/ip6t_LOG.c4
-rw-r--r--net/ipv6/netfilter/ip6t_REJECT.c4
-rw-r--r--net/ipv6/netfilter/ip6t_ah.c19
-rw-r--r--net/ipv6/netfilter/ip6t_frag.c47
-rw-r--r--net/ipv6/netfilter/ip6t_rt.c9
-rw-r--r--net/ipv6/netfilter/ip6table_filter.c4
-rw-r--r--net/ipv6/netfilter/ip6table_mangle.c14
-rw-r--r--net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c12
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[] = {
54static bool icmp_invert_tuple(struct nf_conntrack_tuple *tuple, 54static 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] = {
238static int icmp_nlattr_to_tuple(struct nlattr *tb[], 238static 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
93static bool ah_mt6_check(const struct xt_mtchk_param *par) 90static 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
110static bool frag_mt6_check(const struct xt_mtchk_param *par) 105static 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] = {
244static int icmpv6_nlattr_to_tuple(struct nlattr *tb[], 244static 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;