aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/netfilter/nf_conntrack_tcp.h3
-rw-r--r--net/ipv4/netfilter/arp_tables.c22
-rw-r--r--net/ipv4/netfilter/ip_queue.c5
-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_helper.c22
-rw-r--r--net/ipv4/netfilter/nf_nat_standalone.c10
-rw-r--r--net/ipv6/netfilter/ip6_queue.c5
-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
-rw-r--r--net/netfilter/nf_conntrack_core.c14
-rw-r--r--net/netfilter/nf_conntrack_proto_tcp.c51
-rw-r--r--net/netfilter/nfnetlink_log.c3
-rw-r--r--net/netfilter/nfnetlink_queue.c3
-rw-r--r--net/netfilter/xt_conntrack.c61
-rw-r--r--net/netfilter/xt_socket.c6
32 files changed, 253 insertions, 257 deletions
diff --git a/include/linux/netfilter/nf_conntrack_tcp.h b/include/linux/netfilter/nf_conntrack_tcp.h
index f6d97f64d7a0..6e135f97e59a 100644
--- a/include/linux/netfilter/nf_conntrack_tcp.h
+++ b/include/linux/netfilter/nf_conntrack_tcp.h
@@ -66,6 +66,9 @@ struct ip_ct_tcp {
66 u_int32_t last_ack; /* Last sequence number seen in opposite dir */ 66 u_int32_t last_ack; /* Last sequence number seen in opposite dir */
67 u_int32_t last_end; /* Last seq + len */ 67 u_int32_t last_end; /* Last seq + len */
68 u_int16_t last_win; /* Last window advertisement seen in dir */ 68 u_int16_t last_win; /* Last window advertisement seen in dir */
69 /* For SYN packets while we may be out-of-sync */
70 u_int8_t last_wscale; /* Last window scaling factor seen */
71 u_int8_t last_flags; /* Last flags set */
69}; 72};
70 73
71#endif /* __KERNEL__ */ 74#endif /* __KERNEL__ */
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_queue.c b/net/ipv4/netfilter/ip_queue.c
index 884f0859cb3b..49ad44712f46 100644
--- a/net/ipv4/netfilter/ip_queue.c
+++ b/net/ipv4/netfilter/ip_queue.c
@@ -497,8 +497,7 @@ ipq_rcv_nl_event(struct notifier_block *this,
497{ 497{
498 struct netlink_notify *n = ptr; 498 struct netlink_notify *n = ptr;
499 499
500 if (event == NETLINK_URELEASE && 500 if (event == NETLINK_URELEASE && n->protocol == NETLINK_FIREWALL) {
501 n->protocol == NETLINK_FIREWALL && n->pid) {
502 write_lock_bh(&queue_lock); 501 write_lock_bh(&queue_lock);
503 if ((net_eq(n->net, &init_net)) && (n->pid == peer_pid)) 502 if ((net_eq(n->net, &init_net)) && (n->pid == peer_pid))
504 __ipq_reset(); 503 __ipq_reset();
@@ -622,7 +621,7 @@ cleanup_netlink_notifier:
622static void __exit ip_queue_fini(void) 621static void __exit ip_queue_fini(void)
623{ 622{
624 nf_unregister_queue_handlers(&nfqh); 623 nf_unregister_queue_handlers(&nfqh);
625 synchronize_net(); 624
626 ipq_flush(NULL, 0); 625 ipq_flush(NULL, 0);
627 626
628#ifdef CONFIG_SYSCTL 627#ifdef CONFIG_SYSCTL
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_helper.c b/net/ipv4/netfilter/nf_nat_helper.c
index f9520fa3aba9..7f10a6be0191 100644
--- a/net/ipv4/netfilter/nf_nat_helper.c
+++ b/net/ipv4/netfilter/nf_nat_helper.c
@@ -41,18 +41,14 @@ adjust_tcp_sequence(u32 seq,
41 struct nf_conn *ct, 41 struct nf_conn *ct,
42 enum ip_conntrack_info ctinfo) 42 enum ip_conntrack_info ctinfo)
43{ 43{
44 int dir; 44 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
45 struct nf_nat_seq *this_way, *other_way;
46 struct nf_conn_nat *nat = nfct_nat(ct); 45 struct nf_conn_nat *nat = nfct_nat(ct);
46 struct nf_nat_seq *this_way = &nat->seq[dir];
47 47
48 pr_debug("adjust_tcp_sequence: seq = %u, sizediff = %d\n", seq, seq); 48 pr_debug("adjust_tcp_sequence: seq = %u, sizediff = %d\n",
49 49 seq, sizediff);
50 dir = CTINFO2DIR(ctinfo);
51
52 this_way = &nat->seq[dir];
53 other_way = &nat->seq[!dir];
54 50
55 pr_debug("nf_nat_resize_packet: Seq_offset before: "); 51 pr_debug("adjust_tcp_sequence: Seq_offset before: ");
56 DUMP_OFFSET(this_way); 52 DUMP_OFFSET(this_way);
57 53
58 spin_lock_bh(&nf_nat_seqofs_lock); 54 spin_lock_bh(&nf_nat_seqofs_lock);
@@ -63,13 +59,13 @@ adjust_tcp_sequence(u32 seq,
63 * retransmit */ 59 * retransmit */
64 if (this_way->offset_before == this_way->offset_after || 60 if (this_way->offset_before == this_way->offset_after ||
65 before(this_way->correction_pos, seq)) { 61 before(this_way->correction_pos, seq)) {
66 this_way->correction_pos = seq; 62 this_way->correction_pos = seq;
67 this_way->offset_before = this_way->offset_after; 63 this_way->offset_before = this_way->offset_after;
68 this_way->offset_after += sizediff; 64 this_way->offset_after += sizediff;
69 } 65 }
70 spin_unlock_bh(&nf_nat_seqofs_lock); 66 spin_unlock_bh(&nf_nat_seqofs_lock);
71 67
72 pr_debug("nf_nat_resize_packet: Seq_offset after: "); 68 pr_debug("adjust_tcp_sequence: Seq_offset after: ");
73 DUMP_OFFSET(this_way); 69 DUMP_OFFSET(this_way);
74} 70}
75 71
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_queue.c b/net/ipv6/netfilter/ip6_queue.c
index 4c7a18abcaff..db4d5725cce8 100644
--- a/net/ipv6/netfilter/ip6_queue.c
+++ b/net/ipv6/netfilter/ip6_queue.c
@@ -499,8 +499,7 @@ ipq_rcv_nl_event(struct notifier_block *this,
499{ 499{
500 struct netlink_notify *n = ptr; 500 struct netlink_notify *n = ptr;
501 501
502 if (event == NETLINK_URELEASE && 502 if (event == NETLINK_URELEASE && n->protocol == NETLINK_IP6_FW) {
503 n->protocol == NETLINK_IP6_FW && n->pid) {
504 write_lock_bh(&queue_lock); 503 write_lock_bh(&queue_lock);
505 if ((net_eq(n->net, &init_net)) && (n->pid == peer_pid)) 504 if ((net_eq(n->net, &init_net)) && (n->pid == peer_pid))
506 __ipq_reset(); 505 __ipq_reset();
@@ -625,7 +624,7 @@ cleanup_netlink_notifier:
625static void __exit ip6_queue_fini(void) 624static void __exit ip6_queue_fini(void)
626{ 625{
627 nf_unregister_queue_handlers(&nfqh); 626 nf_unregister_queue_handlers(&nfqh);
628 synchronize_net(); 627
629 ipq_flush(NULL, 0); 628 ipq_flush(NULL, 0);
630 629
631#ifdef CONFIG_SYSCTL 630#ifdef CONFIG_SYSCTL
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;
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index b9168c1864ca..0e98c3282d42 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -512,11 +512,17 @@ static noinline int early_drop(struct net *net, unsigned int hash)
512 cnt++; 512 cnt++;
513 } 513 }
514 514
515 if (ct && unlikely(nf_ct_is_dying(ct) || 515 if (ct != NULL) {
516 !atomic_inc_not_zero(&ct->ct_general.use))) 516 if (likely(!nf_ct_is_dying(ct) &&
517 ct = NULL; 517 atomic_inc_not_zero(&ct->ct_general.use)))
518 if (ct || cnt >= NF_CT_EVICTION_RANGE) 518 break;
519 else
520 ct = NULL;
521 }
522
523 if (cnt >= NF_CT_EVICTION_RANGE)
519 break; 524 break;
525
520 hash = (hash + 1) % nf_conntrack_htable_size; 526 hash = (hash + 1) % nf_conntrack_htable_size;
521 } 527 }
522 rcu_read_unlock(); 528 rcu_read_unlock();
diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c
index ba2b76937283..37a8c74be619 100644
--- a/net/netfilter/nf_conntrack_proto_tcp.c
+++ b/net/netfilter/nf_conntrack_proto_tcp.c
@@ -896,23 +896,54 @@ static int tcp_packet(struct nf_conn *ct,
896 /* b) This SYN/ACK acknowledges a SYN that we earlier 896 /* b) This SYN/ACK acknowledges a SYN that we earlier
897 * ignored as invalid. This means that the client and 897 * ignored as invalid. This means that the client and
898 * the server are both in sync, while the firewall is 898 * the server are both in sync, while the firewall is
899 * not. We kill this session and block the SYN/ACK so 899 * not. We get in sync from the previously annotated
900 * that the client cannot but retransmit its SYN and 900 * values.
901 * thus initiate a clean new session.
902 */ 901 */
903 spin_unlock_bh(&ct->lock); 902 old_state = TCP_CONNTRACK_SYN_SENT;
904 if (LOG_INVALID(net, IPPROTO_TCP)) 903 new_state = TCP_CONNTRACK_SYN_RECV;
905 nf_log_packet(pf, 0, skb, NULL, NULL, NULL, 904 ct->proto.tcp.seen[ct->proto.tcp.last_dir].td_end =
906 "nf_ct_tcp: killing out of sync session "); 905 ct->proto.tcp.last_end;
907 nf_ct_kill(ct); 906 ct->proto.tcp.seen[ct->proto.tcp.last_dir].td_maxend =
908 return NF_DROP; 907 ct->proto.tcp.last_end;
908 ct->proto.tcp.seen[ct->proto.tcp.last_dir].td_maxwin =
909 ct->proto.tcp.last_win == 0 ?
910 1 : ct->proto.tcp.last_win;
911 ct->proto.tcp.seen[ct->proto.tcp.last_dir].td_scale =
912 ct->proto.tcp.last_wscale;
913 ct->proto.tcp.seen[ct->proto.tcp.last_dir].flags =
914 ct->proto.tcp.last_flags;
915 memset(&ct->proto.tcp.seen[dir], 0,
916 sizeof(struct ip_ct_tcp_state));
917 break;
909 } 918 }
910 ct->proto.tcp.last_index = index; 919 ct->proto.tcp.last_index = index;
911 ct->proto.tcp.last_dir = dir; 920 ct->proto.tcp.last_dir = dir;
912 ct->proto.tcp.last_seq = ntohl(th->seq); 921 ct->proto.tcp.last_seq = ntohl(th->seq);
913 ct->proto.tcp.last_end = 922 ct->proto.tcp.last_end =
914 segment_seq_plus_len(ntohl(th->seq), skb->len, dataoff, th); 923 segment_seq_plus_len(ntohl(th->seq), skb->len, dataoff, th);
915 924 ct->proto.tcp.last_win = ntohs(th->window);
925
926 /* a) This is a SYN in ORIGINAL. The client and the server
927 * may be in sync but we are not. In that case, we annotate
928 * the TCP options and let the packet go through. If it is a
929 * valid SYN packet, the server will reply with a SYN/ACK, and
930 * then we'll get in sync. Otherwise, the server ignores it. */
931 if (index == TCP_SYN_SET && dir == IP_CT_DIR_ORIGINAL) {
932 struct ip_ct_tcp_state seen = {};
933
934 ct->proto.tcp.last_flags =
935 ct->proto.tcp.last_wscale = 0;
936 tcp_options(skb, dataoff, th, &seen);
937 if (seen.flags & IP_CT_TCP_FLAG_WINDOW_SCALE) {
938 ct->proto.tcp.last_flags |=
939 IP_CT_TCP_FLAG_WINDOW_SCALE;
940 ct->proto.tcp.last_wscale = seen.td_scale;
941 }
942 if (seen.flags & IP_CT_TCP_FLAG_SACK_PERM) {
943 ct->proto.tcp.last_flags |=
944 IP_CT_TCP_FLAG_SACK_PERM;
945 }
946 }
916 spin_unlock_bh(&ct->lock); 947 spin_unlock_bh(&ct->lock);
917 if (LOG_INVALID(net, IPPROTO_TCP)) 948 if (LOG_INVALID(net, IPPROTO_TCP))
918 nf_log_packet(pf, 0, skb, NULL, NULL, NULL, 949 nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c
index 49005482e39a..9de0470d557e 100644
--- a/net/netfilter/nfnetlink_log.c
+++ b/net/netfilter/nfnetlink_log.c
@@ -666,8 +666,7 @@ nfulnl_rcv_nl_event(struct notifier_block *this,
666{ 666{
667 struct netlink_notify *n = ptr; 667 struct netlink_notify *n = ptr;
668 668
669 if (event == NETLINK_URELEASE && 669 if (event == NETLINK_URELEASE && n->protocol == NETLINK_NETFILTER) {
670 n->protocol == NETLINK_NETFILTER && n->pid) {
671 int i; 670 int i;
672 671
673 /* destroy all instances for this pid */ 672 /* destroy all instances for this pid */
diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c
index 7a9dec9fb822..7e3fa410641e 100644
--- a/net/netfilter/nfnetlink_queue.c
+++ b/net/netfilter/nfnetlink_queue.c
@@ -574,8 +574,7 @@ nfqnl_rcv_nl_event(struct notifier_block *this,
574{ 574{
575 struct netlink_notify *n = ptr; 575 struct netlink_notify *n = ptr;
576 576
577 if (event == NETLINK_URELEASE && 577 if (event == NETLINK_URELEASE && n->protocol == NETLINK_NETFILTER) {
578 n->protocol == NETLINK_NETFILTER && n->pid) {
579 int i; 578 int i;
580 579
581 /* destroy all instances for this pid */ 580 /* destroy all instances for this pid */
diff --git a/net/netfilter/xt_conntrack.c b/net/netfilter/xt_conntrack.c
index 6dc4652f2fe8..ae66305f0fe5 100644
--- a/net/netfilter/xt_conntrack.c
+++ b/net/netfilter/xt_conntrack.c
@@ -113,7 +113,8 @@ ct_proto_port_check(const struct xt_conntrack_mtinfo2 *info,
113} 113}
114 114
115static bool 115static bool
116conntrack_mt(const struct sk_buff *skb, const struct xt_match_param *par) 116conntrack_mt(const struct sk_buff *skb, const struct xt_match_param *par,
117 u16 state_mask, u16 status_mask)
117{ 118{
118 const struct xt_conntrack_mtinfo2 *info = par->matchinfo; 119 const struct xt_conntrack_mtinfo2 *info = par->matchinfo;
119 enum ip_conntrack_info ctinfo; 120 enum ip_conntrack_info ctinfo;
@@ -136,7 +137,7 @@ conntrack_mt(const struct sk_buff *skb, const struct xt_match_param *par)
136 if (test_bit(IPS_DST_NAT_BIT, &ct->status)) 137 if (test_bit(IPS_DST_NAT_BIT, &ct->status))
137 statebit |= XT_CONNTRACK_STATE_DNAT; 138 statebit |= XT_CONNTRACK_STATE_DNAT;
138 } 139 }
139 if (!!(info->state_mask & statebit) ^ 140 if (!!(state_mask & statebit) ^
140 !(info->invert_flags & XT_CONNTRACK_STATE)) 141 !(info->invert_flags & XT_CONNTRACK_STATE))
141 return false; 142 return false;
142 } 143 }
@@ -172,7 +173,7 @@ conntrack_mt(const struct sk_buff *skb, const struct xt_match_param *par)
172 return false; 173 return false;
173 174
174 if ((info->match_flags & XT_CONNTRACK_STATUS) && 175 if ((info->match_flags & XT_CONNTRACK_STATUS) &&
175 (!!(info->status_mask & ct->status) ^ 176 (!!(status_mask & ct->status) ^
176 !(info->invert_flags & XT_CONNTRACK_STATUS))) 177 !(info->invert_flags & XT_CONNTRACK_STATUS)))
177 return false; 178 return false;
178 179
@@ -192,11 +193,17 @@ conntrack_mt(const struct sk_buff *skb, const struct xt_match_param *par)
192static bool 193static bool
193conntrack_mt_v1(const struct sk_buff *skb, const struct xt_match_param *par) 194conntrack_mt_v1(const struct sk_buff *skb, const struct xt_match_param *par)
194{ 195{
195 const struct xt_conntrack_mtinfo2 *const *info = par->matchinfo; 196 const struct xt_conntrack_mtinfo1 *info = par->matchinfo;
196 struct xt_match_param newpar = *par;
197 197
198 newpar.matchinfo = *info; 198 return conntrack_mt(skb, par, info->state_mask, info->status_mask);
199 return conntrack_mt(skb, &newpar); 199}
200
201static bool
202conntrack_mt_v2(const struct sk_buff *skb, const struct xt_match_param *par)
203{
204 const struct xt_conntrack_mtinfo2 *info = par->matchinfo;
205
206 return conntrack_mt(skb, par, info->state_mask, info->status_mask);
200} 207}
201 208
202static bool conntrack_mt_check(const struct xt_mtchk_param *par) 209static bool conntrack_mt_check(const struct xt_mtchk_param *par)
@@ -209,45 +216,11 @@ static bool conntrack_mt_check(const struct xt_mtchk_param *par)
209 return true; 216 return true;
210} 217}
211 218
212static bool conntrack_mt_check_v1(const struct xt_mtchk_param *par)
213{
214 struct xt_conntrack_mtinfo1 *info = par->matchinfo;
215 struct xt_conntrack_mtinfo2 *up;
216 int ret = conntrack_mt_check(par);
217
218 if (ret < 0)
219 return ret;
220
221 up = kmalloc(sizeof(*up), GFP_KERNEL);
222 if (up == NULL) {
223 nf_ct_l3proto_module_put(par->family);
224 return -ENOMEM;
225 }
226
227 /*
228 * The strategy here is to minimize the overhead of v1 matching,
229 * by prebuilding a v2 struct and putting the pointer into the
230 * v1 dataspace.
231 */
232 memcpy(up, info, offsetof(typeof(*info), state_mask));
233 up->state_mask = info->state_mask;
234 up->status_mask = info->status_mask;
235 *(void **)info = up;
236 return true;
237}
238
239static void conntrack_mt_destroy(const struct xt_mtdtor_param *par) 219static void conntrack_mt_destroy(const struct xt_mtdtor_param *par)
240{ 220{
241 nf_ct_l3proto_module_put(par->family); 221 nf_ct_l3proto_module_put(par->family);
242} 222}
243 223
244static void conntrack_mt_destroy_v1(const struct xt_mtdtor_param *par)
245{
246 struct xt_conntrack_mtinfo2 **info = par->matchinfo;
247 kfree(*info);
248 conntrack_mt_destroy(par);
249}
250
251static struct xt_match conntrack_mt_reg[] __read_mostly = { 224static struct xt_match conntrack_mt_reg[] __read_mostly = {
252 { 225 {
253 .name = "conntrack", 226 .name = "conntrack",
@@ -255,8 +228,8 @@ static struct xt_match conntrack_mt_reg[] __read_mostly = {
255 .family = NFPROTO_UNSPEC, 228 .family = NFPROTO_UNSPEC,
256 .matchsize = sizeof(struct xt_conntrack_mtinfo1), 229 .matchsize = sizeof(struct xt_conntrack_mtinfo1),
257 .match = conntrack_mt_v1, 230 .match = conntrack_mt_v1,
258 .checkentry = conntrack_mt_check_v1, 231 .checkentry = conntrack_mt_check,
259 .destroy = conntrack_mt_destroy_v1, 232 .destroy = conntrack_mt_destroy,
260 .me = THIS_MODULE, 233 .me = THIS_MODULE,
261 }, 234 },
262 { 235 {
@@ -264,7 +237,7 @@ static struct xt_match conntrack_mt_reg[] __read_mostly = {
264 .revision = 2, 237 .revision = 2,
265 .family = NFPROTO_UNSPEC, 238 .family = NFPROTO_UNSPEC,
266 .matchsize = sizeof(struct xt_conntrack_mtinfo2), 239 .matchsize = sizeof(struct xt_conntrack_mtinfo2),
267 .match = conntrack_mt, 240 .match = conntrack_mt_v2,
268 .checkentry = conntrack_mt_check, 241 .checkentry = conntrack_mt_check,
269 .destroy = conntrack_mt_destroy, 242 .destroy = conntrack_mt_destroy,
270 .me = THIS_MODULE, 243 .me = THIS_MODULE,
diff --git a/net/netfilter/xt_socket.c b/net/netfilter/xt_socket.c
index 362afbd60a96..6a902564d24f 100644
--- a/net/netfilter/xt_socket.c
+++ b/net/netfilter/xt_socket.c
@@ -192,7 +192,8 @@ static struct xt_match socket_mt_reg[] __read_mostly = {
192 .revision = 0, 192 .revision = 0,
193 .family = NFPROTO_IPV4, 193 .family = NFPROTO_IPV4,
194 .match = socket_mt_v0, 194 .match = socket_mt_v0,
195 .hooks = 1 << NF_INET_PRE_ROUTING, 195 .hooks = (1 << NF_INET_PRE_ROUTING) |
196 (1 << NF_INET_LOCAL_IN),
196 .me = THIS_MODULE, 197 .me = THIS_MODULE,
197 }, 198 },
198 { 199 {
@@ -201,7 +202,8 @@ static struct xt_match socket_mt_reg[] __read_mostly = {
201 .family = NFPROTO_IPV4, 202 .family = NFPROTO_IPV4,
202 .match = socket_mt_v1, 203 .match = socket_mt_v1,
203 .matchsize = sizeof(struct xt_socket_mtinfo1), 204 .matchsize = sizeof(struct xt_socket_mtinfo1),
204 .hooks = 1 << NF_INET_PRE_ROUTING, 205 .hooks = (1 << NF_INET_PRE_ROUTING) |
206 (1 << NF_INET_LOCAL_IN),
205 .me = THIS_MODULE, 207 .me = THIS_MODULE,
206 }, 208 },
207}; 209};