From nobody Tue Sep 29 06:59:03 2026 Received: from mail-wm1-f44.google.com (mail-wm1-f44.google.com [209.85.128.44]) (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 9937F43E07D for ; Tue, 11 Aug 2026 11:22:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.44 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786447367; cv=none; b=OR/UNmuaJdZPy0g518yra1etxPNC5fmiEDJd+YI0wXEJl+JZUYYdnIg9Yd1RENpPOJc1OA1FIRrhPkt+zbjV6pjifCzQG0iz7qBFcMMKr25ZxgDrxEh5UZB2m+yyWacN30ocLXmtWK7LB5s1mbJOuEuMro542Q4IUlRqvNgdQUk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786447367; c=relaxed/simple; bh=wLw+wL5lOK5ZHxFbzv7hNMRisyZ2gWWpu7JX/Ww1mB4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=kumVCrs0V0Lw82yEbhwVl6Qo5WqaZuu7H0o3+aaPZ+HhC9VMNrAKrS1fFOmIOUgd0K4PPMFSSuBeAmuK1Glws7+g/YMxkMPe9mzg6vHUusoxZHDxv7T9gteR6bW6EUcsaBv6r3dwAltSQw9lu5D0KOEVpN69m8ULKYeyhLLmC1o= ARC-Authentication-Results: i=1; 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=ry0r6Tj7; arc=none smtp.client-ip=209.85.128.44 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="ry0r6Tj7" Received: by mail-wm1-f44.google.com with SMTP id 5b1f17b1804b1-49558ce01afso5929035e9.1 for ; Tue, 11 Aug 2026 04:22:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1786447359; x=1787052159; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=Oj+eoknvOaxVg+TzcZeSMNSYsDXOGxOvzczJwlu1YLQ=; b=ry0r6Tj7hJUIrbXgcsVrZuj0QeERRGDMZji/eoNIQk3MAVPFE6fYgkmZMsJYQ2rmqS TO2qtcHjVNoCbkvGoH62rzcv88mvaqFMAeG760x83pZNyl9nS49SHwr/D0U4JNPpnFyp fGn94lLFtmrzb1boiR9uy3HxIg01AAoUDOPME4XjBptYBrPQFYSdqUsoqeIURe8oCHFh CEcrC904z1R+8dvjsjaPkyjbP0GaV01GYbPozF/BDFvuX22ANwO7ndXGyMp9AS3fNwD2 q3pwtNqZUSBgZ9t7S22O9jbfF4lsdP8Twde/CVblT9Ua45AmSiwNwxv1O9Lrw/qOPWbk JPmQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1786447359; x=1787052159; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=Oj+eoknvOaxVg+TzcZeSMNSYsDXOGxOvzczJwlu1YLQ=; b=qx6h3Vs+abEVOs7d6Izzfw4Ty6+9XAry6ZQ8BAMKjNo7AfoBIXZ5Koe+/ldE7Gfth9 MZHQDR1iRGHiga9TuvaUX63dqNxeYrkvqhjgtvXWXAya+vc1kMWe3alU6T2DIHyfPQQU cNM41scVwGpdvbMITdha46yqtJvTJl9ZsTy8624i13JPo4nu3mGonHB89bhNhmuJidFk u1Wu1sf88vjowhvhKPXSSCRVwmMKcLFYXVZFa+GUmnxmRVSaGWOufMpMqwGwk9IoJpv6 TJK1gX6exSPTC7wOOYy8zaddoQzwkr8u4OGpfJxq89Mv9lSocRnEVtmFPYyr6Y5XXo+N zXpg== X-Gm-Message-State: AOJu0YxBR5N3T+g7WV8TlaaA64L+80pPoUHdXyat7t8Y8ZjggXkNmJm/ DwItMlUFjYgAPJ1eYKE3UChEp4prKMhajABw3S49S7ctv07JHjUcylcv X-Gm-Gg: AR+sD10ioRMTjBc3lp/zasAITd3RYxSjZ50g9C8KDNlY/Qb6e7JigQnFC1mnREoOdXh ExUyDH/YdMAjU/EW5R+IhiERII4AjELHdqgiQ9hvCWTkLturxdxGYZ0USiGvUDaPoX981lm85Zm 3uC/x3sidtv0mMEsYKQd+vud3Mx1vVFrN7ZW9/pvJNOhkCxCLbRUTVJ/f8dPtISlc3Zs4RMtAs3 yk/DALvBTi7u9hvuMAhkQ9wiG5Gs0UKOxLEqKXoPg+szRm3qTjA14d4PYdxiQ9dVUispur07pr9 uQjiRAiulDBym9cpTsPOyLCIVTQxrrgi0TGsFf51tkg5yRZMIAxzOiWuVpsGIzSoDauHLGaZ2GB kDrIFgt+OkCMI38gGaJHO8AD1xt8aFAwR5Pz5ILM3MiQW3QOYgISSGUf2N61S+V5eXiKChU0mZa m9gzq4/7PwQWSuHiksgUfxoBj1C+1Vwe7i6ok90D+n1fwuDWsEiWK0Sprqg92uuhGzIfPcbdJeN pqeOIYQDE2EXNY= X-Received: by 2002:a05:600c:4695:b0:499:726a:117c with SMTP id 5b1f17b1804b1-49978494f70mr32371385e9.19.1786447359204; Tue, 11 Aug 2026 04:22:39 -0700 (PDT) Received: from dell-desktop ([2a02:587:4b5e:1100:7303:647d:7cc4:8552]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4997889c2bcsm47547665e9.3.2026.08.11.04.22.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Aug 2026 04:22:38 -0700 (PDT) From: Anastasios Papagiannis To: bpf@vger.kernel.org Cc: linux-kernel@vger.kernel.org, linux-mm@kvack.org, akpm@linux-foundation.org, david@kernel.org, ast@kernel.org, daniel@iogearbox.net, andrii@kernel.org, eddyz87@gmail.com, memxor@gmail.com, kpsingh@kernel.org, matt@bobrowski.net, song@kernel.org, tasos.papagiannnis@gmail.com Subject: [PATCH bpf-next 1/5] mm: Add copy_remote_mm_str() Date: Tue, 11 Aug 2026 14:21:50 +0300 Message-ID: <20260811112154.94053-2-tasos.papagiannnis@gmail.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260811112154.94053-1-tasos.papagiannnis@gmail.com> References: <20260811112154.94053-1-tasos.papagiannnis@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" copy_remote_vm_str() gets the target address space from a struct task_struct. This does not work for an address space that exists but is not yet associated with a task_struct, such as the mm held by struct linux_binprm during exec. This patch adds copy_remote_mm_str(), which operates directly on a struct mm_struct. Signed-off-by: Anastasios Papagiannis --- include/linux/mm.h | 2 ++ mm/memory.c | 25 ++++++++++++++++++++++++- mm/nommu.c | 25 ++++++++++++++++++++++++- 3 files changed, 50 insertions(+), 2 deletions(-) diff --git a/include/linux/mm.h b/include/linux/mm.h index 485df9c2dbdd..eede435bf4a3 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -3222,6 +3222,8 @@ extern int access_remote_vm(struct mm_struct *mm, uns= igned long addr, void *buf, int len, unsigned int gup_flags); =20 #ifdef CONFIG_BPF_SYSCALL +extern int copy_remote_mm_str(struct mm_struct *mm, unsigned long addr, + void *buf, int len, unsigned int gup_flags); extern int copy_remote_vm_str(struct task_struct *tsk, unsigned long addr, void *buf, int len, unsigned int gup_flags); #endif diff --git a/mm/memory.c b/mm/memory.c index 6b8280cfc1db..03cbd3b02bef 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -7218,6 +7218,29 @@ static int __copy_remote_vm_str(struct mm_struct *mm= , unsigned long addr, return buf - old_buf; } =20 +/** + * copy_remote_mm_str - copy a string from a remote address space. + * @mm: the remote address space + * @addr: start address to read from + * @buf: destination buffer + * @len: number of bytes to copy + * @gup_flags: flags modifying lookup behaviour + * + * The caller must hold a reference on @mm. + * + * Return: number of bytes copied from @addr (source) to @buf (destination= ), + * not including the trailing NUL. Always guarantees a NUL-terminated buff= er. + * On any error, return -EFAULT. + */ +int copy_remote_mm_str(struct mm_struct *mm, unsigned long addr, + void *buf, int len, unsigned int gup_flags) +{ + if (unlikely(len =3D=3D 0)) + return 0; + + return __copy_remote_vm_str(mm, addr, buf, len, gup_flags); +} + /** * copy_remote_vm_str - copy a string from another process's address space. * @tsk: the task of the target address space @@ -7247,7 +7270,7 @@ int copy_remote_vm_str(struct task_struct *tsk, unsig= ned long addr, return -EFAULT; } =20 - ret =3D __copy_remote_vm_str(mm, addr, buf, len, gup_flags); + ret =3D copy_remote_mm_str(mm, addr, buf, len, gup_flags); =20 mmput(mm); =20 diff --git a/mm/nommu.c b/mm/nommu.c index ed3934bc2de4..8fbe6306d074 100644 --- a/mm/nommu.c +++ b/mm/nommu.c @@ -1752,6 +1752,29 @@ static int __copy_remote_vm_str(struct mm_struct *mm= , unsigned long addr, return ret; } =20 +/** + * copy_remote_mm_str - copy a string from a remote address space. + * @mm: the remote address space + * @addr: start address to read from + * @buf: destination buffer + * @len: number of bytes to copy + * @gup_flags: flags modifying lookup behaviour (unused) + * + * The caller must hold a reference on @mm. + * + * Return: number of bytes copied from @addr (source) to @buf (destination= ), + * not including the trailing NUL. Always guarantees a NUL-terminated buff= er. + * On any error, return -EFAULT. + */ +int copy_remote_mm_str(struct mm_struct *mm, unsigned long addr, + void *buf, int len, unsigned int gup_flags) +{ + if (unlikely(len =3D=3D 0)) + return 0; + + return __copy_remote_vm_str(mm, addr, buf, len); +} + /** * copy_remote_vm_str - copy a string from another process's address space. * @tsk: the task of the target address space @@ -1781,7 +1804,7 @@ int copy_remote_vm_str(struct task_struct *tsk, unsig= ned long addr, return -EFAULT; } =20 - ret =3D __copy_remote_vm_str(mm, addr, buf, len); + ret =3D copy_remote_mm_str(mm, addr, buf, len, gup_flags); =20 mmput(mm); =20 --=20 2.55.0 From nobody Tue Sep 29 06:59:03 2026 Received: from mail-wm1-f45.google.com (mail-wm1-f45.google.com [209.85.128.45]) (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 EFCDA43E06D for ; Tue, 11 Aug 2026 11:22:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.45 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786447370; cv=none; b=Za+T71uoKB8iGCk+EsQ6TYkFWb3u9Iph1Dird5j1BAt+PmNTJBLBTB9HBxm4OI/TkW7PEAHnajjeH92DiOy+Qj2Seayr1MN/3g9w/z1nZP7nVdksNW9+imXGz+zNuOoVYVeMARgXE2IvwvczJInJDOt4r3AcfdB4TtKxfwNmkMA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786447370; c=relaxed/simple; bh=8DQh2SWbpdhxbKfSWZUmdp9rHTYS6PAT02UU8JSnJKc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=MKOK+zK+SrCQF3ssNBiGhq9GU42xBoCyNWBJej18uak0qxEGZndmOqUXnnloZMC/K06/JFa4JYuMTuIfpy/1uRHm6vIrpaPurilHbbvTnDHzeHBsAHPHpptviJTBzgmqekPqQK3sRu/hxX/68msdvBPliFcjNqdf8MQ/Gu/kzHQ= ARC-Authentication-Results: i=1; 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=gFnN6uck; arc=none smtp.client-ip=209.85.128.45 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="gFnN6uck" Received: by mail-wm1-f45.google.com with SMTP id 5b1f17b1804b1-49978908b35so3265385e9.0 for ; Tue, 11 Aug 2026 04:22:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1786447363; x=1787052163; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=Rcy5zMa/mQvTQ0drm+XsfTSCaDYlJAty3EgPpWyKkzc=; b=gFnN6uckci5jXJJHFeT5sX3RYH2D9Bgq5YPhKUqgsP0SbmHqGMQjVGQdspm/YSAoHo Zen9iKAF4OTPUN36H14SvcYoCjKZC9b/BqKMQE1vx7CSEJRUpOqSeljErhJBD1HqTqgv OLvkCP3NihDjZod0jYgxpYtInCG6u4WumjZcbIcS8izQRs2RuOCoOYI4/wm0VXxx5gC9 zkp5EyS7+F8WE7FMDtDIyWu4V1QhTqLlpMBU4mR/iE6/+QcJ+Io1KKfU/iE4DJkXhXzq XjYwgQQ1IvcG+uyhPXpQj86fBF68MKW5MllxzW92VgBqx5lXmA25f/T0s1qJVI9GeyLP NZEg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1786447363; x=1787052163; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=Rcy5zMa/mQvTQ0drm+XsfTSCaDYlJAty3EgPpWyKkzc=; b=PzW83SksYD7tbBUqgEiiysgHvDdgCfD7eocAwa2ur6d3YNoybjYmYVhiPpuY9FWE1F xyqXg/rBqvymZ07HjHKaaBXfcg6ire+YeJ+dLkIXRSKcvjDFpqtOGPDD2oPEnyRj86JJ RIIftqqu6ntHzgykEDS2cNT+f26XmbJ1yO6/3xiqRfWK0Jsov3IRQzFhWUiatXx5g+hk T5vtJ19Yw22I6CA3vOEBBUD9XnMD5sJRRloxf9nQHGqfyGP9Oxxmq8ySgXvyFtKuM+2Y /8LJIq+bdhDcF6td3a2CIJnT2uWSYx/vjn162gGYeOGraXEuEBAQV5a6uCPrY46vdVQP COag== X-Gm-Message-State: AOJu0YwhoD0QhR+99gqjmO0jzlk5cVON1S3bzP4YjqTlXoexjsT2q4IV +DvoZUXhM1FbllGhGvfH7hjxTXMonneMhyWIgGhmDHj643MeBj08Vu3V X-Gm-Gg: AR+sD108s5i/EzcFL94eG/ccyZyohNW5Zx7Ku/0sLY5dN/tTTkdqC8Gu+ALQA6I+Kng Fc9VS1yhz1GkBOmZspcF5XLu6zRDn5SxxMAIjg3gKut7tD0/seN1vH9T5O5ODx3D2N1FQWHxebK /n9Y9nHxensGqye62gbSgzSV1YjG7waMin4+oZdr3CaQ/wFYAl5HbCNQ92wo5SflxBeJoVZa1QM WOoY0+2T/AlSnJ8wxqR/020K4zIIircT2CaJ5UWYAQHfBNoJNGxXRGTTodR95SJ9yjI9ol1IGEn iizqKubGOpkd30CheJp0U6cgiknS6LqgwU5FZ4AaOY9gkndqjjMb4WVbzLJnElKfSdmwjtnBTbP 5MrxEuJYyIASHoz5mxqbFU4P1+C0WSIrtZtqURq/9ycz+UQ5IScBhzyfXBD8kBz6jylTqWTq9AG KK6Yq19r0i0zuqqy7JiOXHuLyRm6P4aOMdVftNVhFgrLN8JQNUVOoFQYJiWbcBc85l/eS5HlYN9 Otz0cKkNcAqJkk= X-Received: by 2002:a05:600c:1912:b0:499:737c:8a8b with SMTP id 5b1f17b1804b1-4997845e778mr44282705e9.12.1786447363236; Tue, 11 Aug 2026 04:22:43 -0700 (PDT) Received: from dell-desktop ([2a02:587:4b5e:1100:7303:647d:7cc4:8552]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4997889c2bcsm47547665e9.3.2026.08.11.04.22.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Aug 2026 04:22:42 -0700 (PDT) From: Anastasios Papagiannis To: bpf@vger.kernel.org Cc: linux-kernel@vger.kernel.org, linux-mm@kvack.org, akpm@linux-foundation.org, david@kernel.org, ast@kernel.org, daniel@iogearbox.net, andrii@kernel.org, eddyz87@gmail.com, memxor@gmail.com, kpsingh@kernel.org, matt@bobrowski.net, song@kernel.org, tasos.papagiannnis@gmail.com Subject: [PATCH bpf-next 2/5] bpf: Add user memory access kfuncs for mm_struct Date: Tue, 11 Aug 2026 14:21:51 +0300 Message-ID: <20260811112154.94053-3-tasos.papagiannnis@gmail.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260811112154.94053-1-tasos.papagiannnis@gmail.com> References: <20260811112154.94053-1-tasos.papagiannnis@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" When security_bprm_check runs, the arg and env strings for the exec have been copied into bprm->mm. The new address space has not been associated yet with a task_struct until exec_mmap(), so existing BPF user memory helpers can only read from the calling task's old address space. Add bpf_copy_from_user_mm() and bpf_copy_from_user_mm_str() kfuncs. Both take a struct mm_struct pointer directly, allowing callers to access trusted address spaces that are not associated with a task_struct. bpf_copy_from_user_mm() has similar semantics to bpf_copy_from_user_task(). bpf_copy_from_user_mm_str() copies one NUL-terminated string and returns its size including the NUL terminator. It accepts BPF_F_PAD_ZEROS to clear unused destination bytes on success. Register both kfuncs with the common BPF_EVENTS kfunc set and mark them KF_SLEEPABLE because accessing the remote address space can fault. The next patch marks linux_binprm->mm as trusted-or-null, allowing BPF LSM programs attached to security_bprm_check to read arguments beginning at bprm->p after a NULL check and reject an exec based on its command-line arguments. Signed-off-by: Anastasios Papagiannis --- kernel/bpf/helpers.c | 2 + kernel/trace/bpf_trace.c | 83 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 85 insertions(+) diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c index 6388b6b23e49..9ba3362832cd 100644 --- a/kernel/bpf/helpers.c +++ b/kernel/bpf/helpers.c @@ -4931,6 +4931,8 @@ BTF_ID_FLAGS(func, bpf_iter_kmem_cache_destroy, KF_IT= ER_DESTROY | KF_SLEEPABLE) BTF_ID_FLAGS(func, bpf_local_irq_save) BTF_ID_FLAGS(func, bpf_local_irq_restore) #ifdef CONFIG_BPF_EVENTS +BTF_ID_FLAGS(func, bpf_copy_from_user_mm, KF_SLEEPABLE) +BTF_ID_FLAGS(func, bpf_copy_from_user_mm_str, KF_SLEEPABLE) BTF_ID_FLAGS(func, bpf_probe_read_user_dynptr) BTF_ID_FLAGS(func, bpf_probe_read_kernel_dynptr) BTF_ID_FLAGS(func, bpf_probe_read_user_str_dynptr) diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c index 891897f8a1b3..8931b3b2fc9d 100644 --- a/kernel/trace/bpf_trace.c +++ b/kernel/trace/bpf_trace.c @@ -24,6 +24,7 @@ #include #include #include +#include =20 #include =20 @@ -3619,6 +3620,88 @@ __bpf_kfunc int bpf_send_signal_task(struct task_str= uct *task, int sig, enum pid return bpf_send_signal_common(sig, type, task, value); } =20 +/** + * bpf_copy_from_user_mm() - Copy data from an address space + * @dst: Destination address, in kernel space + * @dst__sz: Number of bytes to copy + * @unsafe_ptr__ign: Source address in the address space + * @mm: Address space to copy from + * @flags: Reserved for future use; must be zero + * + * Copies data from the user address space associated with @mm. The destin= ation + * is zeroed if the requested number of bytes cannot be copied in full. + * + * Return: 0 on success, -EINVAL if @flags is non-zero, or -EFAULT if the = copy + * fails or is partial. + */ +__bpf_kfunc int bpf_copy_from_user_mm(void *dst, u32 dst__sz, + const void __user *unsafe_ptr__ign, + struct mm_struct *mm, u64 flags) +{ + int ret; + + if (unlikely(flags)) + return -EINVAL; + + if (unlikely(!dst__sz)) + return 0; + + ret =3D access_remote_vm(mm, (unsigned long)unsafe_ptr__ign, + dst, dst__sz, 0); + if (ret =3D=3D dst__sz) + return 0; + + memset(dst, 0, dst__sz); + return ret < 0 ? ret : -EFAULT; +} + +/** + * bpf_copy_from_user_mm_str() - Copy a string from an address space + * @dst: Destination address, in kernel space. This buffer mus= t be + * at least @dst__sz bytes long + * @dst__sz: Maximum number of bytes to copy, including the traili= ng NUL + * @unsafe_ptr__ign: Source address in the address space + * @mm: Address space to copy from + * @flags: The only supported flag is BPF_F_PAD_ZEROS + * + * Copies a NUL-terminated string from the user address space associated w= ith + * @mm. If the string is too long, @dst is still NUL-terminated unless @ds= t__sz + * is zero. + * + * If BPF_F_PAD_ZEROS is set, the unused portion of @dst is cleared on suc= cess + * and all of @dst is cleared on failure. + * + * Return: The number of copied bytes including the NUL terminator on succ= ess, + * or a negative error code on failure. + */ +__bpf_kfunc int bpf_copy_from_user_mm_str(void *dst, u32 dst__sz, + const void __user *unsafe_ptr__ign, + struct mm_struct *mm, u64 flags) +{ + int ret; + + if (unlikely(flags & ~BPF_F_PAD_ZEROS)) + return -EINVAL; + + if (unlikely(!dst__sz)) + return 0; + + ret =3D copy_remote_mm_str(mm, (unsigned long)unsafe_ptr__ign, + dst, dst__sz, 0); + if (ret < 0) + goto err; + + if (flags & BPF_F_PAD_ZEROS) + memset(dst + ret, 0, dst__sz - ret); + + return ret + 1; + +err: + if (flags & BPF_F_PAD_ZEROS) + memset(dst, 0, dst__sz); + return ret; +} + __bpf_kfunc int bpf_probe_read_user_dynptr(const struct bpf_dynptr *dptr, = u64 off, u64 size, const void __user *unsafe_ptr__ign) { --=20 2.55.0 From nobody Tue Sep 29 06:59:03 2026 Received: from mail-wm1-f52.google.com (mail-wm1-f52.google.com [209.85.128.52]) (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 14DD943D4EC for ; Tue, 11 Aug 2026 11:22:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.52 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786447373; cv=none; b=WvG0roYwduqQBqSvIbMQqvC2SVh2r6vA2sCN9QIdt9LvXUQJlMqw8E50sZicQcVCft4uDYDAJ64yBBwMsm2uTfdKBu+Ub1NfqKQvESCaYzNASckavSWWCnBUr4c5ane0UFnp/5sMC+Nb7G2ttpPUVvcBzWThjYBGLVyqMG/FNPQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786447373; c=relaxed/simple; bh=cFs0xfmRfoyZco4JEYNq6ZrlZJuCFGmvzVSfHHDs8YA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=XbGUjCtVvD3D/1+3G3r4owYR0+P78o5uiM+6TVsLHkVqbzP3zYdtiIfdUVY2Ilg8fZ0pywgcXmbI6fzKdCMrWxurmRXzGfvuI3iNwwgTBOUhcCh0GHE1t7IGmDZQ7LieMgPynVd8PTxkVSeE7tUr1irWnwEjjNhdT3fOvwfoyGo= ARC-Authentication-Results: i=1; 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=AAS5AtwJ; arc=none smtp.client-ip=209.85.128.52 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="AAS5AtwJ" Received: by mail-wm1-f52.google.com with SMTP id 5b1f17b1804b1-4921eed3fa2so23797555e9.0 for ; Tue, 11 Aug 2026 04:22:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1786447367; x=1787052167; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=vdXY11jYOJOgDrqsfvB+3m9H12a0vELp6Tr1U8V4Fak=; b=AAS5AtwJYo7/MnxDvtW+vn3eOb7+r8Xvk/G9KH2JJ2p3hNay6UTNeXT2dmJpLHJTOy gJpHS5lAf3IAj0hyyD8aHN2XCBxBwORMuiARjOm1CDzpMrUXQCEJ3epBC9ln2qlI8CWx 3E8Ud1RypSEUqtjRIu+xGQmLq7DsPMVXgPFmevuuXr7IUUk95fy2IVKoPnF5+RvGahru lxg9VgaXEGcO9QsPudjmWJJ5k2vEorvSFGSR4SXGMZzwoaLIP7jphKIbYLPRBYRX8Q2u p/WuQ8lGClCSY4a5bq+y6i2vdzxOFZKAWDccLGvNzIxH6caNOSjBzpOp/EG0OvKsnV4+ 5Dfg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1786447367; x=1787052167; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=vdXY11jYOJOgDrqsfvB+3m9H12a0vELp6Tr1U8V4Fak=; b=JT0Jw84SDnpTfqGnRlL2v/ngFi+c6j2UNNIk8Zm6QLoHv++VDOy9W+8fEqERtIt8sn Qwy25DxFvpfpTxbyqH0Ety4cedwojnMNUKlGjkEvrCGpweGolxJGpVT9beJ6Yjp+oI+D aIG8Ji5Hjh9SvFyPn5behEYwbVvlgDPSdkKsCO77Zj91Vlvjeuiq8WdUZKSospk6cG1o 1HKX+9pOq2stnX0eDgJ5n/AZ8kpdsxoWRHNPGMi5Q6uZxYyaGv4bEN43TOpj8FYdr/eQ +fgSFsJu5Bd0Z5fBML9tvorBMfhXTMNA+EDXicuwvNFFVCddApZYP/ZsVZMB5UabUIU/ KYXQ== X-Gm-Message-State: AOJu0Yx0OQbbORxpT9LjLiWyoCGO86YkW3p1OMY156efC30HdLQMfCKJ hZwWuX0kiqFFyR1tjRr3jCklS0+gfcQU1WXIST/ekcnq21ChcscZLzvi X-Gm-Gg: AR+sD11rDeY4G6JXFjSFHijqQmUQR1ddcT04ce3i+1WRb1cUjHUw/HfRhwcDTC9IHEX 6n3pkXUni1zoF3hZYD7C8DSAAstFNwwUcJ+h0K5E307OrhqNJXfzCNNw8keakWMsbsgcg7xOWtx WkbQQzK9tcKupZlcmFsEJkQxmfd+QcAtmZYy89vkXU+28zkH7yky71xZPvjVb7+MiNLGKWhz5AF 6IyX21qGmUbZV9MRXFwStP2uriRoYcLiVq4qjdmsrkuu4SmkQalPG8Hpu+HTQkxRYv4IXq7NeiQ b2LDKsAepffso1X+B2qzTcWs8/y+4pGpoSj6IOFI21HYlfZ8mV3PA7BcYSmq5iC6r6nGmyEH+Ss VQTeZkSyhuDJXiJpnuEPZB+CNXiidiJoaQT9P3esDCyhp2wwfMnAlrUX0FOGovhWZqlY31uDN9F vIUhcq/gXLnzhFbjSbUAm8A1XMUmJzvjbWEm2kN72IvvnWIHdVWSoj+v2GatrpZV08eiR9xxYM8 uN3 X-Received: by 2002:a05:600c:1550:b0:498:952:e276 with SMTP id 5b1f17b1804b1-499784358eamr31222895e9.8.1786447366875; Tue, 11 Aug 2026 04:22:46 -0700 (PDT) Received: from dell-desktop ([2a02:587:4b5e:1100:7303:647d:7cc4:8552]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4997889c2bcsm47547665e9.3.2026.08.11.04.22.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Aug 2026 04:22:46 -0700 (PDT) From: Anastasios Papagiannis To: bpf@vger.kernel.org Cc: linux-kernel@vger.kernel.org, linux-mm@kvack.org, akpm@linux-foundation.org, david@kernel.org, ast@kernel.org, daniel@iogearbox.net, andrii@kernel.org, eddyz87@gmail.com, memxor@gmail.com, kpsingh@kernel.org, matt@bobrowski.net, song@kernel.org, tasos.papagiannnis@gmail.com Subject: [PATCH bpf-next 3/5] bpf: Mark linux_binprm->mm as trusted-or-null Date: Tue, 11 Aug 2026 14:21:52 +0300 Message-ID: <20260811112154.94053-4-tasos.papagiannnis@gmail.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260811112154.94053-1-tasos.papagiannnis@gmail.com> References: <20260811112154.94053-1-tasos.papagiannnis@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Mark linux_binprm->mm as a trusted-or-null nested pointer so BPF programs can pass it to kfuncs after a NULL check. The linux_binprm owns this mm throughout the bprm_check_security hook and clears the pointer only after exec_mmap() installs the new address space. This patch also updates the existing LSM selftest to NULL-check bprm->mm before dereferencing it. Signed-off-by: Anastasios Papagiannis --- kernel/bpf/verifier.c | 5 +++++ tools/testing/selftests/bpf/progs/lsm.c | 5 ++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index add3affc5703..8bdcb65618d0 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -5682,6 +5682,10 @@ BTF_TYPE_SAFE_TRUSTED_OR_NULL(struct dentry) { struct inode *d_inode; }; =20 +BTF_TYPE_SAFE_TRUSTED_OR_NULL(struct linux_binprm) { + struct mm_struct *mm; +}; + BTF_TYPE_SAFE_TRUSTED_OR_NULL(struct socket) { struct sock *sk; }; @@ -5732,6 +5736,7 @@ static bool type_is_trusted_or_null(struct bpf_verifi= er_env *env, { BTF_TYPE_EMIT(BTF_TYPE_SAFE_TRUSTED_OR_NULL(struct socket)); BTF_TYPE_EMIT(BTF_TYPE_SAFE_TRUSTED_OR_NULL(struct dentry)); + BTF_TYPE_EMIT(BTF_TYPE_SAFE_TRUSTED_OR_NULL(struct linux_binprm)); BTF_TYPE_EMIT(BTF_TYPE_SAFE_TRUSTED_OR_NULL(struct vm_area_struct)); =20 return btf_nested_type_is_trusted(&env->log, reg, field_name, btf_id, diff --git a/tools/testing/selftests/bpf/progs/lsm.c b/tools/testing/selfte= sts/bpf/progs/lsm.c index 7de173daf27b..7441d66c080c 100644 --- a/tools/testing/selftests/bpf/progs/lsm.c +++ b/tools/testing/selftests/bpf/progs/lsm.c @@ -113,6 +113,7 @@ int BPF_PROG(test_void_hook, struct linux_binprm *bprm) { __u32 pid =3D bpf_get_current_pid_tgid() >> 32; struct inner_map *inner_map; + struct mm_struct *mm; char args[64]; __u32 key =3D 0; __u64 *value; @@ -121,7 +122,9 @@ int BPF_PROG(test_void_hook, struct linux_binprm *bprm) bprm_count++; =20 bpf_copy_from_user(args, sizeof(args), (void *)bprm->vma->vm_mm->arg_star= t); - bpf_copy_from_user(args, sizeof(args), (void *)bprm->mm->arg_start); + mm =3D bprm->mm; + if (mm) + bpf_copy_from_user(args, sizeof(args), (void *)mm->arg_start); =20 value =3D bpf_map_lookup_elem(&array, &key); if (value) --=20 2.55.0 From nobody Tue Sep 29 06:59:03 2026 Received: from mail-wm1-f52.google.com (mail-wm1-f52.google.com [209.85.128.52]) (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 B828F429CC4 for ; Tue, 11 Aug 2026 11:22:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.52 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786447376; cv=none; b=EPYEF1m+sbeKt8P4LLf4AsMO7NaywECnmM7DkIlCIZHj6FP2WbBVImVj/zI8JEvbu5Ac8/j1LCLXc8uspm60oj/RGngzE2uFlNOy54urJK2vBast4VQxPNLS1fJEX2+Pf0YCF4MPrUq4G7TlpXZY08tEkVJTiqEwiIA2yzpHfnE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786447376; c=relaxed/simple; bh=ixxztuSJW7o8vdbV2a1z906U6yqu6uArf99UAbFq08Y=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=CNvdaxLqguPuTMqYy2cenLzOrvUlgh0+PvWaDdE0VO4PZBTBDsWKUbMZ6LyHsIXIyu390l4ZjcD8OLd7IiRj1O1V3a/ocZPsbEDYn6vyam0C5JcW/Y0PxZvAz3t6+PLLPsobx8U/ikwXWDZCX627pWkruTCsoJOOM4dBNwF+m9c= ARC-Authentication-Results: i=1; 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=dDF/O9pu; arc=none smtp.client-ip=209.85.128.52 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="dDF/O9pu" Received: by mail-wm1-f52.google.com with SMTP id 5b1f17b1804b1-4980dc26022so30724875e9.1 for ; Tue, 11 Aug 2026 04:22:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1786447371; x=1787052171; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=1AOkCrY9bi28aQzDGxTuGUu2U3BAeGsVy+sCSxaGiak=; b=dDF/O9pujjxkKui/V2BVwqMGz6hEr4Heq5fnXdjyI9teoz6LDqXhuP8SaPrdyd1yTX gddt95HjKN5wjSa7eUbaZ6UU66DgW8pQbE55g31FJhyNKMXy0x0yUFIIDRfkZsrBcwOA JTf7tIg4SVDjpmsTqBv4rFLfPvOZZhZG/IpPGXFJQX8VbUzQ0IGdvxpr1GvFGlD17L3e ZUeAzgkHYrC0OYQtauJC87uRHjJTRDRe8ylnqqjOrYtdGsLeIjIe0kIS4HIWGqp1V2tP LtoEHnSjc4jf9Mz491/3nwuUlTcbq8xyhKjCikx9yjWiBh3/JOEFBRYvvwX+aevO9Yh2 kD3A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1786447371; x=1787052171; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=1AOkCrY9bi28aQzDGxTuGUu2U3BAeGsVy+sCSxaGiak=; b=KDLJPYrBia3GExeb+HTD5FAWPHGJhlH+6JPaAfRHCHrQH++jRAMc3n8TbM0Pqp5c1p j5kh6SdJDhsScNQQCYQ4eZG287rfzTbFtVaRm4cXfMxIeSIsgsCE+i+Yhq54UWDjeD4i V/psFEWOXs9gX4M4oQzKGDLE2CN3bY9rTNUY2H3BQlQcOur3t13KHvzk7AitdPwzckMR pmFwBWCoagNSgenT0m4t+ueezKyXL+0iauMEmp38Hyc9VL6bzjxfIDYFaUW2pKpUC4Q/ OzpexJRRfcRl9p1iUCJHblV75bd6pWm7u3okRETQeT5UVhpo65Gc4+C81mcRskADGbEu Targ== X-Gm-Message-State: AOJu0YwdNcCD6ZHsjBrwnZtC362RT9lnTwXA6MzfJxBByIm/Mzgfz9DK HhDiub81W5YO1cf6cEizyouZmkkGUVriCSIgbowL5uttClnnsqbyamjs X-Gm-Gg: AR+sD10Z6YywdHe6QOyJdeM8c6DKMi1bRxb7rHTIPtR+0bDVC50HUcvFAI/C78WxuER Dl48LMRmNRlMW9D9F2rERgcJpsRqMY8Iah8+zP7rr7nX0KS3LZYoImZo8jLe8dQ79Oc4SJbyybh x6qV2s/M20jz1pZSi+XB2fAuVw3JklHGtBDzLoPZJRjSttrTkyNGYFvDNpX52RIkup/w4EH/UVh RfRQmHgIqXTo4KF3PnddRZ90zCKDKdjvdJbwsiFL91ncrv5PxqeYfNWTrFubJRNETw1LXEvFKH3 LTYnlfZeYjn05so55VqwPVlYyKy0ebsKkcmwT+iJhOPm0skffb58yQTMJYPUKDp6vDgIcdJHvVY WOToXX8xfvda/+onZFbn6EKzgoppmkm3EsvcVnatjdiDRNiOGDkuNmQFunQFghpAp31ypFRyPuO T3w4Viy5V4YbN+UcYcZ1ycPa7o5o1+J/X+Bu5oJqpNhvLwSugl3AbP4FUh033kprebFz63PipAs zyR X-Received: by 2002:a05:600c:1c07:b0:499:484a:81d0 with SMTP id 5b1f17b1804b1-4997845f6c7mr32679415e9.9.1786447370443; Tue, 11 Aug 2026 04:22:50 -0700 (PDT) Received: from dell-desktop ([2a02:587:4b5e:1100:7303:647d:7cc4:8552]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4997889c2bcsm47547665e9.3.2026.08.11.04.22.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Aug 2026 04:22:49 -0700 (PDT) From: Anastasios Papagiannis To: bpf@vger.kernel.org Cc: linux-kernel@vger.kernel.org, linux-mm@kvack.org, akpm@linux-foundation.org, david@kernel.org, ast@kernel.org, daniel@iogearbox.net, andrii@kernel.org, eddyz87@gmail.com, memxor@gmail.com, kpsingh@kernel.org, matt@bobrowski.net, song@kernel.org, tasos.papagiannnis@gmail.com Subject: [PATCH bpf-next 4/5] selftests/bpf: Test trusted-or-null linux_binprm->mm Date: Tue, 11 Aug 2026 14:21:53 +0300 Message-ID: <20260811112154.94053-5-tasos.papagiannnis@gmail.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260811112154.94053-1-tasos.papagiannnis@gmail.com> References: <20260811112154.94053-1-tasos.papagiannnis@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add verifier coverage for the linux_binprm->mm trusted-or-null annotation. Verify that bpf_copy_from_user_mm() accepts the pointer after a NULL check and rejects it without one. Signed-off-by: Anastasios Papagiannis --- .../selftests/bpf/progs/verifier_lsm.c | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/tools/testing/selftests/bpf/progs/verifier_lsm.c b/tools/testi= ng/selftests/bpf/progs/verifier_lsm.c index c724bf389f5c..4fc835432af0 100644 --- a/tools/testing/selftests/bpf/progs/verifier_lsm.c +++ b/tools/testing/selftests/bpf/progs/verifier_lsm.c @@ -5,6 +5,10 @@ #include #include "bpf_misc.h" =20 +extern int bpf_copy_from_user_mm(void *dst, u32 dst__sz, + const void *unsafe_ptr__ign, + struct mm_struct *mm, u64 flags) __ksym; + SEC("lsm/file_permission") __description("lsm bpf prog with -4095~0 retval. test 1") __success @@ -212,4 +216,31 @@ __naked int retval_load_resets_bounds(void *ctx) ::: __clobber_all); } =20 +SEC("lsm.s/bprm_check_security") +__description("null checking trusted-or-null linux_binprm mm") +__success +int BPF_PROG(copy_from_user_mm_with_null_check, struct linux_binprm *bprm,= int ret) +{ + struct mm_struct *mm; + char dst[8]; + + mm =3D bprm->mm; + if (!mm) + return 0; + + bpf_copy_from_user_mm(dst, sizeof(dst), (void *)bprm->p, mm, 0); + return 0; +} + +SEC("lsm.s/bprm_check_security") +__description("not null checking trusted-or-null linux_binprm mm") +__failure __msg("Possibly NULL pointer passed to trusted R4") +int BPF_PROG(copy_from_user_mm_without_null_check, struct linux_binprm *bp= rm, int ret) +{ + char dst[8]; + + bpf_copy_from_user_mm(dst, sizeof(dst), (void *)bprm->p, bprm->mm, 0); + return 0; +} + char _license[] SEC("license") =3D "GPL"; --=20 2.55.0 From nobody Tue Sep 29 06:59:03 2026 Received: from mail-wm1-f52.google.com (mail-wm1-f52.google.com [209.85.128.52]) (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 0028043F081 for ; Tue, 11 Aug 2026 11:22:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.52 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786447381; cv=none; b=Bfa8YN8QNinZbwYM6RrMfSZjsMQNvRxo0qOteDmHILBZ46fkUUX1Azz4sWui4bdrJeAlGsIBKR68i3UD7IT1Os6odVxA8lybGrr2ZOsh8tLI+CcCugOn7gSD88BlPrHpPhEQ+k1Xecp6Y55TpQb254naf2HPdLh5s/MuJQipXmU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786447381; c=relaxed/simple; bh=p3Bm9C4/TiK3m7Ewplohyu6u32ZVatvdJv7hlTAaDjY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=srRkyDIl8C/Xqbf6cNs6APRbgo9CnHf5p2P3Gm2S+htF8i/E9090DXgfjjayrABtO1j/xFJDt9dOpnUcCp3KopM9qm8klJ6+9fNNx5BwLqCQFodEWKQMGVpD0rSkBGhc9FjUa3z50KPIB0VX4Ogz3rfoZqfCdwLy8BVgrd5PvrQ= ARC-Authentication-Results: i=1; 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=Zmtq/H51; arc=none smtp.client-ip=209.85.128.52 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="Zmtq/H51" Received: by mail-wm1-f52.google.com with SMTP id 5b1f17b1804b1-4954a32cf1eso12603595e9.3 for ; Tue, 11 Aug 2026 04:22:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1786447374; x=1787052174; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=5Ekcm9Or7cb8hAHyaAjXHw9qfIL5BM5+FlcvqMKj+G4=; b=Zmtq/H51iVg6FFS3t1cWxMf4+2otpAYUxoEoQxjQstxSrXegodNh0vpv2cEIcbUprM dvS4c/OwRKbvIsatBqUrE1AG23eh3VJNX9xQ/8am/2WnNVBJSzzGSOlA0GM+NA+c0jnt hCt/COyJFJiD44pytup3+HpE86Ukp/5rNh44QOUa27MDRVCd7mZJjypD+6wKtpr91mvO qsfjj5J6l7uSUvmQ8Y0JljlFHauUrLy9zSKlqUp2HL37QoqVL7b8pHFc33C2Df2loP6R /Nc9dzWACavPI59/VjSAj7mYhjfq6s/kvCAmPu65YmJQ+HvUs4oGClz2MN1jvC+/sVyr M1jA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1786447374; x=1787052174; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=5Ekcm9Or7cb8hAHyaAjXHw9qfIL5BM5+FlcvqMKj+G4=; b=qwXOHDEDcgZWKnfl+V10GBddUUlhNAd+8Dolu0v08LG50PV8TRkHPXa7ZODccaWqhn L3jvbcW2acLk4qNpPrk5h3elmD4o+ABlkC7T97q5CG2+sP8Uy7ZBNNtCWMD4hNt+1HD7 KjkgRA4WE/I6Gc4xkquh3w+akC7LhLOmEQr+4uzqClOh4vz/niuafj2ETHbyfdWSq2ph VigwH1DrnyK6IIRhRAqPRdgAzcJ2MWlOpVkd7Db/JcYFxy8WwxAMSecSlFutqmB5ZMBI Cyp7m5cRt9SrdXU+uwRXDDe0xdFVhD+ck1CFyqJEP/M11mnZ98UV7NRmbEV+GZ8tw9eI WtzQ== X-Gm-Message-State: AOJu0YyfxQcR6DuQQ1dBvxRDB+/Re7Ea8ZPGsZye9J6tOIfMMW2OhqGF 4z+KebN+cBZ7SBmmG5KJBuLu9pNxgOc2gh6MoS9/mnAeXDZw+R0hGGze X-Gm-Gg: AR+sD129NLafKisC6XPvtwTEQ2BH7eBqYahsj0hYnPywbPOsftpoJi20KGQOoRtS6D7 M7oAWvZT5s2xF2cjhgwQYRrXOemCjZLSvxivb3YzOyYy3i0lm3DD7spq9CfLUnj8ALiAZryqySN un65cVepXtEnlZ3OpkOV61QWFHBZfzd0YV41WMtpqPi8XqoJ23fLuOhetHJcJ1w9PE1gDW2iXsz Y1SfamIztQ5FMhanZayJnftvZGPZjCWKLx89t4HXxTMyJwY/rDN+LGmzys4aF4m7KBUFk4GlsPp 2uU6eC5B9ibXRQmQI41jolbYSSFUUicbP8Nky/QESBXN9FGwZDD5SAlJYUrI/FPIvAhhn4NrFz4 gKFNAP4k6c7amL2RwwA6IC8pJL/r9Q/q1SKB+V/Xwz/3Vq6xvKQAKNGFpS+1hxI23jZ79frV+jI wpcyNRVyXRQ3M+QH+JUCnsdLF5D5qW6VPVFVMMPk1KHe+krOVlBU25n34voF1Usydeg5A++soP9 a8C X-Received: by 2002:a05:600c:34d3:b0:499:6eac:36d2 with SMTP id 5b1f17b1804b1-4997846d9c5mr44664915e9.17.1786447373789; Tue, 11 Aug 2026 04:22:53 -0700 (PDT) Received: from dell-desktop ([2a02:587:4b5e:1100:7303:647d:7cc4:8552]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4997889c2bcsm47547665e9.3.2026.08.11.04.22.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Aug 2026 04:22:53 -0700 (PDT) From: Anastasios Papagiannis To: bpf@vger.kernel.org Cc: linux-kernel@vger.kernel.org, linux-mm@kvack.org, akpm@linux-foundation.org, david@kernel.org, ast@kernel.org, daniel@iogearbox.net, andrii@kernel.org, eddyz87@gmail.com, memxor@gmail.com, kpsingh@kernel.org, matt@bobrowski.net, song@kernel.org, tasos.papagiannnis@gmail.com Subject: [PATCH bpf-next 5/5] selftests/bpf: Test mm_struct user memory kfuncs with linux_binprm Date: Tue, 11 Aug 2026 14:21:54 +0300 Message-ID: <20260811112154.94053-6-tasos.papagiannnis@gmail.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260811112154.94053-1-tasos.papagiannnis@gmail.com> References: <20260811112154.94053-1-tasos.papagiannnis@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add a sleepable BPF LSM program attached to bprm_check_security to test bpf_copy_from_user_mm() and bpf_copy_from_user_mm_str() using the trusted mm_struct from linux_binprm. After checking bprm->mm for NULL, start at bprm->p and verify that bpf_copy_from_user_mm() can copy the contiguous NUL-separated argument data. Then use bpf_copy_from_user_mm_str() to read each argument separately by advancing the offset based on the returned length. Also verify that bpf_copy_from_user_mm() rejects unsupported flags. Signed-off-by: Anastasios Papagiannis --- .../bpf/prog_tests/copy_from_user_bprm.c | 52 +++++++++++++ .../selftests/bpf/progs/copy_from_user_bprm.c | 77 +++++++++++++++++++ 2 files changed, 129 insertions(+) create mode 100644 tools/testing/selftests/bpf/prog_tests/copy_from_user_b= prm.c create mode 100644 tools/testing/selftests/bpf/progs/copy_from_user_bprm.c diff --git a/tools/testing/selftests/bpf/prog_tests/copy_from_user_bprm.c b= /tools/testing/selftests/bpf/prog_tests/copy_from_user_bprm.c new file mode 100644 index 000000000000..3d5080a3975e --- /dev/null +++ b/tools/testing/selftests/bpf/prog_tests/copy_from_user_bprm.c @@ -0,0 +1,52 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include +#include +#include + +#include + +#include "copy_from_user_bprm.skel.h" + +void test_copy_from_user_bprm(void) +{ + struct copy_from_user_bprm *skel; + pid_t child; + int status; + + skel =3D copy_from_user_bprm__open_and_load(); + if (!ASSERT_OK_PTR(skel, "open_and_load")) + return; + + if (!ASSERT_OK(copy_from_user_bprm__attach(skel), "attach")) + goto out; + + child =3D fork(); + if (!ASSERT_GE(child, 0, "fork")) + goto out; + + if (!child) { + char *const argv[] =3D { "first", "second-argument", NULL }; + + skel->bss->monitored_pid =3D getpid(); + execv("/bin/true", argv); + _exit(errno); + } + + if (!ASSERT_EQ(waitpid(child, &status, 0), child, "waitpid")) + goto out; + + if (ASSERT_TRUE(WIFEXITED(status), "child_exited")) + ASSERT_EQ(WEXITSTATUS(status), EPERM, "exec_errno"); + + ASSERT_EQ(skel->bss->bprm_argc, 2, "bprm_argc"); + ASSERT_EQ(skel->bss->invalid_flags_ret, -EINVAL, "invalid_flags_ret"); + ASSERT_EQ(skel->bss->copy_ret, 0, "copy_ret"); + ASSERT_EQ(skel->bss->str_arg0_ret, 6, "str_arg0_ret"); + ASSERT_EQ(skel->bss->str_arg1_ret, 16, "str_arg1_ret"); + ASSERT_EQ(skel->bss->args_match, 1, "args_match"); + ASSERT_EQ(skel->bss->str_args_match, 1, "str_args_match"); + +out: + copy_from_user_bprm__destroy(skel); +} diff --git a/tools/testing/selftests/bpf/progs/copy_from_user_bprm.c b/tool= s/testing/selftests/bpf/progs/copy_from_user_bprm.c new file mode 100644 index 000000000000..d7132bca6edc --- /dev/null +++ b/tools/testing/selftests/bpf/progs/copy_from_user_bprm.c @@ -0,0 +1,77 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include "vmlinux.h" + +#include +#include +#include +#include "bpf_misc.h" + +char _license[] SEC("license") =3D "GPL"; + +static const char expected_args[] =3D "first\0second-argument"; +static const char expected_arg0[] =3D "first"; +static const char expected_arg1[] =3D "second-argument"; + +int monitored_pid; +int bprm_argc; +int invalid_flags_ret; +int copy_ret; +int str_arg0_ret; +int str_arg1_ret; +int args_match; +int str_args_match; + +extern int bpf_copy_from_user_mm(void *dst, u32 dst__sz, + const void *unsafe_ptr__ign, + struct mm_struct *mm, u64 flags) __ksym; + +extern int bpf_copy_from_user_mm_str(void *dst, u32 dst__sz, + const void *unsafe_ptr__ign, + struct mm_struct *mm, u64 flags) __ksym; + +SEC("lsm.s/bprm_check_security") +int BPF_PROG(check_exec_args, struct linux_binprm *bprm, int ret) +{ + u32 pid =3D bpf_get_current_pid_tgid() >> 32; + struct mm_struct *mm; + char args[sizeof(expected_args)]; + char arg0[32]; + char arg1[32]; + + if (ret || pid !=3D monitored_pid) + return ret; + + mm =3D bprm->mm; + if (!mm) + return 0; + + bprm_argc =3D bprm->argc; + + invalid_flags_ret =3D bpf_copy_from_user_mm(args, sizeof(args), + (void *)bprm->p, mm, 1); + + copy_ret =3D bpf_copy_from_user_mm(args, sizeof(args), + (void *)bprm->p, mm, 0); + if (copy_ret) + return 0; + + args_match =3D !__builtin_memcmp(args, expected_args, sizeof(expected_arg= s)); + + str_arg0_ret =3D bpf_copy_from_user_mm_str(arg0, sizeof(arg0), + (void *)bprm->p, mm, + BPF_F_PAD_ZEROS); + if (str_arg0_ret !=3D sizeof(expected_arg0)) + return 0; + + str_arg1_ret =3D bpf_copy_from_user_mm_str(arg1, sizeof(arg1), + (void *)(bprm->p + str_arg0_ret), + mm, BPF_F_PAD_ZEROS); + if (str_arg1_ret !=3D sizeof(expected_arg1)) + return 0; + + str_args_match =3D !__builtin_memcmp(arg0, expected_arg0, sizeof(expected= _arg0)) && + !__builtin_memcmp(arg1, expected_arg1, sizeof(expected_arg1)); + + return args_match && str_args_match ? -EPERM : 0; +} --=20 2.55.0