Received: by 2002:ac0:a5b6:0:0:0:0:0 with SMTP id m51-v6csp2223021imm; Thu, 7 Jun 2018 07:18:31 -0700 (PDT) X-Google-Smtp-Source: ADUXVKLwHUKU3lYy/O58tq4umYRs2vaK6wtz34x+1lciL7WoAvLPWIorzbXehLy+rghRPFM4kS1h X-Received: by 2002:a63:61d6:: with SMTP id v205-v6mr1769776pgb.432.1528381111621; Thu, 07 Jun 2018 07:18:31 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1528381111; cv=none; d=google.com; s=arc-20160816; b=sD/QuCIRHwtNDKYOmVANcR7HXZeje2fCPCS7PI8vnuvDaIq+7A/G/z9YWkWQp35iRd SMQDMiOpv8nJrw3FSxPAKojWh2vShNVOQsVe4qBMbeCHOfAEqVknmakR11UODwa+ckJ6 aaJGYNREY9vjoZIQDt9KwfePqgQFl14h3ETHXt45H2kTss5ZHGH0v6qQ9vNQCgG0p3nu SY2nqr9L4qx0JbrjJ6wODJ1Map7fl9O3E4Jg/2GdDaNvt4dxQp4jdBWi0tOLYTUkhPj9 Kb92xeauDfZpuQN+cbo00qxuJuSx5EDWDTA8C1sChOVqkwj6qd97q/U5EgnIi3yizgZn vCDg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:in-reply-to:subject:message-id:date:cc:to :from:mime-version:content-transfer-encoding:content-disposition :arc-authentication-results; bh=pgQ2t4Sms3uZX3oIhTTIBKYwIQsiPrIh2VGGj3zjF48=; b=IHXmzCyUjUY6s6gOgat1wfxUTVY35jCrDlaiKoI4OrPskP6DlGXoEWDNV60r3EZ4rG qsB3LJM+PbLj03+QTaH8EX5yle8dg4wXHHq8uHClv9W+x9IEEy32QDhzNZYM+vDQcR/7 AOOd9NIRPHdRRk3Vg+uMXM7so8gI1OHnH446gs9KeRAaPvFSQ6Ins/elXSWMrVo3zgEn S4Yr8ID99q+kjMVu4U2duAQoxv4wATr22gue1KY8yE3+ODV03CeOQfbRFqNc3h6qiyex AF8TBnzW2o0DmGpl0BeymgWUtMXZiKtNH6w8AsQxxWmXIwPDul4X893W3VKcqJogfyfb CQcA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id f13-v6si8049558pgo.265.2018.06.07.07.18.17; Thu, 07 Jun 2018 07:18:31 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933301AbeFGOQS (ORCPT + 99 others); Thu, 7 Jun 2018 10:16:18 -0400 Received: from shadbolt.e.decadent.org.uk ([88.96.1.126]:39583 "EHLO shadbolt.e.decadent.org.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932919AbeFGOJP (ORCPT ); Thu, 7 Jun 2018 10:09:15 -0400 Received: from [148.252.241.226] (helo=deadeye) by shadbolt.decadent.org.uk with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.84_2) (envelope-from ) id 1fQvbF-0005Zs-La; Thu, 07 Jun 2018 15:09:13 +0100 Received: from ben by deadeye with local (Exim 4.91) (envelope-from ) id 1fQvbC-0003Dx-Ez; Thu, 07 Jun 2018 15:09:10 +0100 Content-Type: text/plain; charset="UTF-8" Content-Disposition: inline Content-Transfer-Encoding: 8bit MIME-Version: 1.0 From: Ben Hutchings To: linux-kernel@vger.kernel.org, stable@vger.kernel.org CC: akpm@linux-foundation.org, "Florian Westphal" , "Pablo Neira Ayuso" , "" , "Eric Dumazet" Date: Thu, 07 Jun 2018 15:05:21 +0100 Message-ID: X-Mailer: LinuxStableQueue (scripts by bwh) Subject: [PATCH 3.16 345/410] netfilter: bridge: ebt_among: add more missing match size checks In-Reply-To: X-SA-Exim-Connect-IP: 148.252.241.226 X-SA-Exim-Mail-From: ben@decadent.org.uk X-SA-Exim-Scanned: No (on shadbolt.decadent.org.uk); SAEximRunCond expanded to false Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 3.16.57-rc1 review patch. If anyone has any objections, please let me know. ------------------ From: Florian Westphal commit c8d70a700a5b486bfa8e5a7d33d805389f6e59f9 upstream. ebt_among is special, it has a dynamic match size and is exempt from the central size checks. commit c4585a2823edf ("bridge: ebt_among: add missing match size checks") added validation for pool size, but missed fact that the macros ebt_among_wh_src/dst can already return out-of-bound result because they do not check value of wh_src/dst_ofs (an offset) vs. the size of the match that userspace gave to us. v2: check that offset has correct alignment. Paolo Abeni points out that we should also check that src/dst wormhash arrays do not overlap, and src + length lines up with start of dst (or vice versa). v3: compact wormhash_sizes_valid() part NB: Fixes tag is intentionally wrong, this bug exists from day one when match was added for 2.6 kernel. Tag is there so stable maintainers will notice this one too. Tested with same rules from the earlier patch. Fixes: c4585a2823edf ("bridge: ebt_among: add missing match size checks") Reported-by: Signed-off-by: Florian Westphal Reviewed-by: Eric Dumazet Signed-off-by: Pablo Neira Ayuso Signed-off-by: Ben Hutchings --- net/bridge/netfilter/ebt_among.c | 34 ++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) --- a/net/bridge/netfilter/ebt_among.c +++ b/net/bridge/netfilter/ebt_among.c @@ -177,6 +177,28 @@ static bool poolsize_invalid(const struc return w && w->poolsize >= (INT_MAX / sizeof(struct ebt_mac_wormhash_tuple)); } +static bool wormhash_offset_invalid(int off, unsigned int len) +{ + if (off == 0) /* not present */ + return false; + + if (off < (int)sizeof(struct ebt_among_info) || + off % __alignof__(struct ebt_mac_wormhash)) + return true; + + off += sizeof(struct ebt_mac_wormhash); + + return off > len; +} + +static bool wormhash_sizes_valid(const struct ebt_mac_wormhash *wh, int a, int b) +{ + if (a == 0) + a = sizeof(struct ebt_among_info); + + return ebt_mac_wormhash_size(wh) + a == b; +} + static int ebt_among_mt_check(const struct xt_mtchk_param *par) { const struct ebt_among_info *info = par->matchinfo; @@ -189,6 +211,10 @@ static int ebt_among_mt_check(const stru if (expected_length > em->match_size) return -EINVAL; + if (wormhash_offset_invalid(info->wh_dst_ofs, em->match_size) || + wormhash_offset_invalid(info->wh_src_ofs, em->match_size)) + return -EINVAL; + wh_dst = ebt_among_wh_dst(info); if (poolsize_invalid(wh_dst)) return -EINVAL; @@ -201,6 +227,14 @@ static int ebt_among_mt_check(const stru if (poolsize_invalid(wh_src)) return -EINVAL; + if (info->wh_src_ofs < info->wh_dst_ofs) { + if (!wormhash_sizes_valid(wh_src, info->wh_src_ofs, info->wh_dst_ofs)) + return -EINVAL; + } else { + if (!wormhash_sizes_valid(wh_dst, info->wh_dst_ofs, info->wh_src_ofs)) + return -EINVAL; + } + expected_length += ebt_mac_wormhash_size(wh_src); if (em->match_size != EBT_ALIGN(expected_length)) {