From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9758F17332B; Wed, 3 Jul 2024 10:53:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1720003987; cv=none; b=i0IzcC69FuR7pYBKb3ejcApC8cKWzUnnMFtpMuR4OQv2EMBpYixoiZm4ecctgh3+x3xF+JIoG6d2FwLsV4bfj1YM4MMUpxs6tEkyqGeOmmLvUovWJfNwyMvAQjs+OktPgdxVkSp1hVVkR2dXx6+F7JX66tE2g6HouvxH5YW7ZwE= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1720003987; c=relaxed/simple; bh=oLUA3HFChwyZeEnrXFe/6zE+OCuTQwOuOaODR1ycWIg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=OCQTvEHG+nZekogxVjloJYmW+uzX7rKMRw9WbR2K/1Je9zAVUFhgUUDPUY0E3z2B6mT3Y/MG3NH8E2HlfjN+UChfYQuX3aAplyG2njOevtF+S2ZgTNMW3vcie/+IbMHnEgasHdN/2s4hG2hOjOt6lbFHz0Nec5XcIlz1+xR+1vw= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b=jpc1M73/; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b="jpc1M73/" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 18131C2BD10; Wed, 3 Jul 2024 10:53:06 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1720003987; bh=oLUA3HFChwyZeEnrXFe/6zE+OCuTQwOuOaODR1ycWIg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=jpc1M73/Ykjc87CIwkmgDIS5bgZabFsbPbFiJkNZ5zbOr5XQTxUpaCfPSfBCc49r5 kco/sYsUmT91Ub0YvOQVzpi0PNtt6oUoS+VPy0dqLpb/7hcOP7zzze59Pj6yEihogA d2cpkMBEjKPtAMCpZVipZuKU3UMzy4uiTWoYZWvs= From: Greg Kroah-Hartman To: stable@vger.kernel.org Cc: Greg Kroah-Hartman , patches@lists.linux.dev, Florian Westphal , Pablo Neira Ayuso Subject: [PATCH 5.4 085/189] netfilter: nftables: exthdr: fix 4-byte stack OOB write Date: Wed, 3 Jul 2024 12:39:06 +0200 Message-ID: <20240703102844.709345926@linuxfoundation.org> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240703102841.492044697@linuxfoundation.org> References: <20240703102841.492044697@linuxfoundation.org> User-Agent: quilt/0.67 X-stable: review X-Patchwork-Hint: ignore Precedence: bulk X-Mailing-List: stable@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 5.4-stable review patch. If anyone has any objections, please let me know. ------------------ From: Florian Westphal commit fd94d9dadee58e09b49075240fe83423eb1dcd36 upstream. If priv->len is a multiple of 4, then dst[len / 4] can write past the destination array which leads to stack corruption. This construct is necessary to clean the remainder of the register in case ->len is NOT a multiple of the register size, so make it conditional just like nft_payload.c does. The bug was added in 4.1 cycle and then copied/inherited when tcp/sctp and ip option support was added. Bug reported by Zero Day Initiative project (ZDI-CAN-21950, ZDI-CAN-21951, ZDI-CAN-21961). Fixes: 49499c3e6e18 ("netfilter: nf_tables: switch registers to 32 bit addressing") Fixes: 935b7f643018 ("netfilter: nft_exthdr: add TCP option matching") Fixes: 133dc203d77d ("netfilter: nft_exthdr: Support SCTP chunks") Fixes: dbb5281a1f84 ("netfilter: nf_tables: add support for matching IPv4 options") Signed-off-by: Florian Westphal Signed-off-by: Pablo Neira Ayuso Signed-off-by: Greg Kroah-Hartman --- net/netfilter/nft_exthdr.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) --- a/net/netfilter/nft_exthdr.c +++ b/net/netfilter/nft_exthdr.c @@ -33,6 +33,14 @@ static unsigned int optlen(const u8 *opt return opt[offset + 1]; } +static int nft_skb_copy_to_reg(const struct sk_buff *skb, int offset, u32 *dest, unsigned int len) +{ + if (len % NFT_REG32_SIZE) + dest[len / NFT_REG32_SIZE] = 0; + + return skb_copy_bits(skb, offset, dest, len); +} + static void nft_exthdr_ipv6_eval(const struct nft_expr *expr, struct nft_regs *regs, const struct nft_pktinfo *pkt) @@ -54,8 +62,7 @@ static void nft_exthdr_ipv6_eval(const s } offset += priv->offset; - dest[priv->len / NFT_REG32_SIZE] = 0; - if (skb_copy_bits(pkt->skb, offset, dest, priv->len) < 0) + if (nft_skb_copy_to_reg(pkt->skb, offset, dest, priv->len) < 0) goto err; return; err: @@ -151,8 +158,7 @@ static void nft_exthdr_ipv4_eval(const s } offset += priv->offset; - dest[priv->len / NFT_REG32_SIZE] = 0; - if (skb_copy_bits(pkt->skb, offset, dest, priv->len) < 0) + if (nft_skb_copy_to_reg(pkt->skb, offset, dest, priv->len) < 0) goto err; return; err: @@ -208,7 +214,8 @@ static void nft_exthdr_tcp_eval(const st if (priv->flags & NFT_EXTHDR_F_PRESENT) { *dest = 1; } else { - dest[priv->len / NFT_REG32_SIZE] = 0; + if (priv->len % NFT_REG32_SIZE) + dest[priv->len / NFT_REG32_SIZE] = 0; memcpy(dest, opt + offset, priv->len); }