lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <f7t356g5s6f.fsf@redhat.com>
Date:   Tue, 07 Mar 2023 13:31:52 -0500
From:   Aaron Conole <aconole@...hat.com>
To:     Xin Long <lucien.xin@...il.com>
Cc:     netfilter-devel@...r.kernel.org,
        network dev <netdev@...r.kernel.org>,
        Pablo Neira Ayuso <pablo@...filter.org>,
        Jozsef Kadlecsik <kadlec@...filter.org>,
        Florian Westphal <fw@...len.de>, davem@...emloft.net,
        kuba@...nel.org, Eric Dumazet <edumazet@...gle.com>,
        Paolo Abeni <pabeni@...hat.com>,
        Roopa Prabhu <roopa@...dia.com>,
        Nikolay Aleksandrov <razor@...ckwall.org>,
        Pravin B Shelar <pshelar@....org>
Subject: Re: [PATCH nf-next 4/6] netfilter: move br_nf_check_hbh_len to utils

Xin Long <lucien.xin@...il.com> writes:

> Rename br_nf_check_hbh_len() to nf_ip6_check_hbh_len() and move it
> to netfilter utils, so that it can be used by other modules, like
> ovs and tc.
>
> Signed-off-by: Xin Long <lucien.xin@...il.com>
> ---

Reviewed-by: Aaron Conole <aconole@...hat.com>

>  include/linux/netfilter_ipv6.h |  2 ++
>  net/bridge/br_netfilter_ipv6.c | 57 +---------------------------------
>  net/netfilter/utils.c          | 54 ++++++++++++++++++++++++++++++++
>  3 files changed, 57 insertions(+), 56 deletions(-)
>
> diff --git a/include/linux/netfilter_ipv6.h b/include/linux/netfilter_ipv6.h
> index 48314ade1506..7834c0be2831 100644
> --- a/include/linux/netfilter_ipv6.h
> +++ b/include/linux/netfilter_ipv6.h
> @@ -197,6 +197,8 @@ static inline int nf_cookie_v6_check(const struct ipv6hdr *iph,
>  __sum16 nf_ip6_checksum(struct sk_buff *skb, unsigned int hook,
>  			unsigned int dataoff, u_int8_t protocol);
>  
> +int nf_ip6_check_hbh_len(struct sk_buff *skb, u32 *plen);
> +
>  int ipv6_netfilter_init(void);
>  void ipv6_netfilter_fini(void);
>  
> diff --git a/net/bridge/br_netfilter_ipv6.c b/net/bridge/br_netfilter_ipv6.c
> index 07289e4f3213..550039dfc31a 100644
> --- a/net/bridge/br_netfilter_ipv6.c
> +++ b/net/bridge/br_netfilter_ipv6.c
> @@ -40,61 +40,6 @@
>  #include <linux/sysctl.h>
>  #endif
>  
> -/* We only check the length. A bridge shouldn't do any hop-by-hop stuff
> - * anyway
> - */
> -static int br_nf_check_hbh_len(struct sk_buff *skb, u32 *plen)
> -{
> -	int len, off = sizeof(struct ipv6hdr);
> -	unsigned char *nh;
> -	u32 pkt_len = 0;
> -
> -	if (!pskb_may_pull(skb, off + 8))
> -		return -1;
> -	nh = (u8 *)(ipv6_hdr(skb) + 1);
> -	len = (nh[1] + 1) << 3;
> -
> -	if (!pskb_may_pull(skb, off + len))
> -		return -1;
> -	nh = skb_network_header(skb);
> -
> -	off += 2;
> -	len -= 2;
> -	while (len > 0) {
> -		int optlen;
> -
> -		if (nh[off] == IPV6_TLV_PAD1) {
> -			off++;
> -			len--;
> -			continue;
> -		}
> -		if (len < 2)
> -			return -1;
> -		optlen = nh[off + 1] + 2;
> -		if (optlen > len)
> -			return -1;
> -
> -		if (nh[off] == IPV6_TLV_JUMBO) {
> -			if (nh[off + 1] != 4 || (off & 3) != 2)
> -				return -1;
> -			pkt_len = ntohl(*(__be32 *)(nh + off + 2));
> -			if (pkt_len <= IPV6_MAXPLEN ||
> -			    ipv6_hdr(skb)->payload_len)
> -				return -1;
> -			if (pkt_len > skb->len - sizeof(struct ipv6hdr))
> -				return -1;
> -		}
> -		off += optlen;
> -		len -= optlen;
> -	}
> -	if (len)
> -		return -1;
> -
> -	if (pkt_len)
> -		*plen = pkt_len;
> -	return 0;
> -}
> -
>  int br_validate_ipv6(struct net *net, struct sk_buff *skb)
>  {
>  	const struct ipv6hdr *hdr;
> @@ -114,7 +59,7 @@ int br_validate_ipv6(struct net *net, struct sk_buff *skb)
>  		goto inhdr_error;
>  
>  	pkt_len = ntohs(hdr->payload_len);
> -	if (hdr->nexthdr == NEXTHDR_HOP && br_nf_check_hbh_len(skb, &pkt_len))
> +	if (hdr->nexthdr == NEXTHDR_HOP && nf_ip6_check_hbh_len(skb, &pkt_len))
>  		goto drop;
>  
>  	if (pkt_len + ip6h_len > skb->len) {
> diff --git a/net/netfilter/utils.c b/net/netfilter/utils.c
> index 2182d361e273..04f4bd661774 100644
> --- a/net/netfilter/utils.c
> +++ b/net/netfilter/utils.c
> @@ -215,3 +215,57 @@ int nf_reroute(struct sk_buff *skb, struct nf_queue_entry *entry)
>  	}
>  	return ret;
>  }
> +
> +/* Only get and check the lengths, not do any hop-by-hop stuff. */
> +int nf_ip6_check_hbh_len(struct sk_buff *skb, u32 *plen)
> +{
> +	int len, off = sizeof(struct ipv6hdr);
> +	unsigned char *nh;
> +	u32 pkt_len = 0;
> +
> +	if (!pskb_may_pull(skb, off + 8))
> +		return -ENOMEM;
> +	nh = (u8 *)(ipv6_hdr(skb) + 1);
> +	len = (nh[1] + 1) << 3;
> +
> +	if (!pskb_may_pull(skb, off + len))
> +		return -ENOMEM;
> +	nh = skb_network_header(skb);
> +
> +	off += 2;
> +	len -= 2;
> +	while (len > 0) {
> +		int optlen;
> +
> +		if (nh[off] == IPV6_TLV_PAD1) {
> +			off++;
> +			len--;
> +			continue;
> +		}
> +		if (len < 2)
> +			return -EBADMSG;
> +		optlen = nh[off + 1] + 2;
> +		if (optlen > len)
> +			return -EBADMSG;
> +
> +		if (nh[off] == IPV6_TLV_JUMBO) {
> +			if (nh[off + 1] != 4 || (off & 3) != 2)
> +				return -EBADMSG;
> +			pkt_len = ntohl(*(__be32 *)(nh + off + 2));
> +			if (pkt_len <= IPV6_MAXPLEN ||
> +			    ipv6_hdr(skb)->payload_len)
> +				return -EBADMSG;
> +			if (pkt_len > skb->len - sizeof(struct ipv6hdr))
> +				return -EBADMSG;
> +		}
> +		off += optlen;
> +		len -= optlen;
> +	}
> +	if (len)
> +		return -EBADMSG;
> +
> +	if (pkt_len)
> +		*plen = pkt_len;
> +	return 0;
> +}
> +EXPORT_SYMBOL_GPL(nf_ip6_check_hbh_len);

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ