diff options
Diffstat (limited to 'net/ipv6')
-rw-r--r-- | net/ipv6/netfilter/ip6_queue.c | 5 | ||||
-rw-r--r-- | net/ipv6/netfilter/ip6_tables.c | 42 | ||||
-rw-r--r-- | net/ipv6/netfilter/ip6t_LOG.c | 4 | ||||
-rw-r--r-- | net/ipv6/netfilter/ip6t_REJECT.c | 4 | ||||
-rw-r--r-- | net/ipv6/netfilter/ip6t_ah.c | 19 | ||||
-rw-r--r-- | net/ipv6/netfilter/ip6t_frag.c | 47 | ||||
-rw-r--r-- | net/ipv6/netfilter/ip6t_rt.c | 9 | ||||
-rw-r--r-- | net/ipv6/netfilter/ip6table_filter.c | 4 | ||||
-rw-r--r-- | net/ipv6/netfilter/ip6table_mangle.c | 14 | ||||
-rw-r--r-- | net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c | 12 |
10 files changed, 74 insertions, 86 deletions
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: | |||
625 | static void __exit ip6_queue_fini(void) | 624 | static 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 | ||
93 | static bool ah_mt6_check(const struct xt_mtchk_param *par) | 90 | static bool ah_mt6_check(const struct xt_mtchk_param *par) |
diff --git a/net/ipv6/netfilter/ip6t_frag.c b/net/ipv6/netfilter/ip6t_frag.c index 673aa0a5084e..7b91c2598ed5 100644 --- a/net/ipv6/netfilter/ip6t_frag.c +++ b/net/ipv6/netfilter/ip6t_frag.c | |||
@@ -70,41 +70,36 @@ frag_mt6(const struct sk_buff *skb, const struct xt_match_param *par) | |||
70 | pr_debug("res %02X %02X%04X %02X ", | 70 | pr_debug("res %02X %02X%04X %02X ", |
71 | fraginfo->flags & IP6T_FRAG_RES, fh->reserved, | 71 | fraginfo->flags & IP6T_FRAG_RES, fh->reserved, |
72 | ntohs(fh->frag_off) & 0x6, | 72 | ntohs(fh->frag_off) & 0x6, |
73 | !((fraginfo->flags & IP6T_FRAG_RES) | 73 | !((fraginfo->flags & IP6T_FRAG_RES) && |
74 | && (fh->reserved || (ntohs(fh->frag_off) & 0x06)))); | 74 | (fh->reserved || (ntohs(fh->frag_off) & 0x06)))); |
75 | pr_debug("first %02X %02X %02X ", | 75 | pr_debug("first %02X %02X %02X ", |
76 | fraginfo->flags & IP6T_FRAG_FST, | 76 | fraginfo->flags & IP6T_FRAG_FST, |
77 | ntohs(fh->frag_off) & ~0x7, | 77 | ntohs(fh->frag_off) & ~0x7, |
78 | !((fraginfo->flags & IP6T_FRAG_FST) | 78 | !((fraginfo->flags & IP6T_FRAG_FST) && |
79 | && (ntohs(fh->frag_off) & ~0x7))); | 79 | (ntohs(fh->frag_off) & ~0x7))); |
80 | pr_debug("mf %02X %02X %02X ", | 80 | pr_debug("mf %02X %02X %02X ", |
81 | fraginfo->flags & IP6T_FRAG_MF, | 81 | fraginfo->flags & IP6T_FRAG_MF, |
82 | ntohs(fh->frag_off) & IP6_MF, | 82 | ntohs(fh->frag_off) & IP6_MF, |
83 | !((fraginfo->flags & IP6T_FRAG_MF) | 83 | !((fraginfo->flags & IP6T_FRAG_MF) && |
84 | && !((ntohs(fh->frag_off) & IP6_MF)))); | 84 | !((ntohs(fh->frag_off) & IP6_MF)))); |
85 | pr_debug("last %02X %02X %02X\n", | 85 | pr_debug("last %02X %02X %02X\n", |
86 | fraginfo->flags & IP6T_FRAG_NMF, | 86 | fraginfo->flags & IP6T_FRAG_NMF, |
87 | ntohs(fh->frag_off) & IP6_MF, | 87 | ntohs(fh->frag_off) & IP6_MF, |
88 | !((fraginfo->flags & IP6T_FRAG_NMF) | 88 | !((fraginfo->flags & IP6T_FRAG_NMF) && |
89 | && (ntohs(fh->frag_off) & IP6_MF))); | 89 | (ntohs(fh->frag_off) & IP6_MF))); |
90 | 90 | ||
91 | return (fh != NULL) | 91 | return (fh != NULL) && |
92 | && | 92 | id_match(fraginfo->ids[0], fraginfo->ids[1], |
93 | id_match(fraginfo->ids[0], fraginfo->ids[1], | 93 | ntohl(fh->identification), |
94 | ntohl(fh->identification), | 94 | !!(fraginfo->invflags & IP6T_FRAG_INV_IDS)) && |
95 | !!(fraginfo->invflags & IP6T_FRAG_INV_IDS)) | 95 | !((fraginfo->flags & IP6T_FRAG_RES) && |
96 | && | 96 | (fh->reserved || (ntohs(fh->frag_off) & 0x6))) && |
97 | !((fraginfo->flags & IP6T_FRAG_RES) | 97 | !((fraginfo->flags & IP6T_FRAG_FST) && |
98 | && (fh->reserved || (ntohs(fh->frag_off) & 0x6))) | 98 | (ntohs(fh->frag_off) & ~0x7)) && |
99 | && | 99 | !((fraginfo->flags & IP6T_FRAG_MF) && |
100 | !((fraginfo->flags & IP6T_FRAG_FST) | 100 | !(ntohs(fh->frag_off) & IP6_MF)) && |
101 | && (ntohs(fh->frag_off) & ~0x7)) | 101 | !((fraginfo->flags & IP6T_FRAG_NMF) && |
102 | && | 102 | (ntohs(fh->frag_off) & IP6_MF)); |
103 | !((fraginfo->flags & IP6T_FRAG_MF) | ||
104 | && !(ntohs(fh->frag_off) & IP6_MF)) | ||
105 | && | ||
106 | !((fraginfo->flags & IP6T_FRAG_NMF) | ||
107 | && (ntohs(fh->frag_off) & IP6_MF)); | ||
108 | } | 103 | } |
109 | 104 | ||
110 | static bool frag_mt6_check(const struct xt_mtchk_param *par) | 105 | static bool frag_mt6_check(const struct xt_mtchk_param *par) |
diff --git a/net/ipv6/netfilter/ip6t_rt.c b/net/ipv6/netfilter/ip6t_rt.c index 356b8d6f6baa..b77307fc8743 100644 --- a/net/ipv6/netfilter/ip6t_rt.c +++ b/net/ipv6/netfilter/ip6t_rt.c | |||
@@ -92,16 +92,13 @@ static bool rt_mt6(const struct sk_buff *skb, const struct xt_match_param *par) | |||
92 | !((rtinfo->flags & IP6T_RT_RES) && | 92 | !((rtinfo->flags & IP6T_RT_RES) && |
93 | (((const struct rt0_hdr *)rh)->reserved))); | 93 | (((const struct rt0_hdr *)rh)->reserved))); |
94 | 94 | ||
95 | ret = (rh != NULL) | 95 | ret = (rh != NULL) && |
96 | && | ||
97 | (segsleft_match(rtinfo->segsleft[0], rtinfo->segsleft[1], | 96 | (segsleft_match(rtinfo->segsleft[0], rtinfo->segsleft[1], |
98 | rh->segments_left, | 97 | rh->segments_left, |
99 | !!(rtinfo->invflags & IP6T_RT_INV_SGS))) | 98 | !!(rtinfo->invflags & IP6T_RT_INV_SGS))) && |
100 | && | ||
101 | (!(rtinfo->flags & IP6T_RT_LEN) || | 99 | (!(rtinfo->flags & IP6T_RT_LEN) || |
102 | ((rtinfo->hdrlen == hdrlen) ^ | 100 | ((rtinfo->hdrlen == hdrlen) ^ |
103 | !!(rtinfo->invflags & IP6T_RT_INV_LEN))) | 101 | !!(rtinfo->invflags & IP6T_RT_INV_LEN))) && |
104 | && | ||
105 | (!(rtinfo->flags & IP6T_RT_TYP) || | 102 | (!(rtinfo->flags & IP6T_RT_TYP) || |
106 | ((rtinfo->rt_type == rh->type) ^ | 103 | ((rtinfo->rt_type == rh->type) ^ |
107 | !!(rtinfo->invflags & IP6T_RT_INV_TYP))); | 104 | !!(rtinfo->invflags & IP6T_RT_INV_TYP))); |
diff --git a/net/ipv6/netfilter/ip6table_filter.c b/net/ipv6/netfilter/ip6table_filter.c index 6f4383ad86f9..ad378efd0eb8 100644 --- a/net/ipv6/netfilter/ip6table_filter.c +++ b/net/ipv6/netfilter/ip6table_filter.c | |||
@@ -79,8 +79,8 @@ ip6t_local_out_hook(unsigned int hook, | |||
79 | { | 79 | { |
80 | #if 0 | 80 | #if 0 |
81 | /* root is playing with raw sockets. */ | 81 | /* root is playing with raw sockets. */ |
82 | if (skb->len < sizeof(struct iphdr) | 82 | if (skb->len < sizeof(struct iphdr) || |
83 | || ip_hdrlen(skb) < sizeof(struct iphdr)) { | 83 | ip_hdrlen(skb) < sizeof(struct iphdr)) { |
84 | if (net_ratelimit()) | 84 | if (net_ratelimit()) |
85 | printk("ip6t_hook: happy cracking.\n"); | 85 | printk("ip6t_hook: happy cracking.\n"); |
86 | return NF_ACCEPT; | 86 | return NF_ACCEPT; |
diff --git a/net/ipv6/netfilter/ip6table_mangle.c b/net/ipv6/netfilter/ip6table_mangle.c index 0ad91433ed61..a929c19d30e3 100644 --- a/net/ipv6/netfilter/ip6table_mangle.c +++ b/net/ipv6/netfilter/ip6table_mangle.c | |||
@@ -102,8 +102,8 @@ ip6t_local_out_hook(unsigned int hook, | |||
102 | 102 | ||
103 | #if 0 | 103 | #if 0 |
104 | /* root is playing with raw sockets. */ | 104 | /* root is playing with raw sockets. */ |
105 | if (skb->len < sizeof(struct iphdr) | 105 | if (skb->len < sizeof(struct iphdr) || |
106 | || ip_hdrlen(skb) < sizeof(struct iphdr)) { | 106 | ip_hdrlen(skb) < sizeof(struct iphdr)) { |
107 | if (net_ratelimit()) | 107 | if (net_ratelimit()) |
108 | printk("ip6t_hook: happy cracking.\n"); | 108 | printk("ip6t_hook: happy cracking.\n"); |
109 | return NF_ACCEPT; | 109 | return NF_ACCEPT; |
@@ -122,11 +122,11 @@ ip6t_local_out_hook(unsigned int hook, | |||
122 | ret = ip6t_do_table(skb, hook, in, out, | 122 | ret = ip6t_do_table(skb, hook, in, out, |
123 | dev_net(out)->ipv6.ip6table_mangle); | 123 | dev_net(out)->ipv6.ip6table_mangle); |
124 | 124 | ||
125 | if (ret != NF_DROP && ret != NF_STOLEN | 125 | if (ret != NF_DROP && ret != NF_STOLEN && |
126 | && (memcmp(&ipv6_hdr(skb)->saddr, &saddr, sizeof(saddr)) | 126 | (memcmp(&ipv6_hdr(skb)->saddr, &saddr, sizeof(saddr)) || |
127 | || memcmp(&ipv6_hdr(skb)->daddr, &daddr, sizeof(daddr)) | 127 | memcmp(&ipv6_hdr(skb)->daddr, &daddr, sizeof(daddr)) || |
128 | || skb->mark != mark | 128 | skb->mark != mark || |
129 | || ipv6_hdr(skb)->hop_limit != hop_limit)) | 129 | ipv6_hdr(skb)->hop_limit != hop_limit)) |
130 | return ip6_route_me_harder(skb) == 0 ? ret : NF_DROP; | 130 | return ip6_route_me_harder(skb) == 0 ? ret : NF_DROP; |
131 | 131 | ||
132 | return ret; | 132 | return ret; |
diff --git a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c index 642dcb127bab..0f3df45718ac 100644 --- a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c +++ b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c | |||
@@ -244,18 +244,18 @@ static const struct nla_policy icmpv6_nla_policy[CTA_PROTO_MAX+1] = { | |||
244 | static int icmpv6_nlattr_to_tuple(struct nlattr *tb[], | 244 | static int icmpv6_nlattr_to_tuple(struct nlattr *tb[], |
245 | struct nf_conntrack_tuple *tuple) | 245 | struct nf_conntrack_tuple *tuple) |
246 | { | 246 | { |
247 | if (!tb[CTA_PROTO_ICMPV6_TYPE] | 247 | if (!tb[CTA_PROTO_ICMPV6_TYPE] || |
248 | || !tb[CTA_PROTO_ICMPV6_CODE] | 248 | !tb[CTA_PROTO_ICMPV6_CODE] || |
249 | || !tb[CTA_PROTO_ICMPV6_ID]) | 249 | !tb[CTA_PROTO_ICMPV6_ID]) |
250 | return -EINVAL; | 250 | return -EINVAL; |
251 | 251 | ||
252 | tuple->dst.u.icmp.type = nla_get_u8(tb[CTA_PROTO_ICMPV6_TYPE]); | 252 | tuple->dst.u.icmp.type = nla_get_u8(tb[CTA_PROTO_ICMPV6_TYPE]); |
253 | tuple->dst.u.icmp.code = nla_get_u8(tb[CTA_PROTO_ICMPV6_CODE]); | 253 | tuple->dst.u.icmp.code = nla_get_u8(tb[CTA_PROTO_ICMPV6_CODE]); |
254 | tuple->src.u.icmp.id = nla_get_be16(tb[CTA_PROTO_ICMPV6_ID]); | 254 | tuple->src.u.icmp.id = nla_get_be16(tb[CTA_PROTO_ICMPV6_ID]); |
255 | 255 | ||
256 | if (tuple->dst.u.icmp.type < 128 | 256 | if (tuple->dst.u.icmp.type < 128 || |
257 | || tuple->dst.u.icmp.type - 128 >= sizeof(invmap) | 257 | tuple->dst.u.icmp.type - 128 >= sizeof(invmap) || |
258 | || !invmap[tuple->dst.u.icmp.type - 128]) | 258 | !invmap[tuple->dst.u.icmp.type - 128]) |
259 | return -EINVAL; | 259 | return -EINVAL; |
260 | 260 | ||
261 | return 0; | 261 | return 0; |