--- zzzz-none-000/linux-2.6.19.2/net/ipv6/netfilter/ip6_tables.c 2007-01-10 19:10:37.000000000 +0000 +++ davinci-8020-5505/linux-2.6.19.2/net/ipv6/netfilter/ip6_tables.c 2007-01-19 14:42:56.000000000 +0000 @@ -111,7 +111,7 @@ const char *outdev, const struct ip6t_ip6 *ip6info, unsigned int *protoff, - int *fragoff, int *hotdrop) + int *fragoff) { size_t i; unsigned long ret; @@ -169,11 +169,9 @@ unsigned short _frag_off; protohdr = ipv6_find_hdr(skb, protoff, -1, &_frag_off); - if (protohdr < 0) { - if (_frag_off == 0) - *hotdrop = 1; + if (protohdr < 0) return 0; - } + *fragoff = _frag_off; dprintf("Packet protocol %hi ?= %s%hi.\n", @@ -292,7 +290,7 @@ IP_NF_ASSERT(e); IP_NF_ASSERT(back); if (ip6_packet_match(*pskb, indev, outdev, &e->ipv6, - &protoff, &offset, &hotdrop)) { + &protoff, &offset)) { struct ip6t_entry_target *t; if (IP6T_MATCH_ITERATE(e, do_match, @@ -579,19 +577,12 @@ return -EINVAL; } - if (e->target_offset + sizeof(struct ip6t_entry_target) > - e->next_offset) - return -EINVAL; - j = 0; ret = IP6T_MATCH_ITERATE(e, check_match, name, &e->ipv6, e->comefrom, &j); if (ret != 0) goto cleanup_matches; t = ip6t_get_target(e); - ret = -EINVAL; - if (e->target_offset + t->u.target_size > e->next_offset) - goto cleanup_matches; target = try_then_request_module(xt_find_target(AF_INET6, t->u.user.name, t->u.user.revision), @@ -756,7 +747,7 @@ if (ret != 0) { IP6T_ENTRY_ITERATE(entry0, newinfo->size, - cleanup_entry, &i); + cleanup_entry, &i); return ret; } @@ -766,7 +757,7 @@ memcpy(newinfo->entries[i], entry0, newinfo->size); } - return 0; + return ret; } /* Gets counters. */ @@ -1435,9 +1426,6 @@ * If target header is found, its offset is set in *offset and return protocol * number. Otherwise, return -1. * - * If the first fragment doesn't contain the final protocol header or - * NEXTHDR_NONE it is considered invalid. - * * Note that non-1st fragment is special case that "the protocol number * of last header" is "next header" field in Fragment header. In this case, * *offset is meaningless and fragment offset is stored in *fragoff if fragoff @@ -1461,12 +1449,12 @@ if ((!ipv6_ext_hdr(nexthdr)) || nexthdr == NEXTHDR_NONE) { if (target < 0) break; - return -ENOENT; + return -1; } hp = skb_header_pointer(skb, start, sizeof(_hdr), &_hdr); if (hp == NULL) - return -EBADMSG; + return -1; if (nexthdr == NEXTHDR_FRAGMENT) { unsigned short _frag_off, *fp; fp = skb_header_pointer(skb, @@ -1475,18 +1463,18 @@ sizeof(_frag_off), &_frag_off); if (fp == NULL) - return -EBADMSG; + return -1; _frag_off = ntohs(*fp) & ~0x7; if (_frag_off) { if (target < 0 && ((!ipv6_ext_hdr(hp->nexthdr)) || - hp->nexthdr == NEXTHDR_NONE)) { + nexthdr == NEXTHDR_NONE)) { if (fragoff) *fragoff = _frag_off; return hp->nexthdr; } - return -ENOENT; + return -1; } hdrlen = 8; } else if (nexthdr == NEXTHDR_AUTH)