nft_exthdr_init() passes user-controlled priv->len to nft_parse_register_store(), which marks that many bytes in the register bitmap as initialized. However, when NFT_EXTHDR_F_PRESENT is set, the eval paths write only 1 byte (nft_reg_store8) or 4 bytes (*dest = 0 on TCP/DCCP error path). When len > 4, registers beyond the first are never written, retaining uninitialized stack data from nft_regs. Bail out if userspace requests too much data when F_PRESENT is set. Reported-by: Ji'an Zhou Fixes: c078ca3b0c5b ("netfilter: nft_exthdr: Add support for existence check") Signed-off-by: Florian Westphal --- v2: reject rule add instead of silent 'len = 1'. net/netfilter/nft_exthdr.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/net/netfilter/nft_exthdr.c b/net/netfilter/nft_exthdr.c index e6a07c0df207..b6cca7c947a2 100644 --- a/net/netfilter/nft_exthdr.c +++ b/net/netfilter/nft_exthdr.c @@ -532,6 +532,9 @@ static int nft_exthdr_init(const struct nft_ctx *ctx, return err; } + if ((priv->flags & NFT_EXTHDR_F_PRESENT) && len != 1) + return -EINVAL; + priv->type = nla_get_u8(tb[NFTA_EXTHDR_TYPE]); priv->offset = offset; priv->len = len; -- 2.53.0