Received: by 2002:a05:6a10:1d13:0:0:0:0 with SMTP id pp19csp331115pxb; Mon, 16 Aug 2021 06:29:36 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxzwJqfZn3Ims8BO8xjsBtGWFAMZbWnT1sKOcCmunJJE7/nxBCNwGz4V2TEIOy9FAMh0Ldi X-Received: by 2002:aa7:d5c8:: with SMTP id d8mr20400830eds.110.1629120576576; Mon, 16 Aug 2021 06:29:36 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1629120576; cv=none; d=google.com; s=arc-20160816; b=gF93sdOsue+f0ivf8bs5ZQyO+Q6/HIF8mictL3Bm4E+at8xN+y2bBBrM4AJBpIS75p P5r6IOtTigsYN/vpHYcBoiM1Z4Dlahuo41745RqABDu8yqbL3TELCF9Vw3+a+0Jpng5y mlKl9ReP+gdkazhrMdkv0wf90YTlYCn0Hmvw0//4kb7QPuExDMeeRPbTAB9SQUnPN8ct i7g8eHsgoKhNnzq4whGVCqUnqBWQ+TIS79kDhZL6rc5c8JaG+omEbF+c2TMzVI3Di2Cz yejRsLIWDUw6FwV+zIO1bkdsYkU16nu73tvQN2QmyVjlERlr9ruP4F8Hg6VlWhf0O887 k3Ng== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=MSc654yyQC6fyAH8vGsl6lzdy6Uzci53lA7zkLboiuE=; b=HUBCulYSCIjzgttV0emJgUJXnC8smFOHluqznRk+f+egieV8FvV6MI8lmrPoaGrpq7 MGV4fafAuoyoXUmZ9KTCoseriIZ1ILNnV7wie3fSr4QWoKUVjjXGh4+MC0BD8fetQngB aJReHj7cS/c2PogBAKK2CHsRlScJeJUSPdqz04bYzAWZY194LRN2PuOuPsnVN8V2l3No tSQOJzdD13AojTeIUPNr7AxeJC4xa2lcthjNPdEhMrMPGe72GstLqtZ0LgvikkGbLqls DUq75FdKE8AY5/sfXjYfXImZSaXFMle3RF6TuHRoyBG9wX5vMTb3b7uHIngd2x8Vrys2 Ag4g== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=T1RmlD9B; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id j1si10741984edt.69.2021.08.16.06.29.13; Mon, 16 Aug 2021 06:29:36 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=T1RmlD9B; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241331AbhHPN0s (ORCPT + 99 others); Mon, 16 Aug 2021 09:26:48 -0400 Received: from mail.kernel.org ([198.145.29.99]:43352 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240071AbhHPNQq (ORCPT ); Mon, 16 Aug 2021 09:16:46 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id B830A632F8; Mon, 16 Aug 2021 13:13:41 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1629119622; bh=8n7fKA6o2yylu2ozHvI9dzT6Y9m7/8bAE62WE4O1QCE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=T1RmlD9BGml+RK+hTntTpQWIRdhYT3XYAoX++rmHnnqwoUyJNRyrtX+z05wEal6Ii lDODPLk0X9/5X+xsG0l7/n+imJGGVRJe3dzIO78J1t8NT/X4ZikUuhqF+nbpGIuYpT ERhE7g7GdK4ZrumyOkCBqDLVQbZJ7/2w0gsXKSiU= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Tatsuhiko Yasumatsu , Daniel Borkmann , Sasha Levin Subject: [PATCH 5.13 064/151] bpf: Fix integer overflow involving bucket_size Date: Mon, 16 Aug 2021 15:01:34 +0200 Message-Id: <20210816125446.176472058@linuxfoundation.org> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20210816125444.082226187@linuxfoundation.org> References: <20210816125444.082226187@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Tatsuhiko Yasumatsu [ Upstream commit c4eb1f403243fc7bbb7de644db8587c03de36da6 ] In __htab_map_lookup_and_delete_batch(), hash buckets are iterated over to count the number of elements in each bucket (bucket_size). If bucket_size is large enough, the multiplication to calculate kvmalloc() size could overflow, resulting in out-of-bounds write as reported by KASAN: [...] [ 104.986052] BUG: KASAN: vmalloc-out-of-bounds in __htab_map_lookup_and_delete_batch+0x5ce/0xb60 [ 104.986489] Write of size 4194224 at addr ffffc9010503be70 by task crash/112 [ 104.986889] [ 104.987193] CPU: 0 PID: 112 Comm: crash Not tainted 5.14.0-rc4 #13 [ 104.987552] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.13.0-1ubuntu1.1 04/01/2014 [ 104.988104] Call Trace: [ 104.988410] dump_stack_lvl+0x34/0x44 [ 104.988706] print_address_description.constprop.0+0x21/0x140 [ 104.988991] ? __htab_map_lookup_and_delete_batch+0x5ce/0xb60 [ 104.989327] ? __htab_map_lookup_and_delete_batch+0x5ce/0xb60 [ 104.989622] kasan_report.cold+0x7f/0x11b [ 104.989881] ? __htab_map_lookup_and_delete_batch+0x5ce/0xb60 [ 104.990239] kasan_check_range+0x17c/0x1e0 [ 104.990467] memcpy+0x39/0x60 [ 104.990670] __htab_map_lookup_and_delete_batch+0x5ce/0xb60 [ 104.990982] ? __wake_up_common+0x4d/0x230 [ 104.991256] ? htab_of_map_free+0x130/0x130 [ 104.991541] bpf_map_do_batch+0x1fb/0x220 [...] In hashtable, if the elements' keys have the same jhash() value, the elements will be put into the same bucket. By putting a lot of elements into a single bucket, the value of bucket_size can be increased to trigger the integer overflow. Triggering the overflow is possible for both callers with CAP_SYS_ADMIN and callers without CAP_SYS_ADMIN. It will be trivial for a caller with CAP_SYS_ADMIN to intentionally reach this overflow by enabling BPF_F_ZERO_SEED. As this flag will set the random seed passed to jhash() to 0, it will be easy for the caller to prepare keys which will be hashed into the same value, and thus put all the elements into the same bucket. If the caller does not have CAP_SYS_ADMIN, BPF_F_ZERO_SEED cannot be used. However, it will be still technically possible to trigger the overflow, by guessing the random seed value passed to jhash() (32bit) and repeating the attempt to trigger the overflow. In this case, the probability to trigger the overflow will be low and will take a very long time. Fix the integer overflow by calling kvmalloc_array() instead of kvmalloc() to allocate memory. Fixes: 057996380a42 ("bpf: Add batch ops to all htab bpf map") Signed-off-by: Tatsuhiko Yasumatsu Signed-off-by: Daniel Borkmann Link: https://lore.kernel.org/bpf/20210806150419.109658-1-th.yasumatsu@gmail.com Signed-off-by: Sasha Levin --- kernel/bpf/hashtab.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kernel/bpf/hashtab.c b/kernel/bpf/hashtab.c index d7ebb12ffffc..49857e8cd6ce 100644 --- a/kernel/bpf/hashtab.c +++ b/kernel/bpf/hashtab.c @@ -1464,8 +1464,8 @@ alloc: /* We cannot do copy_from_user or copy_to_user inside * the rcu_read_lock. Allocate enough space here. */ - keys = kvmalloc(key_size * bucket_size, GFP_USER | __GFP_NOWARN); - values = kvmalloc(value_size * bucket_size, GFP_USER | __GFP_NOWARN); + keys = kvmalloc_array(key_size, bucket_size, GFP_USER | __GFP_NOWARN); + values = kvmalloc_array(value_size, bucket_size, GFP_USER | __GFP_NOWARN); if (!keys || !values) { ret = -ENOMEM; goto after_loop; -- 2.30.2