aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.osdl.org>2006-12-07 12:05:15 -0500
committerLinus Torvalds <torvalds@woody.osdl.org>2006-12-07 12:05:15 -0500
commit2685b267bce34c9b66626cb11664509c32a761a5 (patch)
treece8b4ad47b4a1aa1b0e7634298d63c4cb0ca46c5 /net/ipv6
parent4522d58275f124105819723e24e912c8e5bf3cdd (diff)
parent272491ef423b6976a230a998b10f46976aa91342 (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.c2
-rw-r--r--net/ipv6/netfilter/ip6_tables.c59
-rw-r--r--net/ipv6/raw.c3
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
511static inline int 525static inline int
512standard_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
532static inline int
533check_match(struct ip6t_entry_match *m, 526check_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;
780cleanup:
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 }
855done: 855done:
856 dst_release(dst); 856 dst_release(dst);
857 release_sock(sk); 857 if (!inet->hdrincl)
858 release_sock(sk);
858out: 859out:
859 fl6_sock_release(flowlabel); 860 fl6_sock_release(flowlabel);
860 return err<0?err:len; 861 return err<0?err:len;