Received: by 2002:a05:7412:a9a2:b0:e2:908c:2ebd with SMTP id o34csp1310127rdh; Fri, 27 Oct 2023 10:14:02 -0700 (PDT) X-Google-Smtp-Source: AGHT+IEAYzqL9yImSaHBBGUAzDkPoHqfMt8rOi1uEw26YXMHTDL1rRWKe0zlU00kYQSORvitGmIQ X-Received: by 2002:a25:77d3:0:b0:d81:51db:3292 with SMTP id s202-20020a2577d3000000b00d8151db3292mr3728694ybc.45.1698426841723; Fri, 27 Oct 2023 10:14:01 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1698426841; cv=none; d=google.com; s=arc-20160816; b=X1GotwRd0xJ54GT50Sd1EA6k7vQhARkFv1+daown3O5EaeDJFIIIldVwmk5ykfca67 wYy1cwYdNsAioCkvD8YnLJ7z4zdVukeL9H4JXT8m6St5dl3BNIqad6/0RfX6WYP14O3C XMnj2JF9YmY+6xBJ4iug2WmKFZ0odYwGgZGj4GhjEj66X1qqckDugY688FJNrr/Ry8hH OI9wwDyltyovNBrdkDzgZeGwQW0+dXlWcpTo+R3x75nfb9Es7HjS4NchmZ29Jo8K80le xV8y6RH2c1N3Q8ODBAdevHJwcBaFTDBy1Yd4wgpMXWJhNEv+U0n83EL0ZAcg0kAPSVju bv0w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:cc:to:subject:message-id:date:from:mime-version :dkim-signature; bh=uflhsKfvfbwjHaS6RjFEsCiPUfIOoxhNzB+wL9eWIuk=; fh=xGzRTL8uyYKy4iABrPoXnZjya+hivHZY9zu0EtqZuEc=; b=VFPLCwjtkKdEHuU0aXZa2uxoJk3xGWrVEQolh5Kl4l87BlBTgKQRi8F92Rzl0JqFmr vkd4W9coRE7i1hEaSPr8rxj9bnIAU0NkqzKKcfAjh9/bQ/zqsUZpBidNgCfoRzw/IyoI BCiBxVhn+L8eyTVvMCF1edpWVvvwxWqxcQb2lz3NUnKd2ksnQLASIS1owV+2tPvXi4dD jDQA1+wv0uAYaFmS7nWIFZDuuCX1zfLpqe0177H0CZJShFb+3HxMNg5posRpKq47Xs5T NvAdiDPja3SmMLzir5pE4qmtpmFsW3wnLjlFcT5Wd5+nNUUvyd/Dt/WT4I6fyPGpDDTr oPag== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20230601 header.b=fjIX1UlL; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:6 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Return-Path: Received: from pete.vger.email (pete.vger.email. [2620:137:e000::3:6]) by mx.google.com with ESMTPS id z185-20020a254cc2000000b00d8169bdad70si2926332yba.56.2023.10.27.10.13.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 27 Oct 2023 10:14:01 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:6 as permitted sender) client-ip=2620:137:e000::3:6; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20230601 header.b=fjIX1UlL; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:6 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by pete.vger.email (Postfix) with ESMTP id 527A0851FE2A; Fri, 27 Oct 2023 10:13:53 -0700 (PDT) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.10 at pete.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232071AbjJ0RN3 (ORCPT + 99 others); Fri, 27 Oct 2023 13:13:29 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47652 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232292AbjJ0RN2 (ORCPT ); Fri, 27 Oct 2023 13:13:28 -0400 Received: from mail-ed1-x52b.google.com (mail-ed1-x52b.google.com [IPv6:2a00:1450:4864:20::52b]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C50078262 for ; Fri, 27 Oct 2023 10:13:25 -0700 (PDT) Received: by mail-ed1-x52b.google.com with SMTP id 4fb4d7f45d1cf-53f98cbcd76so492a12.1 for ; Fri, 27 Oct 2023 10:13:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1698426804; x=1699031604; darn=vger.kernel.org; h=cc:to:subject:message-id:date:from:mime-version:from:to:cc:subject :date:message-id:reply-to; bh=uflhsKfvfbwjHaS6RjFEsCiPUfIOoxhNzB+wL9eWIuk=; b=fjIX1UlL8G6KBtvFdvkO5QILXtQk2lTF2ge4R3FmTkR1vyYEseFolQrPhMt6GHGSmR vLEcltcmduKsB64xN8ZtDm+hiS5lbog6jusQ/7R9rMT6K1pf096wtNbqMXnqE2fA+OfY EELkoo0g2pWDpvk5v+Y6n4ibBP74ircVleDP+O8qXDLpAu6K19NCIDp8NuR0eNnNQ98C 5z6rBMxLFoSgud7lTbAmOarmqn16sLP3XNMmOQsYPbL9rLTNLpNIOA+5RcXJG2II3BBE ScvfFmId1KbK1+/xVgsRQ0+fcvG25zI12C2rTEAtNVSzd6rwR+TqvmIqoC/iHYzyyqeE mhzg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1698426804; x=1699031604; h=cc:to:subject:message-id:date:from:mime-version:x-gm-message-state :from:to:cc:subject:date:message-id:reply-to; bh=uflhsKfvfbwjHaS6RjFEsCiPUfIOoxhNzB+wL9eWIuk=; b=ky/nUP3zQeOk56MtQOGSsQjEkxH9a64/QSqhuxd+otFyKHOvjw/WckTTpM/BRtUAvP hS9O20rc6/quTx2LsD1SSqqo4XO6GFtPQ4iR1D1zL0i+iD0Za4xp/rf7t+OAhw4OyhfK yGgsqGw/x/lSX4uSD9y8i/MFajbYYLQaQlcojuScOETU8NDKkoEKy+kFExYO0argZntR E1xvFbsm/YpxfmNOU6Xi3dXRpGdX+NbW1j45wwfImbKCSSvSE9mKvanwCtXZHSoxDwKw 2zJwDXZT77ZZ6DLokfcqytPPeTi6RfpYL7PS5GcRj0yZ3689SxSIfp3+2grcR7wEWqzP 7H3w== X-Gm-Message-State: AOJu0YylBaII94qVQwGq8xJ3x01teuP3YERuB+Hs/5WJdQkZN10q4geU EDJeo6c5+qY5eqRVgkKYGBm21ij20sWhPFy9BQPrvQ== X-Received: by 2002:a50:c101:0:b0:540:e46c:5c7e with SMTP id l1-20020a50c101000000b00540e46c5c7emr12155edf.0.1698426804082; Fri, 27 Oct 2023 10:13:24 -0700 (PDT) MIME-Version: 1.0 From: Jann Horn Date: Fri, 27 Oct 2023 19:12:46 +0200 Message-ID: Subject: BPF: bpf_d_path() can be invoked on "struct path" not holding proper references, resulting in kernel memory corruption To: Alexei Starovoitov , Daniel Borkmann , Andrii Nakryiko , Jiri Olsa Cc: Martin KaFai Lau , Song Liu , Yonghong Song , John Fastabend , KP Singh , Stanislav Fomichev , Hao Luo , KP Singh , Matt Bobrowski , bpf , kernel list , Al Viro Content-Type: text/plain; charset="UTF-8" X-Spam-Status: No, score=-8.4 required=5.0 tests=DKIMWL_WL_MED,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_IN_DEF_DKIM_WL autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on pete.vger.email Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (pete.vger.email [0.0.0.0]); Fri, 27 Oct 2023 10:13:53 -0700 (PDT) Hi! bpf_d_path() can be invoked on a "struct path" that results from following a pointer chain involving pointers that can concurrently change; this can lead to stuff like use-after-free in d_path(). For example, the BPF verifier permits stuff like bpf_d_path(¤t->mm->exe_file->f_path, ...), which is not actually safe in many contexts: current->mm->exe_file can concurrently change; so by the time bpf_d_path() is called, the file's refcount might have gone to zero, and __fput() may have already mostly torn down the file. "struct file" currently has some limited RCU lifetime, but that is supposed to be an implementation detail that BPF shouldn't be relying on, and "struct file" will soon have even less RCU lifetime than before (see ). When __fput() tears down a file, it drops the references held by file->f_path.mnt and file->f_path.dentry. "struct vfsmount" has some kind of RCU lifetime, but "struct dentry" will be freed directly in dentry_free() if it has DCACHE_NORCU set, which is the case if it was allocated via d_alloc_pseudo(), which is how memfd files are allocated. So the following race is possible, if we start in a situation where current->mm->exe_file points to a memfd: thread A thread B ======== ======== begin RCU section begin BPF program compute path = ¤t->mm->exe_file->f_path prctl(PR_SET_MM, PR_SET_MM_MAP, ...) updates current->mm->exe_file calls fput() on old ->exe_file __fput() runs dput(dentry); mntput(mnt) invoke helper bpf_d_path(path, ...) d_path() reads path->dentry->d_op *** UAF read *** reads path->dentry->d_op->d_dname *** read through wild pointer *** path->dentry->d_op->d_dname(...) *** wild pointer call *** So if an attacker managed to reallocate the old "struct dentry" with attacker-controlled data, they could probably get the kernel to call an attacker-provided function pointer, eventually letting an attacker gain kernel privileges. Obviously this is not a bug an unprivileged attacker can just hit directly on a system where no legitimate BPF programs are already running, because loading tracing BPF programs requires privileges; but if a privileged process loads a tracing BPF program that does something unsafe like "bpf_d_path(¤t->mm->exe_file->f_path, ...)", an attacker might be able to leverage that. If BPF wants to be able to promise that buggy BPF code can't crash the kernel (or, worse, introduce privilege escalation vulnerabilities in the kernel), then I think BPF programs must not be allowed to follow any pointer chain and pass the object at the end of it into BPF helpers.