Re: [PATCH libnetfilter_queue] src: fix IPv6 header handling

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




On 09.02.21, 17:33, "Pablo Neira Ayuso" <pablo@xxxxxxxxxxxxx> wrote:

Thanks for looking into this.

> Note: nfq_ip6_set_transport_header() is very much similar to
> ipv6_skip_exthdr() in the Linux kernel, see net/ipv6/exthdrs_core.c

I submitted a revised version that uses similar logic as in the kernel
to exit the loop once extension headers are fully processed.

> >  		uint32_t hdrlen;
> >  
> >  		/* No more extensions, we're done. */
> > -		if (nexthdr == IPPROTO_NONE) {
> > +		if (nexthdr == IPPROTO_TCP || nexthdr == IPPROTO_UDP || nexthdr == IPPROTO_ESP ||
> > +		        nexthdr == IPPROTO_ICMPV6 || nexthdr == IPPROTO_NONE) {
> >  			cur = NULL;
> >  			break;
> >  		}
> > @@ -107,7 +108,7 @@ int nfq_ip6_set_transport_header(struct pkt_buff *pktb, struct ip6_hdr *ip6h,
> >  		} else if (nexthdr == IPPROTO_AH)
> >  			hdrlen = (ip6_ext->ip6e_len + 2) << 2;
> >  		else
> > -			hdrlen = ip6_ext->ip6e_len;
> > +			hdrlen = (ip6_ext->ip6e_len + 1) << 3;
>
> This looks correct, IPv6 optlen is miscalculated.
>
> The chunk above to stop the iteration, so I think the chunk that fixes
> optlen is sufficient to fix the bug.

The optlen fix is not sufficient when a non-existent 'target' is given.
For example, if a UDP packet is passed with 'target' IPPROTO_TCP,
the loop will go on and attempt to interpret the UDP packet body
as another IP extension header. Instead, by exiting the loop also
when all extension headers are processed, the function will now return
0 in that case, as documented in the header file.

Thanks

Etan






[Index of Archives]     [Netfitler Users]     [Berkeley Packet Filter]     [LARTC]     [Bugtraq]     [Yosemite Forum]

  Powered by Linux