diff options
author | Linus Torvalds <torvalds@woody.osdl.org> | 2006-12-07 12:05:15 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.osdl.org> | 2006-12-07 12:05:15 -0500 |
commit | 2685b267bce34c9b66626cb11664509c32a761a5 (patch) | |
tree | ce8b4ad47b4a1aa1b0e7634298d63c4cb0ca46c5 /net/ipv6 | |
parent | 4522d58275f124105819723e24e912c8e5bf3cdd (diff) | |
parent | 272491ef423b6976a230a998b10f46976aa91342 (diff) |
Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
* master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6: (48 commits)
[NETFILTER]: Fix non-ANSI func. decl.
[TG3]: Identify Serdes devices more clearly.
[TG3]: Use msleep.
[TG3]: Use netif_msg_*.
[TG3]: Allow partial speed advertisement.
[TG3]: Add TG3_FLG2_IS_NIC flag.
[TG3]: Add 5787F device ID.
[TG3]: Fix Phy loopback.
[WANROUTER]: Kill kmalloc debugging code.
[TCP] inet_twdr_hangman: Delete unnecessary memory barrier().
[NET]: Memory barrier cleanups
[IPSEC]: Fix inetpeer leak in ipv4 xfrm dst entries.
audit: disable ipsec auditing when CONFIG_AUDITSYSCALL=n
audit: Add auditing to ipsec
[IRDA] irlan: Fix compile warning when CONFIG_PROC_FS=n
[IrDA]: Incorrect TTP header reservation
[IrDA]: PXA FIR code device model conversion
[GENETLINK]: Fix misplaced command flags.
[NETLIK]: Add a pointer to the Generic Netlink wiki page.
[IPV6] RAW: Don't release unlocked sock.
...
Diffstat (limited to 'net/ipv6')
-rw-r--r-- | net/ipv6/ip6_output.c | 2 | ||||
-rw-r--r-- | net/ipv6/netfilter/ip6_tables.c | 59 | ||||
-rw-r--r-- | net/ipv6/raw.c | 3 |
3 files changed, 26 insertions, 38 deletions
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index e05ecbb1412d..e9212c7ff5cf 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c | |||
@@ -624,13 +624,13 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) | |||
624 | skb_shinfo(skb)->frag_list = NULL; | 624 | skb_shinfo(skb)->frag_list = NULL; |
625 | /* BUILD HEADER */ | 625 | /* BUILD HEADER */ |
626 | 626 | ||
627 | *prevhdr = NEXTHDR_FRAGMENT; | ||
627 | tmp_hdr = kmemdup(skb->nh.raw, hlen, GFP_ATOMIC); | 628 | tmp_hdr = kmemdup(skb->nh.raw, hlen, GFP_ATOMIC); |
628 | if (!tmp_hdr) { | 629 | if (!tmp_hdr) { |
629 | IP6_INC_STATS(ip6_dst_idev(skb->dst), IPSTATS_MIB_FRAGFAILS); | 630 | IP6_INC_STATS(ip6_dst_idev(skb->dst), IPSTATS_MIB_FRAGFAILS); |
630 | return -ENOMEM; | 631 | return -ENOMEM; |
631 | } | 632 | } |
632 | 633 | ||
633 | *prevhdr = NEXTHDR_FRAGMENT; | ||
634 | __skb_pull(skb, hlen); | 634 | __skb_pull(skb, hlen); |
635 | fh = (struct frag_hdr*)__skb_push(skb, sizeof(struct frag_hdr)); | 635 | fh = (struct frag_hdr*)__skb_push(skb, sizeof(struct frag_hdr)); |
636 | skb->nh.raw = __skb_push(skb, hlen); | 636 | skb->nh.raw = __skb_push(skb, hlen); |
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c index f63fb86d7c7b..4eec4b3988b8 100644 --- a/net/ipv6/netfilter/ip6_tables.c +++ b/net/ipv6/netfilter/ip6_tables.c | |||
@@ -440,6 +440,13 @@ mark_source_chains(struct xt_table_info *newinfo, | |||
440 | && unconditional(&e->ipv6)) { | 440 | && unconditional(&e->ipv6)) { |
441 | unsigned int oldpos, size; | 441 | unsigned int oldpos, size; |
442 | 442 | ||
443 | if (t->verdict < -NF_MAX_VERDICT - 1) { | ||
444 | duprintf("mark_source_chains: bad " | ||
445 | "negative verdict (%i)\n", | ||
446 | t->verdict); | ||
447 | return 0; | ||
448 | } | ||
449 | |||
443 | /* Return: backtrack through the last | 450 | /* Return: backtrack through the last |
444 | big jump. */ | 451 | big jump. */ |
445 | do { | 452 | do { |
@@ -477,6 +484,13 @@ mark_source_chains(struct xt_table_info *newinfo, | |||
477 | if (strcmp(t->target.u.user.name, | 484 | if (strcmp(t->target.u.user.name, |
478 | IP6T_STANDARD_TARGET) == 0 | 485 | IP6T_STANDARD_TARGET) == 0 |
479 | && newpos >= 0) { | 486 | && newpos >= 0) { |
487 | if (newpos > newinfo->size - | ||
488 | sizeof(struct ip6t_entry)) { | ||
489 | duprintf("mark_source_chains: " | ||
490 | "bad verdict (%i)\n", | ||
491 | newpos); | ||
492 | return 0; | ||
493 | } | ||
480 | /* This a jump; chase it. */ | 494 | /* This a jump; chase it. */ |
481 | duprintf("Jump rule %u -> %u\n", | 495 | duprintf("Jump rule %u -> %u\n", |
482 | pos, newpos); | 496 | pos, newpos); |
@@ -509,27 +523,6 @@ cleanup_match(struct ip6t_entry_match *m, unsigned int *i) | |||
509 | } | 523 | } |
510 | 524 | ||
511 | static inline int | 525 | static inline int |
512 | standard_check(const struct ip6t_entry_target *t, | ||
513 | unsigned int max_offset) | ||
514 | { | ||
515 | struct ip6t_standard_target *targ = (void *)t; | ||
516 | |||
517 | /* Check standard info. */ | ||
518 | if (targ->verdict >= 0 | ||
519 | && targ->verdict > max_offset - sizeof(struct ip6t_entry)) { | ||
520 | duprintf("ip6t_standard_check: bad verdict (%i)\n", | ||
521 | targ->verdict); | ||
522 | return 0; | ||
523 | } | ||
524 | if (targ->verdict < -NF_MAX_VERDICT - 1) { | ||
525 | duprintf("ip6t_standard_check: bad negative verdict (%i)\n", | ||
526 | targ->verdict); | ||
527 | return 0; | ||
528 | } | ||
529 | return 1; | ||
530 | } | ||
531 | |||
532 | static inline int | ||
533 | check_match(struct ip6t_entry_match *m, | 526 | check_match(struct ip6t_entry_match *m, |
534 | const char *name, | 527 | const char *name, |
535 | const struct ip6t_ip6 *ipv6, | 528 | const struct ip6t_ip6 *ipv6, |
@@ -616,12 +609,7 @@ check_entry(struct ip6t_entry *e, const char *name, unsigned int size, | |||
616 | if (ret) | 609 | if (ret) |
617 | goto err; | 610 | goto err; |
618 | 611 | ||
619 | if (t->u.kernel.target == &ip6t_standard_target) { | 612 | if (t->u.kernel.target->checkentry |
620 | if (!standard_check(t, size)) { | ||
621 | ret = -EINVAL; | ||
622 | goto err; | ||
623 | } | ||
624 | } else if (t->u.kernel.target->checkentry | ||
625 | && !t->u.kernel.target->checkentry(name, e, target, t->data, | 613 | && !t->u.kernel.target->checkentry(name, e, target, t->data, |
626 | e->comefrom)) { | 614 | e->comefrom)) { |
627 | duprintf("ip_tables: check failed for `%s'.\n", | 615 | duprintf("ip_tables: check failed for `%s'.\n", |
@@ -758,17 +746,19 @@ translate_table(const char *name, | |||
758 | } | 746 | } |
759 | } | 747 | } |
760 | 748 | ||
749 | if (!mark_source_chains(newinfo, valid_hooks, entry0)) | ||
750 | return -ELOOP; | ||
751 | |||
761 | /* Finally, each sanity check must pass */ | 752 | /* Finally, each sanity check must pass */ |
762 | i = 0; | 753 | i = 0; |
763 | ret = IP6T_ENTRY_ITERATE(entry0, newinfo->size, | 754 | ret = IP6T_ENTRY_ITERATE(entry0, newinfo->size, |
764 | check_entry, name, size, &i); | 755 | check_entry, name, size, &i); |
765 | 756 | ||
766 | if (ret != 0) | 757 | if (ret != 0) { |
767 | goto cleanup; | 758 | IP6T_ENTRY_ITERATE(entry0, newinfo->size, |
768 | 759 | cleanup_entry, &i); | |
769 | ret = -ELOOP; | 760 | return ret; |
770 | if (!mark_source_chains(newinfo, valid_hooks, entry0)) | 761 | } |
771 | goto cleanup; | ||
772 | 762 | ||
773 | /* And one copy for every other CPU */ | 763 | /* And one copy for every other CPU */ |
774 | for_each_possible_cpu(i) { | 764 | for_each_possible_cpu(i) { |
@@ -777,9 +767,6 @@ translate_table(const char *name, | |||
777 | } | 767 | } |
778 | 768 | ||
779 | return 0; | 769 | return 0; |
780 | cleanup: | ||
781 | IP6T_ENTRY_ITERATE(entry0, newinfo->size, cleanup_entry, &i); | ||
782 | return ret; | ||
783 | } | 770 | } |
784 | 771 | ||
785 | /* Gets counters. */ | 772 | /* Gets counters. */ |
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index c2e629d6aea4..4ae1b19ada5d 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c | |||
@@ -854,7 +854,8 @@ back_from_confirm: | |||
854 | } | 854 | } |
855 | done: | 855 | done: |
856 | dst_release(dst); | 856 | dst_release(dst); |
857 | release_sock(sk); | 857 | if (!inet->hdrincl) |
858 | release_sock(sk); | ||
858 | out: | 859 | out: |
859 | fl6_sock_release(flowlabel); | 860 | fl6_sock_release(flowlabel); |
860 | return err<0?err:len; | 861 | return err<0?err:len; |