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=unavailable 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 1B024C49ED6 for ; Mon, 28 Jun 2021 14:54:22 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 058CB61C8F for ; Mon, 28 Jun 2021 14:54:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236781AbhF1O4D (ORCPT ); Mon, 28 Jun 2021 10:56:03 -0400 Received: from mail.kernel.org ([198.145.29.99]:51760 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234787AbhF1OmH (ORCPT ); Mon, 28 Jun 2021 10:42:07 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id AEE5461C78; Mon, 28 Jun 2021 14:33:36 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1624890817; bh=eemzLOynjJYmeBT75YBEiDabzrnXq6KUkKeHGEq/ONM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=dssAfWvIPzKV/bxFIclXc5VXMSF9qASi+qo0oWuAenLIsUmahcXPu0XwE8B6XkHNF IYQi0CCARnl0eegrEgjhJ5xOMhhAXWCLKUskfPKxU8CDTvOjOOax8zvbHVATpbRHPA 62cJa05IZwJiNXTMFT2hnzRVyCHq16zy8pmcw7vjFLCDqcg0LTPs8xvyEp8bRsb3cY oB2S3w0Sn7CU9Dx2g2i7J85PFXXF2tVIJ6MW90XknTgGG6kgcJOg2eEc0wDwKTtZqh zbXXsatecPTjoKcV9rVmDK8M/EyWuALqAG7EBNsuRj21HvummX06WTOXUYfum5JL0j 2x3khIsfF/SSw== 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.19 033/109] netfilter: synproxy: Fix out of bounds when parsing TCP options Date: Mon, 28 Jun 2021 10:31:49 -0400 Message-Id: <20210628143305.32978-34-sashal@kernel.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210628143305.32978-1-sashal@kernel.org> References: <20210628143305.32978-1-sashal@kernel.org> MIME-Version: 1.0 X-KernelTest-Patch: http://kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.19.196-rc1.gz X-KernelTest-Tree: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git X-KernelTest-Branch: linux-4.19.y X-KernelTest-Patches: git://git.kernel.org/pub/scm/linux/kernel/git/stable/stable-queue.git X-KernelTest-Version: 4.19.196-rc1 X-KernelTest-Deadline: 2021-06-30T14:32+00:00 X-stable: review X-Patchwork-Hint: Ignore Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@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 353a2aa80c3c..04b07b63c540 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