Re: [netfilter-core] [PATCH net] netfilter: nf_tables: fix pointer math issue in nft_byteorder_eval()

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

 



On Tue, Feb 06, 2024 at 12:29:51PM +0100, Pablo Neira Ayuso wrote:
> On Tue, Feb 06, 2024 at 12:11:12PM +0100, Florian Westphal wrote:
> > Michal Kubecek <mkubecek@xxxxxxx> wrote:
> > > I stumbled upon this when the issue got a CVE id (sigh) and I share
> > > Andrea's (Cc-ed) concern that the fix is incomplete. While the fix,
> > > commit c301f0981fdd ("netfilter: nf_tables: fix pointer math issue in
> > > nft_byteorder_eval()") now, fixes the destination side, src is still
> > > a pointer to u32, i.e. we are reading 64-bit values with relative
> > > offsets which are multiples of 32 bits.
> > > 
> > > Shouldn't we fix this as well, e.g. like indicated below?
> > 
> > No, please remove multi-elem support instead, nothing uses this feature.
> 
> See attached patch.
> 
> I posted this:
> 
> https://patchwork.ozlabs.org/project/netfilter-devel/patch/20240202120602.5122-1-pablo@xxxxxxxxxxxxx/
> 
> I can replace it by the attached patch if you prefer. This can only
> help in the future to microoptimize some set configurations, where
> several byteorder can be coalesced into one single expression.

I have to replace those index 'i' by simply dst instead, this is
obviosly incomplete.

> diff --git a/net/netfilter/nft_byteorder.c b/net/netfilter/nft_byteorder.c
> index 8cf91e47fd7a..af3412602869 100644
> --- a/net/netfilter/nft_byteorder.c
> +++ b/net/netfilter/nft_byteorder.c
> @@ -43,18 +43,14 @@ void nft_byteorder_eval(const struct nft_expr *expr,
>  
>  		switch (priv->op) {
>  		case NFT_BYTEORDER_NTOH:
> -			for (i = 0; i < priv->len / 8; i++) {
> -				src64 = nft_reg_load64(&src[i]);
> -				nft_reg_store64(&dst64[i],
> -						be64_to_cpu((__force __be64)src64));
> -			}
> +			src64 = nft_reg_load64(&src[i]);
> +			nft_reg_store64(&dst64[i],
> +					be64_to_cpu((__force __be64)src64));
>  			break;
>  		case NFT_BYTEORDER_HTON:
> -			for (i = 0; i < priv->len / 8; i++) {
> -				src64 = (__force __u64)
> -					cpu_to_be64(nft_reg_load64(&src[i]));
> -				nft_reg_store64(&dst64[i], src64);
> -			}
> +			src64 = (__force __u64)
> +				cpu_to_be64(nft_reg_load64(&src[i]));
> +			nft_reg_store64(&dst64[i], src64);
>  			break;
>  		}
>  		break;
> @@ -62,24 +58,20 @@ void nft_byteorder_eval(const struct nft_expr *expr,
>  	case 4:
>  		switch (priv->op) {
>  		case NFT_BYTEORDER_NTOH:
> -			for (i = 0; i < priv->len / 4; i++)
> -				dst[i] = ntohl((__force __be32)src[i]);
> +			dst[i] = ntohl((__force __be32)src[i]);
>  			break;
>  		case NFT_BYTEORDER_HTON:
> -			for (i = 0; i < priv->len / 4; i++)
> -				dst[i] = (__force __u32)htonl(src[i]);
> +			dst[i] = (__force __u32)htonl(src[i]);
>  			break;
>  		}
>  		break;
>  	case 2:
>  		switch (priv->op) {
>  		case NFT_BYTEORDER_NTOH:
> -			for (i = 0; i < priv->len / 2; i++)
> -				d16[i] = ntohs((__force __be16)s16[i]);
> +			d16[i] = ntohs((__force __be16)s16[i]);
>  			break;
>  		case NFT_BYTEORDER_HTON:
> -			for (i = 0; i < priv->len / 2; i++)
> -				d16[i] = (__force __u16)htons(s16[i]);
> +			d16[i] = (__force __u16)htons(s16[i]);
>  			break;
>  		}
>  		break;
> @@ -137,6 +129,9 @@ static int nft_byteorder_init(const struct nft_ctx *ctx,
>  	if (err < 0)
>  		return err;
>  
> +	if (priv->size != len)
> +		return -EINVAL;
> +
>  	priv->len = len;
>  
>  	if (len % size != 0)





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

  Powered by Linux