From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.remote-ip=209.85.216.69 ARC-Seal: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; cv=none; t=1793051581; b=q7RCON75U8ug41FPzL1+ea6X9L6WXjVgp9JLav4B+mFdfyxUK5SsO3aVuinO3SxmVrKR CkzSaYjBd9zBDtMMu0vWi2iQEY/K6a/r2YJBfJG/f2p89wbVVzL4XVmat6L2ULRUCQLM2 e73F+7e8hw1lqBXpHjaTQ1H1wZF2ep1JVACYz4WsOFgNjYiJOfbdhcqyjWX2fjhWWUFwI nCTYpPKsyphsG/iHPNv0Q+Uo70wFkZfdAajJS/aH+GHTiIDRvUUup0rTUJYHEub9dWW6Q AmynctTr/iWbqc3BoICr54ACNBZdIvpUH0YBk7gxz3KJNyVDn5YTX1l49A+MHNmqHEA== ARC-Message-Signature: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; c=relaxed/relaxed; t=1793051581; h=DMARC-Filter:Received:DKIM-Signature:X-Google-DKIM-Signature: X-Forwarded-Encrypted:X-Gm-Message-State:X-Received:Date:In-Reply-To: Mime-Version:References:X-Mailer:Message-ID:Subject:From:To:Cc: Content-Type; bh=oogWXdI71uSApWoisQtM4clnwhLv0Vs2bmtqChsuYec=; b=nquvSNWHCCRV9VSNhAi23EUgEscHyOEUPaErDAWAKB9tQi7zKb1PyjOTu84cz5KDAbce WxCcPNbpKgukcV44HH8SPhd2nX4wJihihcYmbZDzrbx8fSTwEkQqSS0WBmrYyib9bM434 2gOxe4qV5IwActO2YZ9VThKn11uZEGYjDi8bH+b+wPVHhfL5AzrXgLSXVKD5E7xXUMrET Yuf0B4BDFrXFXY/xVePXb6hz4PUpVg5WVSsg7UiVbT6Rbw9ywxcFEpA91GfhhKgT3JT3m MkOZvPhkzfcq8PggqZMetpS9jpbRWLtE8nKUu5Om+V/ZsrLb+VVSHBQfj4Ho2xjJ8LQ== ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass header.from=google.com; spf=(null) smtp.mailfrom=flex--jthoughton.bounces.google.com; dkim=pass header.d=google.com header.i=@google.com header.a=rsa-sha256 header.s=20251104 header.b=sJPCAyGd; arc=none smtp.remote-ip=209.85.216.69 Received: from mail-pj1-f69.google.com (mail-pj1-f69.google.com [209.85.216.69]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits) key-exchange X25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1914A606A332 for ; Mon, 26 Oct 2026 21:52:51 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.2 smtp.subspace.kernel.org 1914A606A332 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=tempfail smtp.mailfrom=flex--jthoughton.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key, unprotected) header.d=google.com header.i=@google.com header.a=rsa-sha256 header.s=20251104 header.b=sJPCAyGd Received: by mail-pj1-f69.google.com with SMTP id 98e67ed59e1d1-3ad98380ccfso5288472a91.1 for ; Mon, 26 Oct 2026 14:52:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1793051570; x=1793656370; darn=vger.kernel.org; h=content-type:cc:to:from:subject:message-id:references:mime-version :in-reply-to:date:from:to:cc:subject:date:message-id:reply-to :content-type; bh=oogWXdI71uSApWoisQtM4clnwhLv0Vs2bmtqChsuYec=; b=sJPCAyGdVEm2VhcvIBWqxKdB1ov+NEHAo0t+uGAM/0+qDIoJvuHm7nefnhKXLbxfZu kkzdd/4AnoA114yH/wBhWFkj4bhnTFD/5geQjiLBoAkwcMG8cTAN5yffgV7X8VZkSD6k UqJP6p4PAxwVl8yTZ/Y+9JixBhYbVYFxenEyF+y0YO2Y9TO0Q2mOae4aV4jUlpGMmFIH Y+Azcs1izJVTuxuoeh6BKO/iK8Vap0RGSadypMKvAjvOIsUEPKwpqHb793AvWJQkjEjp +fWxRFzb1QlgIgm+QlrlfCdAQHISYeGneT49/PFezT8s3UQeSh2Ep1POwSjeCezfL9SA lQ4g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1793051570; x=1793656370; h=content-type:cc:to:from:subject:message-id:references:mime-version :in-reply-to:date:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to:content-type; bh=oogWXdI71uSApWoisQtM4clnwhLv0Vs2bmtqChsuYec=; b=21Pc1IYJngkehWPZDv55q2CHV5a4y5dDTju2M0YBlB306XYVs5qq/SW2UgGWJjFb2F RGoEC3n1rkTfFaY285Pk0FvnQ5WdXlphPhtSjuju3l8Hz4m9NCUmlnQ3Z9jVeSc0GcJ/ UWklXqGbieKuZ7p5Er4QhO/j/VTYbhajLIyYuyN4Km9OpfClHW5vfzVnEGCBXIsxH2Lk brU43E6M5RLLieFR3xLMqIvfiYShPR9tniJ0N00o7n4CDXmQ+dUi3BLN4vD+0cEDP6LO CR71/1IIFxrdxB2QouFjpYUO7fEuc/nBLLZUfyVQiwT30Ig1aQ3lGEchmRbmAdGTpxOJ 8i5A== X-Forwarded-Encrypted: i=1; AKwUvBz/lv87IYr6zuGapKj4azpsOVThMsBjo7UPmu9k+YsyrIjrmN4F0A3i1P2p6yTRbILUNYTOyc+JtMCVngY=@vger.kernel.org X-Gm-Message-State: AFq9FYLzg633P3HO1tNPjQEwdxd2/MTTph4OKZyPf6N9GlKvE6uy0r5h gckaZY9urHc7mlp3CRbMI53R9OCW0/cifaWKJvWOeVmYXIinULrAYp9v+sKT1lcRz+q+wCB0+zF e2icxCq4WIDUZHmjmlgWsIA== X-Received: from pjbml16.prod.google.com ([2002:a17:90b:3610:b0:3ab:54fb:2a3d]) (user=jthoughton job=prod-delivery.src-stubby-dispatcher) by 2002:a17:90b:56ce:b0:3a8:9d0d:ca50 with SMTP id 98e67ed59e1d1-3adeaae618emr6704272a91.10.1793051570356; Mon, 26 Oct 2026 14:52:50 -0700 (PDT) Date: Mon, 26 Oct 2026 21:52:19 +0000 In-Reply-To: <20261026215226.3713941-1-jthoughton@google.com> X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list Mime-Version: 1.0 References: <20261026215226.3713941-1-jthoughton@google.com> X-Mailer: git-send-email 2.56.0.307.g5fe7bd680c-goog Message-ID: <20261026215226.3713941-4-jthoughton@google.com> Subject: [RFC PATCH 03/10] bpf: Fail sleepable user copy helpers when current->mm is NULL From: James Houghton To: Andrew Morton , Alexander Viro Cc: Thomas Gleixner , Peter Zijlstra , Kees Cook , Arnd Bergmann , David Hildenbrand , Lorenzo Stoakes , "Liam R. Howlett" , Vlastimil Babka , Mike Rapoport , Suren Baghdasaryan , Michal Hocko , Sean Christopherson , Paolo Bonzini , Jim Mattson , Jens Axboe , Pavel Begunkov , "James E.J. Bottomley" , "Martin K. Petersen" , David Sterba , Chris Mason , Alexei Starovoitov , Daniel Borkmann , John Fastabend , Josh Poimboeuf , Steven Rostedt , Masami Hiramatsu , Mathieu Desnoyers , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , linux-mm@kvack.org, linux-fsdevel@vger.kernel.org, kvm@vger.kernel.org, io-uring@vger.kernel.org, linux-scsi@vger.kernel.org, linux-btrfs@vger.kernel.org, bpf@vger.kernel.org, linux-trace-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, James Houghton Content-Type: text/plain; charset="UTF-8" Sleepable BPF programs can run on behalf of a kernel thread, or of a task that has already gone through exit_mm(). For example, bpf_wq callbacks always run from a kworker, bpf_task_work callbacks queued late enough run from exit_task_work(), and lsm.s or fentry.s programs may be attached to functions called during exit_files(), exit_task_work() or from kernel threads (e.g. security_file_release() from a kworker running delayed_fput()). In such contexts, bpf_copy_from_user(), bpf_copy_from_user_str() and bpf_copy_from_user{,_str}_dynptr() (when reading from the current task) call copy_from_user() or strncpy_from_user() without an mm. That access does not reliably fail: the user half of the address space belongs to whatever mm happens to be lazily loaded, if any, so the program may read another task's memory. As there is no user memory to read from in this case, fail with -EFAULT without attempting the access. Fixes: 07be4c4a3e7a ("bpf: Add bpf_copy_from_user() helper.") Fixes: 65ab5ac4df01 ("bpf: Add bpf_copy_from_user_str kfunc") Fixes: a498ee7576de ("bpf: Implement dynptr copy kfuncs") Signed-off-by: James Houghton --- Tested with a small bpf_wq reproducer: a SEC("syscall") program arms a bpf_wq whose callback (which runs in a kworker) calls bpf_copy_from_user() on an address in the loader. With the uaccess check from later in this series but without this patch, that triggers the new WARN from bpf_copy_from_user(); with this patch, the helper returns -EFAULT without warning. I can turn this into a selftest under tools/testing/selftests/bpf if that's useful. --- kernel/bpf/helpers.c | 11 +++++++++-- kernel/trace/bpf_trace.c | 4 ++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c index 712dca5a2c5b..c4aa8bcaf2bd 100644 --- a/kernel/bpf/helpers.c +++ b/kernel/bpf/helpers.c @@ -659,7 +659,11 @@ const struct bpf_func_proto bpf_event_output_data_proto = { BPF_CALL_3(bpf_copy_from_user, void *, dst, u32, size, const void __user *, user_ptr) { - int ret = copy_from_user(dst, user_ptr, size); + int ret = -EFAULT; + + /* Sleepable programs may run without an mm, e.g. on kernel threads. */ + if (likely(current->mm)) + ret = copy_from_user(dst, user_ptr, size); if (unlikely(ret)) { memset(dst, 0, size); @@ -3642,7 +3646,10 @@ __bpf_kfunc int bpf_copy_from_user_str(void *dst, u32 dst__sz, const void __user if (unlikely(!dst__sz)) return 0; - ret = strncpy_from_user(dst, unsafe_ptr__ign, dst__sz - 1); + if (unlikely(!current->mm)) + ret = -EFAULT; + else + ret = strncpy_from_user(dst, unsafe_ptr__ign, dst__sz - 1); if (ret < 0) { if (flags & BPF_F_PAD_ZEROS) memset((char *)dst, 0, dst__sz); diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c index 88c3b5b513ab..793fb3dce5f1 100644 --- a/kernel/trace/bpf_trace.c +++ b/kernel/trace/bpf_trace.c @@ -3556,6 +3556,8 @@ static __always_inline int copy_user_data_sleepable(void *dst, const void *unsaf int ret; if (!tsk) { /* Read from the current task */ + if (unlikely(!current->mm)) + return -EFAULT; ret = copy_from_user(dst, (const void __user *)unsafe_src, size); if (ret) return -EFAULT; @@ -3590,6 +3592,8 @@ static __always_inline int copy_user_str_sleepable(void *dst, const void *unsafe if (tsk) { ret = copy_remote_vm_str(tsk, (unsigned long)unsafe_src, dst, size, 0); + } else if (unlikely(!current->mm)) { + ret = -EFAULT; } else { ret = strncpy_from_user(dst, (const void __user *)unsafe_src, size - 1); /* strncpy_from_user does not guarantee NUL termination */ -- 2.56.0.307.g5fe7bd680c-goog