diff options
Diffstat (limited to 'net/ipv6')
-rw-r--r-- | net/ipv6/ip6_fib.c | 9 | ||||
-rw-r--r-- | net/ipv6/ip6_flowlabel.c | 24 | ||||
-rw-r--r-- | net/ipv6/ndisc.c | 1 | ||||
-rw-r--r-- | net/ipv6/netfilter/Kconfig | 2 | ||||
-rw-r--r-- | net/ipv6/netfilter/ip6_queue.c | 7 | ||||
-rw-r--r-- | net/ipv6/netfilter/ip6_tables.c | 47 | ||||
-rw-r--r-- | net/ipv6/netfilter/ip6t_ah.c | 7 | ||||
-rw-r--r-- | net/ipv6/netfilter/ip6t_frag.c | 7 | ||||
-rw-r--r-- | net/ipv6/netfilter/ip6t_hbh.c | 7 | ||||
-rw-r--r-- | net/ipv6/netfilter/ip6t_rt.c | 7 | ||||
-rw-r--r-- | net/ipv6/raw.c | 17 | ||||
-rw-r--r-- | net/ipv6/sit.c | 1 | ||||
-rw-r--r-- | net/ipv6/xfrm6_tunnel.c | 4 |
13 files changed, 91 insertions, 49 deletions
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c index 8fcae7a6510b..f98ca30d7c1f 100644 --- a/net/ipv6/ip6_fib.c +++ b/net/ipv6/ip6_fib.c | |||
@@ -169,7 +169,6 @@ static __inline__ void rt6_release(struct rt6_info *rt) | |||
169 | 169 | ||
170 | static struct fib6_table fib6_main_tbl = { | 170 | static struct fib6_table fib6_main_tbl = { |
171 | .tb6_id = RT6_TABLE_MAIN, | 171 | .tb6_id = RT6_TABLE_MAIN, |
172 | .tb6_lock = RW_LOCK_UNLOCKED, | ||
173 | .tb6_root = { | 172 | .tb6_root = { |
174 | .leaf = &ip6_null_entry, | 173 | .leaf = &ip6_null_entry, |
175 | .fn_flags = RTN_ROOT | RTN_TL_ROOT | RTN_RTINFO, | 174 | .fn_flags = RTN_ROOT | RTN_TL_ROOT | RTN_RTINFO, |
@@ -187,6 +186,12 @@ static void fib6_link_table(struct fib6_table *tb) | |||
187 | { | 186 | { |
188 | unsigned int h; | 187 | unsigned int h; |
189 | 188 | ||
189 | /* | ||
190 | * Initialize table lock at a single place to give lockdep a key, | ||
191 | * tables aren't visible prior to being linked to the list. | ||
192 | */ | ||
193 | rwlock_init(&tb->tb6_lock); | ||
194 | |||
190 | h = tb->tb6_id & (FIB_TABLE_HASHSZ - 1); | 195 | h = tb->tb6_id & (FIB_TABLE_HASHSZ - 1); |
191 | 196 | ||
192 | /* | 197 | /* |
@@ -199,7 +204,6 @@ static void fib6_link_table(struct fib6_table *tb) | |||
199 | #ifdef CONFIG_IPV6_MULTIPLE_TABLES | 204 | #ifdef CONFIG_IPV6_MULTIPLE_TABLES |
200 | static struct fib6_table fib6_local_tbl = { | 205 | static struct fib6_table fib6_local_tbl = { |
201 | .tb6_id = RT6_TABLE_LOCAL, | 206 | .tb6_id = RT6_TABLE_LOCAL, |
202 | .tb6_lock = RW_LOCK_UNLOCKED, | ||
203 | .tb6_root = { | 207 | .tb6_root = { |
204 | .leaf = &ip6_null_entry, | 208 | .leaf = &ip6_null_entry, |
205 | .fn_flags = RTN_ROOT | RTN_TL_ROOT | RTN_RTINFO, | 209 | .fn_flags = RTN_ROOT | RTN_TL_ROOT | RTN_RTINFO, |
@@ -213,7 +217,6 @@ static struct fib6_table *fib6_alloc_table(u32 id) | |||
213 | table = kzalloc(sizeof(*table), GFP_ATOMIC); | 217 | table = kzalloc(sizeof(*table), GFP_ATOMIC); |
214 | if (table != NULL) { | 218 | if (table != NULL) { |
215 | table->tb6_id = id; | 219 | table->tb6_id = id; |
216 | table->tb6_lock = RW_LOCK_UNLOCKED; | ||
217 | table->tb6_root.leaf = &ip6_null_entry; | 220 | table->tb6_root.leaf = &ip6_null_entry; |
218 | table->tb6_root.fn_flags = RTN_ROOT | RTN_TL_ROOT | RTN_RTINFO; | 221 | table->tb6_root.fn_flags = RTN_ROOT | RTN_TL_ROOT | RTN_RTINFO; |
219 | } | 222 | } |
diff --git a/net/ipv6/ip6_flowlabel.c b/net/ipv6/ip6_flowlabel.c index 1d672b0547f2..6d4533b58dca 100644 --- a/net/ipv6/ip6_flowlabel.c +++ b/net/ipv6/ip6_flowlabel.c | |||
@@ -330,8 +330,10 @@ fl_create(struct in6_flowlabel_req *freq, char __user *optval, int optlen, int * | |||
330 | fl->share = freq->flr_share; | 330 | fl->share = freq->flr_share; |
331 | addr_type = ipv6_addr_type(&freq->flr_dst); | 331 | addr_type = ipv6_addr_type(&freq->flr_dst); |
332 | if ((addr_type&IPV6_ADDR_MAPPED) | 332 | if ((addr_type&IPV6_ADDR_MAPPED) |
333 | || addr_type == IPV6_ADDR_ANY) | 333 | || addr_type == IPV6_ADDR_ANY) { |
334 | err = -EINVAL; | ||
334 | goto done; | 335 | goto done; |
336 | } | ||
335 | ipv6_addr_copy(&fl->dst, &freq->flr_dst); | 337 | ipv6_addr_copy(&fl->dst, &freq->flr_dst); |
336 | atomic_set(&fl->users, 1); | 338 | atomic_set(&fl->users, 1); |
337 | switch (fl->share) { | 339 | switch (fl->share) { |
@@ -587,6 +589,8 @@ static struct ip6_flowlabel *ip6fl_get_next(struct seq_file *seq, struct ip6_flo | |||
587 | while (!fl) { | 589 | while (!fl) { |
588 | if (++state->bucket <= FL_HASH_MASK) | 590 | if (++state->bucket <= FL_HASH_MASK) |
589 | fl = fl_ht[state->bucket]; | 591 | fl = fl_ht[state->bucket]; |
592 | else | ||
593 | break; | ||
590 | } | 594 | } |
591 | return fl; | 595 | return fl; |
592 | } | 596 | } |
@@ -623,9 +627,13 @@ static void ip6fl_seq_stop(struct seq_file *seq, void *v) | |||
623 | read_unlock_bh(&ip6_fl_lock); | 627 | read_unlock_bh(&ip6_fl_lock); |
624 | } | 628 | } |
625 | 629 | ||
626 | static void ip6fl_fl_seq_show(struct seq_file *seq, struct ip6_flowlabel *fl) | 630 | static int ip6fl_seq_show(struct seq_file *seq, void *v) |
627 | { | 631 | { |
628 | while(fl) { | 632 | if (v == SEQ_START_TOKEN) |
633 | seq_printf(seq, "%-5s %-1s %-6s %-6s %-6s %-8s %-32s %s\n", | ||
634 | "Label", "S", "Owner", "Users", "Linger", "Expires", "Dst", "Opt"); | ||
635 | else { | ||
636 | struct ip6_flowlabel *fl = v; | ||
629 | seq_printf(seq, | 637 | seq_printf(seq, |
630 | "%05X %-1d %-6d %-6d %-6ld %-8ld " NIP6_SEQFMT " %-4d\n", | 638 | "%05X %-1d %-6d %-6d %-6ld %-8ld " NIP6_SEQFMT " %-4d\n", |
631 | (unsigned)ntohl(fl->label), | 639 | (unsigned)ntohl(fl->label), |
@@ -636,17 +644,7 @@ static void ip6fl_fl_seq_show(struct seq_file *seq, struct ip6_flowlabel *fl) | |||
636 | (long)(fl->expires - jiffies)/HZ, | 644 | (long)(fl->expires - jiffies)/HZ, |
637 | NIP6(fl->dst), | 645 | NIP6(fl->dst), |
638 | fl->opt ? fl->opt->opt_nflen : 0); | 646 | fl->opt ? fl->opt->opt_nflen : 0); |
639 | fl = fl->next; | ||
640 | } | 647 | } |
641 | } | ||
642 | |||
643 | static int ip6fl_seq_show(struct seq_file *seq, void *v) | ||
644 | { | ||
645 | if (v == SEQ_START_TOKEN) | ||
646 | seq_printf(seq, "%-5s %-1s %-6s %-6s %-6s %-8s %-32s %s\n", | ||
647 | "Label", "S", "Owner", "Users", "Linger", "Expires", "Dst", "Opt"); | ||
648 | else | ||
649 | ip6fl_fl_seq_show(seq, v); | ||
650 | return 0; | 648 | return 0; |
651 | } | 649 | } |
652 | 650 | ||
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index 41a8a5f06602..73eb8c33e9f0 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c | |||
@@ -1742,6 +1742,7 @@ int __init ndisc_init(struct net_proto_family *ops) | |||
1742 | 1742 | ||
1743 | void ndisc_cleanup(void) | 1743 | void ndisc_cleanup(void) |
1744 | { | 1744 | { |
1745 | unregister_netdevice_notifier(&ndisc_netdev_notifier); | ||
1745 | #ifdef CONFIG_SYSCTL | 1746 | #ifdef CONFIG_SYSCTL |
1746 | neigh_sysctl_unregister(&nd_tbl.parms); | 1747 | neigh_sysctl_unregister(&nd_tbl.parms); |
1747 | #endif | 1748 | #endif |
diff --git a/net/ipv6/netfilter/Kconfig b/net/ipv6/netfilter/Kconfig index 4bc4e5b33794..d7c45a9c15fe 100644 --- a/net/ipv6/netfilter/Kconfig +++ b/net/ipv6/netfilter/Kconfig | |||
@@ -40,7 +40,7 @@ config IP6_NF_QUEUE | |||
40 | To compile it as a module, choose M here. If unsure, say N. | 40 | To compile it as a module, choose M here. If unsure, say N. |
41 | 41 | ||
42 | config IP6_NF_IPTABLES | 42 | config IP6_NF_IPTABLES |
43 | tristate "IP6 tables support (required for filtering/masq/NAT)" | 43 | tristate "IP6 tables support (required for filtering)" |
44 | depends on NETFILTER_XTABLES | 44 | depends on NETFILTER_XTABLES |
45 | help | 45 | help |
46 | ip6tables is a general, extensible packet identification framework. | 46 | ip6tables is a general, extensible packet identification framework. |
diff --git a/net/ipv6/netfilter/ip6_queue.c b/net/ipv6/netfilter/ip6_queue.c index 9510c24ca8d2..9fec832ee08b 100644 --- a/net/ipv6/netfilter/ip6_queue.c +++ b/net/ipv6/netfilter/ip6_queue.c | |||
@@ -349,9 +349,10 @@ ipq_mangle_ipv6(ipq_verdict_msg_t *v, struct ipq_queue_entry *e) | |||
349 | if (v->data_len < sizeof(*user_iph)) | 349 | if (v->data_len < sizeof(*user_iph)) |
350 | return 0; | 350 | return 0; |
351 | diff = v->data_len - e->skb->len; | 351 | diff = v->data_len - e->skb->len; |
352 | if (diff < 0) | 352 | if (diff < 0) { |
353 | skb_trim(e->skb, v->data_len); | 353 | if (pskb_trim(e->skb, v->data_len)) |
354 | else if (diff > 0) { | 354 | return -ENOMEM; |
355 | } else if (diff > 0) { | ||
355 | if (v->data_len > 0xFFFF) | 356 | if (v->data_len > 0xFFFF) |
356 | return -EINVAL; | 357 | return -EINVAL; |
357 | if (diff > skb_tailroom(e->skb)) { | 358 | if (diff > skb_tailroom(e->skb)) { |
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c index 4ab368fa0b8f..204e02162d49 100644 --- a/net/ipv6/netfilter/ip6_tables.c +++ b/net/ipv6/netfilter/ip6_tables.c | |||
@@ -111,7 +111,7 @@ ip6_packet_match(const struct sk_buff *skb, | |||
111 | const char *outdev, | 111 | const char *outdev, |
112 | const struct ip6t_ip6 *ip6info, | 112 | const struct ip6t_ip6 *ip6info, |
113 | unsigned int *protoff, | 113 | unsigned int *protoff, |
114 | int *fragoff) | 114 | int *fragoff, int *hotdrop) |
115 | { | 115 | { |
116 | size_t i; | 116 | size_t i; |
117 | unsigned long ret; | 117 | unsigned long ret; |
@@ -169,9 +169,11 @@ ip6_packet_match(const struct sk_buff *skb, | |||
169 | unsigned short _frag_off; | 169 | unsigned short _frag_off; |
170 | 170 | ||
171 | protohdr = ipv6_find_hdr(skb, protoff, -1, &_frag_off); | 171 | protohdr = ipv6_find_hdr(skb, protoff, -1, &_frag_off); |
172 | if (protohdr < 0) | 172 | if (protohdr < 0) { |
173 | if (_frag_off == 0) | ||
174 | *hotdrop = 1; | ||
173 | return 0; | 175 | return 0; |
174 | 176 | } | |
175 | *fragoff = _frag_off; | 177 | *fragoff = _frag_off; |
176 | 178 | ||
177 | dprintf("Packet protocol %hi ?= %s%hi.\n", | 179 | dprintf("Packet protocol %hi ?= %s%hi.\n", |
@@ -290,7 +292,7 @@ ip6t_do_table(struct sk_buff **pskb, | |||
290 | IP_NF_ASSERT(e); | 292 | IP_NF_ASSERT(e); |
291 | IP_NF_ASSERT(back); | 293 | IP_NF_ASSERT(back); |
292 | if (ip6_packet_match(*pskb, indev, outdev, &e->ipv6, | 294 | if (ip6_packet_match(*pskb, indev, outdev, &e->ipv6, |
293 | &protoff, &offset)) { | 295 | &protoff, &offset, &hotdrop)) { |
294 | struct ip6t_entry_target *t; | 296 | struct ip6t_entry_target *t; |
295 | 297 | ||
296 | if (IP6T_MATCH_ITERATE(e, do_match, | 298 | if (IP6T_MATCH_ITERATE(e, do_match, |
@@ -584,12 +586,19 @@ check_entry(struct ip6t_entry *e, const char *name, unsigned int size, | |||
584 | return -EINVAL; | 586 | return -EINVAL; |
585 | } | 587 | } |
586 | 588 | ||
589 | if (e->target_offset + sizeof(struct ip6t_entry_target) > | ||
590 | e->next_offset) | ||
591 | return -EINVAL; | ||
592 | |||
587 | j = 0; | 593 | j = 0; |
588 | ret = IP6T_MATCH_ITERATE(e, check_match, name, &e->ipv6, e->comefrom, &j); | 594 | ret = IP6T_MATCH_ITERATE(e, check_match, name, &e->ipv6, e->comefrom, &j); |
589 | if (ret != 0) | 595 | if (ret != 0) |
590 | goto cleanup_matches; | 596 | goto cleanup_matches; |
591 | 597 | ||
592 | t = ip6t_get_target(e); | 598 | t = ip6t_get_target(e); |
599 | ret = -EINVAL; | ||
600 | if (e->target_offset + t->u.target_size > e->next_offset) | ||
601 | goto cleanup_matches; | ||
593 | target = try_then_request_module(xt_find_target(AF_INET6, | 602 | target = try_then_request_module(xt_find_target(AF_INET6, |
594 | t->u.user.name, | 603 | t->u.user.name, |
595 | t->u.user.revision), | 604 | t->u.user.revision), |
@@ -749,19 +758,17 @@ translate_table(const char *name, | |||
749 | } | 758 | } |
750 | } | 759 | } |
751 | 760 | ||
752 | if (!mark_source_chains(newinfo, valid_hooks, entry0)) | ||
753 | return -ELOOP; | ||
754 | |||
755 | /* Finally, each sanity check must pass */ | 761 | /* Finally, each sanity check must pass */ |
756 | i = 0; | 762 | i = 0; |
757 | ret = IP6T_ENTRY_ITERATE(entry0, newinfo->size, | 763 | ret = IP6T_ENTRY_ITERATE(entry0, newinfo->size, |
758 | check_entry, name, size, &i); | 764 | check_entry, name, size, &i); |
759 | 765 | ||
760 | if (ret != 0) { | 766 | if (ret != 0) |
761 | IP6T_ENTRY_ITERATE(entry0, newinfo->size, | 767 | goto cleanup; |
762 | cleanup_entry, &i); | 768 | |
763 | return ret; | 769 | ret = -ELOOP; |
764 | } | 770 | if (!mark_source_chains(newinfo, valid_hooks, entry0)) |
771 | goto cleanup; | ||
765 | 772 | ||
766 | /* And one copy for every other CPU */ | 773 | /* And one copy for every other CPU */ |
767 | for_each_possible_cpu(i) { | 774 | for_each_possible_cpu(i) { |
@@ -769,6 +776,9 @@ translate_table(const char *name, | |||
769 | memcpy(newinfo->entries[i], entry0, newinfo->size); | 776 | memcpy(newinfo->entries[i], entry0, newinfo->size); |
770 | } | 777 | } |
771 | 778 | ||
779 | return 0; | ||
780 | cleanup: | ||
781 | IP6T_ENTRY_ITERATE(entry0, newinfo->size, cleanup_entry, &i); | ||
772 | return ret; | 782 | return ret; |
773 | } | 783 | } |
774 | 784 | ||
@@ -1438,6 +1448,9 @@ static void __exit ip6_tables_fini(void) | |||
1438 | * If target header is found, its offset is set in *offset and return protocol | 1448 | * If target header is found, its offset is set in *offset and return protocol |
1439 | * number. Otherwise, return -1. | 1449 | * number. Otherwise, return -1. |
1440 | * | 1450 | * |
1451 | * If the first fragment doesn't contain the final protocol header or | ||
1452 | * NEXTHDR_NONE it is considered invalid. | ||
1453 | * | ||
1441 | * Note that non-1st fragment is special case that "the protocol number | 1454 | * Note that non-1st fragment is special case that "the protocol number |
1442 | * of last header" is "next header" field in Fragment header. In this case, | 1455 | * of last header" is "next header" field in Fragment header. In this case, |
1443 | * *offset is meaningless and fragment offset is stored in *fragoff if fragoff | 1456 | * *offset is meaningless and fragment offset is stored in *fragoff if fragoff |
@@ -1461,12 +1474,12 @@ int ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset, | |||
1461 | if ((!ipv6_ext_hdr(nexthdr)) || nexthdr == NEXTHDR_NONE) { | 1474 | if ((!ipv6_ext_hdr(nexthdr)) || nexthdr == NEXTHDR_NONE) { |
1462 | if (target < 0) | 1475 | if (target < 0) |
1463 | break; | 1476 | break; |
1464 | return -1; | 1477 | return -ENOENT; |
1465 | } | 1478 | } |
1466 | 1479 | ||
1467 | hp = skb_header_pointer(skb, start, sizeof(_hdr), &_hdr); | 1480 | hp = skb_header_pointer(skb, start, sizeof(_hdr), &_hdr); |
1468 | if (hp == NULL) | 1481 | if (hp == NULL) |
1469 | return -1; | 1482 | return -EBADMSG; |
1470 | if (nexthdr == NEXTHDR_FRAGMENT) { | 1483 | if (nexthdr == NEXTHDR_FRAGMENT) { |
1471 | unsigned short _frag_off, *fp; | 1484 | unsigned short _frag_off, *fp; |
1472 | fp = skb_header_pointer(skb, | 1485 | fp = skb_header_pointer(skb, |
@@ -1475,18 +1488,18 @@ int ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset, | |||
1475 | sizeof(_frag_off), | 1488 | sizeof(_frag_off), |
1476 | &_frag_off); | 1489 | &_frag_off); |
1477 | if (fp == NULL) | 1490 | if (fp == NULL) |
1478 | return -1; | 1491 | return -EBADMSG; |
1479 | 1492 | ||
1480 | _frag_off = ntohs(*fp) & ~0x7; | 1493 | _frag_off = ntohs(*fp) & ~0x7; |
1481 | if (_frag_off) { | 1494 | if (_frag_off) { |
1482 | if (target < 0 && | 1495 | if (target < 0 && |
1483 | ((!ipv6_ext_hdr(hp->nexthdr)) || | 1496 | ((!ipv6_ext_hdr(hp->nexthdr)) || |
1484 | nexthdr == NEXTHDR_NONE)) { | 1497 | hp->nexthdr == NEXTHDR_NONE)) { |
1485 | if (fragoff) | 1498 | if (fragoff) |
1486 | *fragoff = _frag_off; | 1499 | *fragoff = _frag_off; |
1487 | return hp->nexthdr; | 1500 | return hp->nexthdr; |
1488 | } | 1501 | } |
1489 | return -1; | 1502 | return -ENOENT; |
1490 | } | 1503 | } |
1491 | hdrlen = 8; | 1504 | hdrlen = 8; |
1492 | } else if (nexthdr == NEXTHDR_AUTH) | 1505 | } else if (nexthdr == NEXTHDR_AUTH) |
diff --git a/net/ipv6/netfilter/ip6t_ah.c b/net/ipv6/netfilter/ip6t_ah.c index ec1b1608156c..46486645eb75 100644 --- a/net/ipv6/netfilter/ip6t_ah.c +++ b/net/ipv6/netfilter/ip6t_ah.c | |||
@@ -54,9 +54,14 @@ match(const struct sk_buff *skb, | |||
54 | const struct ip6t_ah *ahinfo = matchinfo; | 54 | const struct ip6t_ah *ahinfo = matchinfo; |
55 | unsigned int ptr; | 55 | unsigned int ptr; |
56 | unsigned int hdrlen = 0; | 56 | unsigned int hdrlen = 0; |
57 | int err; | ||
57 | 58 | ||
58 | if (ipv6_find_hdr(skb, &ptr, NEXTHDR_AUTH, NULL) < 0) | 59 | err = ipv6_find_hdr(skb, &ptr, NEXTHDR_AUTH, NULL); |
60 | if (err < 0) { | ||
61 | if (err != -ENOENT) | ||
62 | *hotdrop = 1; | ||
59 | return 0; | 63 | return 0; |
64 | } | ||
60 | 65 | ||
61 | ah = skb_header_pointer(skb, ptr, sizeof(_ah), &_ah); | 66 | ah = skb_header_pointer(skb, ptr, sizeof(_ah), &_ah); |
62 | if (ah == NULL) { | 67 | if (ah == NULL) { |
diff --git a/net/ipv6/netfilter/ip6t_frag.c b/net/ipv6/netfilter/ip6t_frag.c index 78d9c8b9e28a..cd22eaaccdca 100644 --- a/net/ipv6/netfilter/ip6t_frag.c +++ b/net/ipv6/netfilter/ip6t_frag.c | |||
@@ -52,9 +52,14 @@ match(const struct sk_buff *skb, | |||
52 | struct frag_hdr _frag, *fh; | 52 | struct frag_hdr _frag, *fh; |
53 | const struct ip6t_frag *fraginfo = matchinfo; | 53 | const struct ip6t_frag *fraginfo = matchinfo; |
54 | unsigned int ptr; | 54 | unsigned int ptr; |
55 | int err; | ||
55 | 56 | ||
56 | if (ipv6_find_hdr(skb, &ptr, NEXTHDR_FRAGMENT, NULL) < 0) | 57 | err = ipv6_find_hdr(skb, &ptr, NEXTHDR_FRAGMENT, NULL); |
58 | if (err < 0) { | ||
59 | if (err != -ENOENT) | ||
60 | *hotdrop = 1; | ||
57 | return 0; | 61 | return 0; |
62 | } | ||
58 | 63 | ||
59 | fh = skb_header_pointer(skb, ptr, sizeof(_frag), &_frag); | 64 | fh = skb_header_pointer(skb, ptr, sizeof(_frag), &_frag); |
60 | if (fh == NULL) { | 65 | if (fh == NULL) { |
diff --git a/net/ipv6/netfilter/ip6t_hbh.c b/net/ipv6/netfilter/ip6t_hbh.c index d32a205e3af2..3f25babe0440 100644 --- a/net/ipv6/netfilter/ip6t_hbh.c +++ b/net/ipv6/netfilter/ip6t_hbh.c | |||
@@ -65,9 +65,14 @@ match(const struct sk_buff *skb, | |||
65 | u8 _opttype, *tp = NULL; | 65 | u8 _opttype, *tp = NULL; |
66 | u8 _optlen, *lp = NULL; | 66 | u8 _optlen, *lp = NULL; |
67 | unsigned int optlen; | 67 | unsigned int optlen; |
68 | int err; | ||
68 | 69 | ||
69 | if (ipv6_find_hdr(skb, &ptr, match->data, NULL) < 0) | 70 | err = ipv6_find_hdr(skb, &ptr, match->data, NULL); |
71 | if (err < 0) { | ||
72 | if (err != -ENOENT) | ||
73 | *hotdrop = 1; | ||
70 | return 0; | 74 | return 0; |
75 | } | ||
71 | 76 | ||
72 | oh = skb_header_pointer(skb, ptr, sizeof(_optsh), &_optsh); | 77 | oh = skb_header_pointer(skb, ptr, sizeof(_optsh), &_optsh); |
73 | if (oh == NULL) { | 78 | if (oh == NULL) { |
diff --git a/net/ipv6/netfilter/ip6t_rt.c b/net/ipv6/netfilter/ip6t_rt.c index bcb2e168a5bc..54d7d14134fd 100644 --- a/net/ipv6/netfilter/ip6t_rt.c +++ b/net/ipv6/netfilter/ip6t_rt.c | |||
@@ -58,9 +58,14 @@ match(const struct sk_buff *skb, | |||
58 | unsigned int hdrlen = 0; | 58 | unsigned int hdrlen = 0; |
59 | unsigned int ret = 0; | 59 | unsigned int ret = 0; |
60 | struct in6_addr *ap, _addr; | 60 | struct in6_addr *ap, _addr; |
61 | int err; | ||
61 | 62 | ||
62 | if (ipv6_find_hdr(skb, &ptr, NEXTHDR_ROUTING, NULL) < 0) | 63 | err = ipv6_find_hdr(skb, &ptr, NEXTHDR_ROUTING, NULL); |
64 | if (err < 0) { | ||
65 | if (err != -ENOENT) | ||
66 | *hotdrop = 1; | ||
63 | return 0; | 67 | return 0; |
68 | } | ||
64 | 69 | ||
65 | rh = skb_header_pointer(skb, ptr, sizeof(_route), &_route); | 70 | rh = skb_header_pointer(skb, ptr, sizeof(_route), &_route); |
66 | if (rh == NULL) { | 71 | if (rh == NULL) { |
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index d09329ca3267..d6dedc4aec77 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c | |||
@@ -604,7 +604,7 @@ error: | |||
604 | return err; | 604 | return err; |
605 | } | 605 | } |
606 | 606 | ||
607 | static void rawv6_probe_proto_opt(struct flowi *fl, struct msghdr *msg) | 607 | static int rawv6_probe_proto_opt(struct flowi *fl, struct msghdr *msg) |
608 | { | 608 | { |
609 | struct iovec *iov; | 609 | struct iovec *iov; |
610 | u8 __user *type = NULL; | 610 | u8 __user *type = NULL; |
@@ -616,7 +616,7 @@ static void rawv6_probe_proto_opt(struct flowi *fl, struct msghdr *msg) | |||
616 | int i; | 616 | int i; |
617 | 617 | ||
618 | if (!msg->msg_iov) | 618 | if (!msg->msg_iov) |
619 | return; | 619 | return 0; |
620 | 620 | ||
621 | for (i = 0; i < msg->msg_iovlen; i++) { | 621 | for (i = 0; i < msg->msg_iovlen; i++) { |
622 | iov = &msg->msg_iov[i]; | 622 | iov = &msg->msg_iov[i]; |
@@ -638,8 +638,9 @@ static void rawv6_probe_proto_opt(struct flowi *fl, struct msghdr *msg) | |||
638 | code = iov->iov_base; | 638 | code = iov->iov_base; |
639 | 639 | ||
640 | if (type && code) { | 640 | if (type && code) { |
641 | get_user(fl->fl_icmp_type, type); | 641 | if (get_user(fl->fl_icmp_type, type) || |
642 | get_user(fl->fl_icmp_code, code); | 642 | get_user(fl->fl_icmp_code, code)) |
643 | return -EFAULT; | ||
643 | probed = 1; | 644 | probed = 1; |
644 | } | 645 | } |
645 | break; | 646 | break; |
@@ -650,7 +651,8 @@ static void rawv6_probe_proto_opt(struct flowi *fl, struct msghdr *msg) | |||
650 | /* check if type field is readable or not. */ | 651 | /* check if type field is readable or not. */ |
651 | if (iov->iov_len > 2 - len) { | 652 | if (iov->iov_len > 2 - len) { |
652 | u8 __user *p = iov->iov_base; | 653 | u8 __user *p = iov->iov_base; |
653 | get_user(fl->fl_mh_type, &p[2 - len]); | 654 | if (get_user(fl->fl_mh_type, &p[2 - len])) |
655 | return -EFAULT; | ||
654 | probed = 1; | 656 | probed = 1; |
655 | } else | 657 | } else |
656 | len += iov->iov_len; | 658 | len += iov->iov_len; |
@@ -664,6 +666,7 @@ static void rawv6_probe_proto_opt(struct flowi *fl, struct msghdr *msg) | |||
664 | if (probed) | 666 | if (probed) |
665 | break; | 667 | break; |
666 | } | 668 | } |
669 | return 0; | ||
667 | } | 670 | } |
668 | 671 | ||
669 | static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk, | 672 | static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk, |
@@ -787,7 +790,9 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk, | |||
787 | opt = ipv6_fixup_options(&opt_space, opt); | 790 | opt = ipv6_fixup_options(&opt_space, opt); |
788 | 791 | ||
789 | fl.proto = proto; | 792 | fl.proto = proto; |
790 | rawv6_probe_proto_opt(&fl, msg); | 793 | err = rawv6_probe_proto_opt(&fl, msg); |
794 | if (err) | ||
795 | goto out; | ||
791 | 796 | ||
792 | ipv6_addr_copy(&fl.fl6_dst, daddr); | 797 | ipv6_addr_copy(&fl.fl6_dst, daddr); |
793 | if (ipv6_addr_any(&fl.fl6_src) && !ipv6_addr_any(&np->saddr)) | 798 | if (ipv6_addr_any(&fl.fl6_src) && !ipv6_addr_any(&np->saddr)) |
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index b481a4d780c2..be699f85b2c7 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c | |||
@@ -854,3 +854,4 @@ int __init sit_init(void) | |||
854 | module_init(sit_init); | 854 | module_init(sit_init); |
855 | module_exit(sit_cleanup); | 855 | module_exit(sit_cleanup); |
856 | MODULE_LICENSE("GPL"); | 856 | MODULE_LICENSE("GPL"); |
857 | MODULE_ALIAS("sit0"); | ||
diff --git a/net/ipv6/xfrm6_tunnel.c b/net/ipv6/xfrm6_tunnel.c index 7af227bb1551..7931e4f898d4 100644 --- a/net/ipv6/xfrm6_tunnel.c +++ b/net/ipv6/xfrm6_tunnel.c | |||
@@ -135,7 +135,7 @@ u32 xfrm6_tunnel_spi_lookup(xfrm_address_t *saddr) | |||
135 | x6spi = __xfrm6_tunnel_spi_lookup(saddr); | 135 | x6spi = __xfrm6_tunnel_spi_lookup(saddr); |
136 | spi = x6spi ? x6spi->spi : 0; | 136 | spi = x6spi ? x6spi->spi : 0; |
137 | read_unlock_bh(&xfrm6_tunnel_spi_lock); | 137 | read_unlock_bh(&xfrm6_tunnel_spi_lock); |
138 | return spi; | 138 | return htonl(spi); |
139 | } | 139 | } |
140 | 140 | ||
141 | EXPORT_SYMBOL(xfrm6_tunnel_spi_lookup); | 141 | EXPORT_SYMBOL(xfrm6_tunnel_spi_lookup); |
@@ -210,7 +210,7 @@ u32 xfrm6_tunnel_alloc_spi(xfrm_address_t *saddr) | |||
210 | spi = __xfrm6_tunnel_alloc_spi(saddr); | 210 | spi = __xfrm6_tunnel_alloc_spi(saddr); |
211 | write_unlock_bh(&xfrm6_tunnel_spi_lock); | 211 | write_unlock_bh(&xfrm6_tunnel_spi_lock); |
212 | 212 | ||
213 | return spi; | 213 | return htonl(spi); |
214 | } | 214 | } |
215 | 215 | ||
216 | EXPORT_SYMBOL(xfrm6_tunnel_alloc_spi); | 216 | EXPORT_SYMBOL(xfrm6_tunnel_alloc_spi); |