diff options
Diffstat (limited to 'net/netfilter/nft_payload.c')
| -rw-r--r-- | net/netfilter/nft_payload.c | 29 | 
1 files changed, 21 insertions, 8 deletions
diff --git a/net/netfilter/nft_payload.c b/net/netfilter/nft_payload.c index 2e7ac007cb30..eb0e40c29712 100644 --- a/net/netfilter/nft_payload.c +++ b/net/netfilter/nft_payload.c @@ -740,17 +740,23 @@ static int nft_payload_set_init(const struct nft_ctx *ctx,  				const struct nlattr * const tb[])  {  	struct nft_payload_set *priv = nft_expr_priv(expr); +	u32 csum_offset, csum_type = NFT_PAYLOAD_CSUM_NONE; +	int err;  	priv->base        = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_BASE]));  	priv->offset      = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_OFFSET]));  	priv->len         = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_LEN]));  	if (tb[NFTA_PAYLOAD_CSUM_TYPE]) -		priv->csum_type = -			ntohl(nla_get_be32(tb[NFTA_PAYLOAD_CSUM_TYPE])); -	if (tb[NFTA_PAYLOAD_CSUM_OFFSET]) -		priv->csum_offset = -			ntohl(nla_get_be32(tb[NFTA_PAYLOAD_CSUM_OFFSET])); +		csum_type = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_CSUM_TYPE])); +	if (tb[NFTA_PAYLOAD_CSUM_OFFSET]) { +		err = nft_parse_u32_check(tb[NFTA_PAYLOAD_CSUM_OFFSET], U8_MAX, +					  &csum_offset); +		if (err < 0) +			return err; + +		priv->csum_offset = csum_offset; +	}  	if (tb[NFTA_PAYLOAD_CSUM_FLAGS]) {  		u32 flags; @@ -761,7 +767,7 @@ static int nft_payload_set_init(const struct nft_ctx *ctx,  		priv->csum_flags = flags;  	} -	switch (priv->csum_type) { +	switch (csum_type) {  	case NFT_PAYLOAD_CSUM_NONE:  	case NFT_PAYLOAD_CSUM_INET:  		break; @@ -775,6 +781,7 @@ static int nft_payload_set_init(const struct nft_ctx *ctx,  	default:  		return -EOPNOTSUPP;  	} +	priv->csum_type = csum_type;  	return nft_parse_register_load(tb[NFTA_PAYLOAD_SREG], &priv->sreg,  				       priv->len); @@ -833,6 +840,7 @@ nft_payload_select_ops(const struct nft_ctx *ctx,  {  	enum nft_payload_bases base;  	unsigned int offset, len; +	int err;  	if (tb[NFTA_PAYLOAD_BASE] == NULL ||  	    tb[NFTA_PAYLOAD_OFFSET] == NULL || @@ -859,8 +867,13 @@ nft_payload_select_ops(const struct nft_ctx *ctx,  	if (tb[NFTA_PAYLOAD_DREG] == NULL)  		return ERR_PTR(-EINVAL); -	offset = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_OFFSET])); -	len    = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_LEN])); +	err = nft_parse_u32_check(tb[NFTA_PAYLOAD_OFFSET], U8_MAX, &offset); +	if (err < 0) +		return ERR_PTR(err); + +	err = nft_parse_u32_check(tb[NFTA_PAYLOAD_LEN], U8_MAX, &len); +	if (err < 0) +		return ERR_PTR(err);  	if (len <= 4 && is_power_of_2(len) && IS_ALIGNED(offset, len) &&  	    base != NFT_PAYLOAD_LL_HEADER && base != NFT_PAYLOAD_INNER_HEADER)  | 
