]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
netfilter: nft_payload: reject offsets exceeding 65535 bytes
authorFlorian Westphal <fw@strlen.de>
Thu, 18 Jun 2026 04:58:24 +0000 (06:58 +0200)
committerPablo Neira Ayuso <pablo@netfilter.org>
Sat, 20 Jun 2026 22:18:26 +0000 (00:18 +0200)
Large offsets were rejected based on netlink policy, but blamed commit
removed the policy without updating nft_payload_inner_init() to use the
truncation-check helper.

Silent truncation is not a problem, but not wanted either, so add a
check.

Fixes: 077dc4a27579 ("netfilter: nft_payload: extend offset to 65535 bytes")
Signed-off-by: Florian Westphal <fw@strlen.de>
Reviewed-by: Fernando Fernandez Mancera <fmancera@suse.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
net/netfilter/nft_payload.c

index ef2a80dfc68f951d8faa9908f23a8a8d38249cac..345eff140d56f87eb211370380689f5a6efc0aa7 100644 (file)
@@ -224,11 +224,17 @@ static int nft_payload_init(const struct nft_ctx *ctx,
                            const struct nlattr * const tb[])
 {
        struct nft_payload *priv = nft_expr_priv(expr);
+       u32 offset;
+       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]));
 
+       err = nft_parse_u32_check(tb[NFTA_PAYLOAD_OFFSET], U16_MAX, &offset);
+       if (err < 0)
+               return err;
+       priv->offset = offset;
+
        return nft_parse_register_store(ctx, tb[NFTA_PAYLOAD_DREG],
                                        &priv->dreg, NULL, NFT_DATA_VALUE,
                                        priv->len);
@@ -621,7 +627,8 @@ static int nft_payload_inner_init(const struct nft_ctx *ctx,
                                  const struct nlattr * const tb[])
 {
        struct nft_payload *priv = nft_expr_priv(expr);
-       u32 base;
+       u32 base, offset;
+       int err;
 
        if (!tb[NFTA_PAYLOAD_BASE] || !tb[NFTA_PAYLOAD_OFFSET] ||
            !tb[NFTA_PAYLOAD_LEN] || !tb[NFTA_PAYLOAD_DREG])
@@ -639,8 +646,11 @@ static int nft_payload_inner_init(const struct nft_ctx *ctx,
        }
 
        priv->base   = base;
-       priv->offset = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_OFFSET]));
        priv->len    = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_LEN]));
+       err = nft_parse_u32_check(tb[NFTA_PAYLOAD_OFFSET], U16_MAX, &offset);
+       if (err < 0)
+               return err;
+       priv->offset = offset;
 
        return nft_parse_register_store(ctx, tb[NFTA_PAYLOAD_DREG],
                                        &priv->dreg, NULL, NFT_DATA_VALUE,