From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-19.4 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id A58BAC49EAB for ; Mon, 28 Jun 2021 14:49:04 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 8C042619AD for ; Mon, 28 Jun 2021 14:49:04 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234249AbhF1Ov1 (ORCPT ); Mon, 28 Jun 2021 10:51:27 -0400 Received: from mail.kernel.org ([198.145.29.99]:53670 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236457AbhF1OtX (ORCPT ); Mon, 28 Jun 2021 10:49:23 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 207A461D22; Mon, 28 Jun 2021 14:36:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1624891014; bh=h09FyihdMQ+8qBwG/JCco+Ksho2nEcWP+G1jmPejVH0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=jPv3BtzU2KK60KlgQpbX5vkizpW6pb8eOe23+fS6rU4V2gwKCVewVIaQHa7WP78mf V3toCjCg2da76CmNd3Q8rextN3bL1Cx7obajXXbaLp704iBxnp16mkMS4iMvZYAjSx p6We4967dwc3jP6T7NNC+VX3AoJdZrZNrwG1cEpCcfBlaWLinr2h2Zd4V3kIYWox07 Bzg0QyEiLom0wUI3mgzcH2yuC8d2tvVOGzl2xQ3QQTyd4h2wO6/EuegPe75BNGC5LX YtBdWhqieb2MvpOuPBXFTWQoEg7FrAgPr2/j7StsbtkD+es/Moys72LwfqtCFWOvZu KIL+hs7o98L8Q== From: Sasha Levin To: linux-kernel@vger.kernel.org, stable@vger.kernel.org Cc: Maxim Mikityanskiy , Young Xiao <92siuyang@gmail.com>, Florian Westphal , "David S . Miller" , Sasha Levin Subject: [PATCH 4.14 27/88] netfilter: synproxy: Fix out of bounds when parsing TCP options Date: Mon, 28 Jun 2021 10:35:27 -0400 Message-Id: <20210628143628.33342-28-sashal@kernel.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210628143628.33342-1-sashal@kernel.org> References: <20210628143628.33342-1-sashal@kernel.org> MIME-Version: 1.0 X-KernelTest-Patch: http://kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.14.238-rc1.gz X-KernelTest-Tree: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git X-KernelTest-Branch: linux-4.14.y X-KernelTest-Patches: git://git.kernel.org/pub/scm/linux/kernel/git/stable/stable-queue.git X-KernelTest-Version: 4.14.238-rc1 X-KernelTest-Deadline: 2021-06-30T14:36+00:00 X-stable: review X-Patchwork-Hint: Ignore Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: stable@vger.kernel.org From: Maxim Mikityanskiy [ Upstream commit 5fc177ab759418c9537433e63301096e733fb915 ] The TCP option parser in synproxy (synproxy_parse_options) could read one byte out of bounds. When the length is 1, the execution flow gets into the loop, reads one byte of the opcode, and if the opcode is neither TCPOPT_EOL nor TCPOPT_NOP, it reads one more byte, which exceeds the length of 1. This fix is inspired by commit 9609dad263f8 ("ipv4: tcp_input: fix stack out of bounds when parsing TCP options."). v2 changes: Added an early return when length < 0 to avoid calling skb_header_pointer with negative length. Cc: Young Xiao <92siuyang@gmail.com> Fixes: 48b1de4c110a ("netfilter: add SYNPROXY core/target") Signed-off-by: Maxim Mikityanskiy Reviewed-by: Florian Westphal Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- net/netfilter/nf_synproxy_core.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/net/netfilter/nf_synproxy_core.c b/net/netfilter/nf_synproxy_core.c index 49bd8bb16b18..9ff26eb0309a 100644 --- a/net/netfilter/nf_synproxy_core.c +++ b/net/netfilter/nf_synproxy_core.c @@ -34,6 +34,9 @@ synproxy_parse_options(const struct sk_buff *skb, unsigned int doff, int length = (th->doff * 4) - sizeof(*th); u8 buf[40], *ptr; + if (unlikely(length < 0)) + return false; + ptr = skb_header_pointer(skb, doff + sizeof(*th), length, buf); if (ptr == NULL) return false; @@ -50,6 +53,8 @@ synproxy_parse_options(const struct sk_buff *skb, unsigned int doff, length--; continue; default: + if (length < 2) + return true; opsize = *ptr++; if (opsize < 2) return true; -- 2.30.2