From patchwork Fri Sep 6 06:14:38 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Koichiro Den X-Patchwork-Id: 1981548 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.ubuntu.com (client-ip=185.125.189.65; helo=lists.ubuntu.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=patchwork.ozlabs.org) Received: from lists.ubuntu.com (lists.ubuntu.com [185.125.189.65]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4X0QvR6clqz1ygP for ; Fri, 6 Sep 2024 16:15:31 +1000 (AEST) Received: from localhost ([127.0.0.1] helo=lists.ubuntu.com) by lists.ubuntu.com with esmtp (Exim 4.86_2) (envelope-from ) id 1smSFc-00065i-CE; Fri, 06 Sep 2024 06:15:20 +0000 Received: from smtp-relay-internal-0.internal ([10.131.114.225] helo=smtp-relay-internal-0.canonical.com) by lists.ubuntu.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1smSFa-00065F-9m for kernel-team@lists.ubuntu.com; Fri, 06 Sep 2024 06:15:18 +0000 Received: from mail-pl1-f199.google.com (mail-pl1-f199.google.com [209.85.214.199]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-internal-0.canonical.com (Postfix) with ESMTPS id C564C3F45F for ; Fri, 6 Sep 2024 06:15:17 +0000 (UTC) Received: by mail-pl1-f199.google.com with SMTP id d9443c01a7336-2054ff12bb9so19477285ad.1 for ; Thu, 05 Sep 2024 23:15:17 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1725603315; x=1726208115; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=ad/Y/vOqLE0w8v/j2hnZBvEBglqgF64XKZSqLHNeKf8=; b=uF3Kfmt3ehksh7F7zWI9g5h0GiQ/Wdefq0faFuoLhOglfaVF5Ct/nxhbQyIWz2IW4a nCvifKnZFM51uv0/XBz8pCbRCdooQcC18/CGty3+uZ9MBwCecUeJq78+dR77FFzk76mV JMJwuPc/x0qe4MBpm/caKBrKwVzOJIeOTENEeNYr1U/tu35gKHwgBwHOfe/iSQvvCd5c OzH8Rm+D9sw3m+WkP1dJwSda81F5Eow37hsF+m6L6PqgE3DY6ZL0lqneo+GpWZdw5Z++ RgB9eXXuE/N7XtZSgUT+m8foIKc6n9Pq6MQZAVfcPesmitLyF1acsncLuyI0mnXLJt3E 6VFQ== X-Gm-Message-State: AOJu0Yyj3Ta43OSizdQusQlDwBe7QRvY38ci8VvIka32yA/OXLtH2KH1 I4VJx5X3UJinAM68FDhC/4Tqf0Mr+0FZ3OugDURXXmHTLm5esWln2EpA48lYjv7oEWOVe2vwlrW mHz+X3132378Na0ipiu9IkgHd0CtOP1Cpn7rdKMPX8847XoAOpqOv9zWc95u2aTtFPo04NJ8C4j sFCm/iKFilEg== X-Received: by 2002:a17:902:e891:b0:202:13ca:d73e with SMTP id d9443c01a7336-206f0518deemr13500835ad.28.1725603315457; Thu, 05 Sep 2024 23:15:15 -0700 (PDT) X-Google-Smtp-Source: AGHT+IHEfCCS+o5gbqSDRnxxErOIKrBXaTA1ogzI9TqmIx/mtTKLQuwWWHgwMEI2345WZjX+pVpp2g== X-Received: by 2002:a17:902:e891:b0:202:13ca:d73e with SMTP id d9443c01a7336-206f0518deemr13500615ad.28.1725603314904; Thu, 05 Sep 2024 23:15:14 -0700 (PDT) Received: from localhost.localdomain ([240f:74:7be:1:30a0:3aa:ffce:68e4]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-206ae9558fdsm37279885ad.91.2024.09.05.23.15.13 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 05 Sep 2024 23:15:14 -0700 (PDT) From: Koichiro Den To: kernel-team@lists.ubuntu.com Subject: [SRU][F][PATCH 1/1] bpf: Fix DEVMAP_HASH overflow check on 32-bit arches Date: Fri, 6 Sep 2024 15:14:38 +0900 Message-ID: <20240906061449.734300-2-koichiro.den@canonical.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240906061449.734300-1-koichiro.den@canonical.com> References: <20240906061449.734300-1-koichiro.den@canonical.com> MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Toke Høiland-Jørgensen The devmap code allocates a number hash buckets equal to the next power of two of the max_entries value provided when creating the map. When rounding up to the next power of two, the 32-bit variable storing the number of buckets can overflow, and the code checks for overflow by checking if the truncated 32-bit value is equal to 0. However, on 32-bit arches the rounding up itself can overflow mid-way through, because it ends up doing a left-shift of 32 bits on an unsigned long value. If the size of an unsigned long is four bytes, this is undefined behaviour, so there is no guarantee that we'll end up with a nice and tidy 0-value at the end. Syzbot managed to turn this into a crash on arm32 by creating a DEVMAP_HASH with max_entries > 0x80000000 and then trying to update it. Fix this by moving the overflow check to before the rounding up operation. Fixes: 6f9d451ab1a3 ("xdp: Add devmap_hash map type for looking up devices by hashed index") Link: https://lore.kernel.org/r/000000000000ed666a0611af6818@google.com Reported-and-tested-by: syzbot+8cd36f6b65f3cafd400a@syzkaller.appspotmail.com Signed-off-by: Toke Høiland-Jørgensen Message-ID: <20240307120340.99577-2-toke@redhat.com> Signed-off-by: Alexei Starovoitov (backported from commit 281d464a34f540de166cee74b723e97ac2515ec3) [koichiroden: Adjusted context due to missing commits: commit 844f157f6c0a ("bpf: Eliminate rlimit-based memory accounting for devmap maps") commit 96360004b862 ("xdp: Make devmap flush_list common for all map instances")] CVE-2024-26885 Signed-off-by: Koichiro Den --- kernel/bpf/devmap.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/kernel/bpf/devmap.c b/kernel/bpf/devmap.c index 4b2819b0a05a..b3b5c8f71f58 100644 --- a/kernel/bpf/devmap.c +++ b/kernel/bpf/devmap.c @@ -130,10 +130,12 @@ static int dev_map_init_map(struct bpf_dtab *dtab, union bpf_attr *attr) cost = (u64) sizeof(struct list_head) * num_possible_cpus(); if (attr->map_type == BPF_MAP_TYPE_DEVMAP_HASH) { - dtab->n_buckets = roundup_pow_of_two(dtab->map.max_entries); - - if (!dtab->n_buckets) /* Overflow check */ + /* hash table size must be power of 2; roundup_pow_of_two() can + * overflow into UB on 32-bit arches, so check that first + */ + if (dtab->map.max_entries > 1UL << 31) return -EINVAL; + dtab->n_buckets = roundup_pow_of_two(dtab->map.max_entries); cost += (u64) sizeof(struct hlist_head) * dtab->n_buckets; } else { cost += (u64) dtab->map.max_entries * sizeof(struct bpf_dtab_netdev *);