From nobody Mon Jun 8 12:16:18 2026 Received: from mail-ed1-f53.google.com (mail-ed1-f53.google.com [209.85.208.53]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9F6F33AD516 for ; Fri, 29 May 2026 08:01:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=pass smtp.client-ip=209.85.208.53 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780041705; cv=pass; b=cqdqJ+YVnETPNpebuJe1ccq7s0ItlT90STtl6qLFNP7RGDpbaIb1TA9vLkaXgRiw8p9yb5dXKVYaYopjRrYKtTNAKn3oCBbxy4xl44xFCLZxw3Uh1Y7pXHbYImVqOQYvwo6GHS2ze6GROrFiXFyO9QmigqDmJsAY5sJDIr7gP2U= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780041705; c=relaxed/simple; bh=BnSxB7MNKfuACgGegp9vQcxDloM1Xn3kSs5NA/LfGys=; h=MIME-Version:From:Date:Message-ID:Subject:To:Cc:Content-Type; b=ELid65W3tTvYQyUc0nM06tOqTcEj5KijX6g+nC+MPFRji3yEDiSaG22b25DnVY8lcQzM6HLbMwthe2VwpFuqNGcCM5291GUogaERWkuqIVnPo+bPss5bRN0nVaWip3x8CM38LNcIpWcJTs88uogzsfBIhb3L/pSoccpFnlIXd+o= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=ClH2unIb; arc=pass smtp.client-ip=209.85.208.53 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="ClH2unIb" Received: by mail-ed1-f53.google.com with SMTP id 4fb4d7f45d1cf-67fd8befac7so7042087a12.2 for ; Fri, 29 May 2026 01:01:43 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1780041702; cv=none; d=google.com; s=arc-20240605; b=gtE6dmdw/jzZvlwSLNfhKdCO0bV+5cSKOXR2GR3rTfHa2F54ZjVboC8bhczzcfsH4u GsDKxmtt+y/zIV1UdSGcqpptWnwX8yWJ+etJFrnjOqo1YvqDyG1b86jnXWA494drLJ5K NvhvZ5RLEZD9xAOpkIBfo/QpFFh98anVoPwMjTRYZ6VYUpNkLyipsqZa0sDo/KabH+IH 1yosPsaSdSAkP2kMxbnyJk29BR2wqcQ03TLQsrSoREkhvEnyP893sAGiERn226onYwwI Orf2wWf2HRhd1qsRZJIm3/zTUL0eKFJdS6rSHqavwjVtikNm3iLE1EJJlStGz2ocLhGr hIVQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=cc:to:subject:message-id:date:from:mime-version:dkim-signature; bh=p/7hRCDFxLMueRxm6cxWJtgPYfIyfdwPUvmOsgwP1QU=; fh=dBIDgfDsGq2woyL7UGrEheMAQdb+UIK7t+G9cLaFjjw=; b=cth9l5BBkW6blAz06yEJDaw2cOE/1vTiA/oxzDP5q6cdINV5xMbS+s3r3RiOMEmgOm KtWDhk2eoTVQUORl361zPfvOMVXw7NzR81EioVVqA7p5Jqut3BmmPcjIqpJjPakmWJxC Q7p8pQdR1FK+tsPG0+4I2bPWGBD50LzKWOTs5RukixnTZo1GRXHasAp5Y8bWQzNubVmx w47fuRiu/myF8mOfk/CG2MtIF2Vp3+WR5DXVOaRXrlUW8pOrPW3SD1wsQhhNPoM02xwu fR2WWE2+fA+5phXuI7pVzHiRVGfLeVhCOZ3FziQC2g7ISevZae84o0FoPpacA/2OIVFg HjIg==; darn=vger.kernel.org ARC-Authentication-Results: i=1; mx.google.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1780041702; x=1780646502; darn=vger.kernel.org; h=cc:to:subject:message-id:date:from:mime-version:from:to:cc:subject :date:message-id:reply-to; bh=p/7hRCDFxLMueRxm6cxWJtgPYfIyfdwPUvmOsgwP1QU=; b=ClH2unIbPJTEo1SNnZsS2e2NT6FZPN5C+fAEbewY3xh8a2FTsALKSz8eJbUomkISqI 0sc6IKrjfTJf/rLhEYAdV85uHdPYVMHyorPLkgiV8NCh7JpA9k061756DpdvNPt9LDvh o/jTuaOjo+SOlBzBDdvu5DW0UE7Ou23Ue61KSzbXkAZzyhDDauO4BPTrMIm/GX3kaALf rA0LbGMrAWeBbJv5NUYEpHuqvqZb3ZATcl6/7ZpJ4lhogC0fz+UKOnHxIomhJfKvskJA H3WvFOEH9gE3r5daAInymZrUA46JrFAvm5YIkxxNg6IwDKPtR1Su6isoYuVNDpgxhtRc dMPw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1780041702; x=1780646502; h=cc:to:subject:message-id:date:from:mime-version:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=p/7hRCDFxLMueRxm6cxWJtgPYfIyfdwPUvmOsgwP1QU=; b=cyCGAAL5Dd9ofWOXmRCjgouw9b5aKexUAxWe8erUpU1zMWd3QyGG1zkdRLNSPqO043 F7p5hdqYo4i9HHyIs7kwj2+cvNsBeMabSioG6jZTyWOpiB+YvI0S7qfCdGndBFELrLT9 d5gzm7BV5ct1W1g40vpExOCts+qqalvTYDOJUJvWhMLUIrNuWtRJY5tR5BuMTORAPK2v sKuOAoYXMjwXzENMEB8vFKPSINhZhYhN1g7ykv7aJ+qBCe0qilGoUsAl0zrGjT9zAVcJ MmA9tIyprMo2pV0+siinHijQz2yW5u8vk8bAqCLwx3M1rfOJGvD+oNNDGuj3+oMDmVjC +YSw== X-Forwarded-Encrypted: i=1; AFNElJ90q2k75IOF4JeC9cbgLVYyxREy92QthazEP8f4HDYEzQWVrjk3lNTLTd+N0qSlLR4nkpsxrS9I0pbYIc4=@vger.kernel.org X-Gm-Message-State: AOJu0YxGfdo7ohdI3ym9Pz4XVEfoK9Vfk1KS/J8QNNpJS3LCu9O0YOgG GKBIp3cgpmY6XXb1pv5myGwZOS0LcEpRkKRT1fCQJZYKTkW4nI2IBonPsGVNkeSalEsYYID5Uss FeKv1KtZvbCAFdaZIomc8qvSgECeD5/0= X-Gm-Gg: Acq92OFwidblhtm+7JaUoqJncbo5R64B/icLNiJZs3LNJPedvuvmBHaZCkfY+v4mOpT D66UX/cRG6lng/ilk0wfui10TNk/wBCYnZWxQ6iVX07N+SY3y93XkjckLLDlzZuGOERValxzHtk 7wuJVzjYjPMOSDnKA9rMjuoRFQRBfwpe7LnXzb7KjvIVzOIHPIwC+I7aeDH8Ove9TQRWb89pIUc MkcnpwD7QcIeTpW1OMnfQ5rj5g1YJAuTw/Aveo02gtnCH8iDli2Uh1+85AhztZ07ihYpn9mxv0D XgbQUPBUA3jS6WFSJHOAQ4CEfxpZ7PqdgiiR/+sNR532BiXgXw== X-Received: by 2002:a17:907:7b91:b0:bd4:7bed:512a with SMTP id a640c23a62f3a-be9ccd77561mr82061066b.30.1780041701586; Fri, 29 May 2026 01:01:41 -0700 (PDT) Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Sanghyun Park Date: Fri, 29 May 2026 17:01:02 +0900 X-Gm-Features: AVHnY4JQvv523fz0OjYrhufApmA8nMXikUDlTLVeTqDx-h6qgEpNtI_ZkFuyy10 Message-ID: Subject: [PATCH v2] bpf: Fix use-after-free on mm_struct in bpf_find_vma() To: ast@kernel.org, daniel@iogearbox.net, andrii@kernel.org Cc: bpf@vger.kernel.org, linux-kernel@vger.kernel.org, puranjay@kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" bpf_find_vma() reads task->mm without holding task_lock() or taking an mm reference via mmget()/mmget_not_zero(). When called on a foreign task obtained via bpf_task_from_pid(), a concurrent exit_mm() can free the mm_struct between the raw pointer read and mmap_read_trylock(mm), resulting in a use-after-free on the mm's mmap_lock. This is the same bug class fixed by commit d8e27d2d22b6 ("bpf: fix mm lifecycle in open-coded task_vma iterator") for the open-coded task_vma iterator, but bpf_find_vma() in the same file was missed by that fix. For the current task, task->mm is stable and needs no extra reference. For a foreign task, use get_task_mm() which acquires task_lock(), checks task->mm, and calls mmget() atomically, preventing the race with exit_mm(). The reference is dropped via mmput() after the mmap lock is released. Race: CPU0 (BPF program) CPU1 (exiting task) =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D bpf_find_vma(foreign_task): mm =3D task->mm // raw read, no reference exit_mm(): task->mm =3D NULL mmput(mm) -> frees mm_struct mmap_read_trylock(mm) // UAF: mm is freed Reproduction: 1. Build kernel >=3D 5.17 with CONFIG_KASAN=3Dy, CONFIG_BPF_SYSCALL=3Dy 2. Boot in a VM (QEMU works fine) 3. Compile the reproducer below: gcc -O2 -o repro -static repro.c -lbpf -lelf -lz 4. Run as root: ./repro 5. Check dmesg for: BUG: KASAN: slab-use-after-free in down_read_trylock The reproducer attaches a BPF program that calls bpf_find_vma() on a foreign task obtained via bpf_task_from_pid(). A racing thread repeatedly fork+exit's that task, creating a window where mm is freed. KASAN report (reproduced on 6.12.91, CONFIG_PREEMPT + KASAN): BUG: KASAN: slab-use-after-free in down_read_trylock+0x380/0x3f0 Read of size 8 at addr ffff888003cd2fd0 by task repro/164451 Call Trace: down_read_trylock+0x380/0x3f0 bpf_find_vma+0xdd/0x360 bpf_prog_708df9c9a3e172a7_main_f+0x8b/0x9e bpf_trampoline_6442513469+0x43/0xa3 Freed by task 164453: kmem_cache_free+0x15d/0x4b0 finish_task_switch.isra.0+0x4ab/0x810 Fixes: 7c7e3d31e785 ("bpf: Introduce helper bpf_find_vma") Signed-off-by: Sanghyun Park --- v2: Rebased onto bpf-next to fix merge conflict (no code changes). kernel/bpf/task_iter.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/kernel/bpf/task_iter.c b/kernel/bpf/task_iter.c index e791ae065c..015399e62b 100644 --- a/kernel/bpf/task_iter.c +++ b/kernel/bpf/task_iter.c @@ -757,6 +757,7 @@ BPF_CALL_5(bpf_find_vma, struct task_struct *, task, u64, start, struct vm_area_struct *vma; bool irq_work_busy =3D false; struct mm_struct *mm; + bool foreign =3D task !=3D current; int ret =3D -ENOENT; if (flags) @@ -765,7 +766,12 @@ BPF_CALL_5(bpf_find_vma, struct task_struct *, task, u64, start, if (!task) return -ENOENT; - mm =3D task->mm; + if (foreign) { + mm =3D get_task_mm(task); + } else { + mm =3D task->mm; + } + if (!mm) return -ENOENT; @@ -782,6 +788,8 @@ BPF_CALL_5(bpf_find_vma, struct task_struct *, task, u64, start, ret =3D 0; } bpf_mmap_unlock_mm(work, mm); + if (foreign) + mmput(mm); return ret; } --=20 2.48.1