From nobody Fri Sep 25 07:56:45 2026 Received: from mail-wm2-f12.google.com (mail-wm2-f12.google.com [74.125.225.140]) (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 8F62F3A5E9F for ; Tue, 15 Sep 2026 08:03:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.225.140 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789459413; cv=none; b=JvtsnfX+8CIQ7lpinzIdEkaMcuDasP7R0buGBSBmXI8gqexNoAyntSb0lQq9EadTyrAVfgN12Uj4C/AvVvlMrQcl9Uokk0AEsN7Yui4MpP9XizXoT9nzJ8PmlcIPKM4JWmWPRANiifXQP3qqewvO8u4J47wu/9skBblA/DJQ9+A= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789459413; c=relaxed/simple; bh=gPtSx4zRiY9vNNn8/J/N7Zvn2DKwUG6rUjRqgnMLI5Y=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=iepp1fUmrJ/BajSqq1nB29SkUZ/GOWxmBUAHsqsZiRTPr1CTMdF9uAtdJzKD242T/0FAoTY9UzMH8jK5n6U7jdeh89Bto7IvqA/R+wUAQNicyIBPv0jFThEPQrG891MUYbmyngTBWlkCJE4o5yYQ9PesUek+guY0+dIzS7/ZrEA= 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=F+E0dsev; arc=none smtp.client-ip=74.125.225.140 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="F+E0dsev" Received: by mail-wm2-f12.google.com with SMTP id 5b1f17b1804b1-49e69b9e16aso27351605e9.1 for ; Tue, 15 Sep 2026 01:03:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1789459409; x=1790064209; 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=LNtsDssHmIZmCVL8XDm90qTc9aUzb3Y+uIIuk09X5PE=; b=F+E0dsevQRh1g0hUHO88J5KfD3eUQoOrAAqQd67snMXvFAPq0IzB5Y0qyq0zPuCRNq JbKwcOWxNfvYEr29LRMWSMPYorr822fE0Q29gK1bEVv2F60SYI0Hs3cb37wuayFwx3ms Yl/ZTPUK5O6PdK74r+9TnXd4lSlHS2X5HAghsi+YqSg08k20ZXaIL0MiwoAw+V2Uz3ly +bD+Sol1/Wq1Nl04te9VGZ5bwEVCF6kwWZrPSvmz3b/4erixSTJv47llL08aQQeHvJT4 UyNTPlStP5CpBL0ajqSsjEI0NMn/7AhgKZOY34TjHPqRqlwE8AaWkG11TL1YV+wRvut+ Z5Xw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1789459409; x=1790064209; 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=LNtsDssHmIZmCVL8XDm90qTc9aUzb3Y+uIIuk09X5PE=; b=M4FV+eyTEUN22ZFvYPoggXMaV53yAZ1Q4717FO/GrrAQrEMjnBA+wS1zctHCzS/A3B kbZ25fD3K7duj6IYhY0xUiEvVoA5qPhgP430Sr5fp7f/iiexG9F0ZRa+FUPm9tkuKcTN HrDjcElABykURhNOb+yW5UIgstHuV3BwOgk9mj8sLWRYdoExNlk9TBb4WYnzNh4ZZ5p2 5ldZWailREqqLl7DInqz3yCRJW0L6vwLNPaSFUVjtg3MyQUf7A68TeZpdc5+5ns9T5zj fgvVjW2NnicmgI9lT7Y0unZtrw+NfCGgvZoT/x+OT+ggKQMX4Tt79MN9qLPU6w8XIhXA MToQ== X-Forwarded-Encrypted: i=1; AKwUvBy8ZX85fMGEvteSevTKXbCLSg9L07wCwI2W7lZugJ6vJsmcOFJ02z+AEoAy+2l2sHZi+Hi4RJaHxfbJcLc=@vger.kernel.org X-Gm-Message-State: AFuF++kCpYlOEc/Om4rZOPBQGZ/RBLjqWu3r2UcAq/hkVBQNOnZAxChW UHPhl5qajsgTBRRl9XUWtMePUlTU5J93XHVJFtfS9uGaY+8njEFafVQ0 X-Gm-Gg: AYBFou2qI8ZGtyMXXQhy34KGGg61k+TgWRYtReIT6tOStt70KmrBaavAS1uscoOI8yc BV6JmJkQ9Y8kqvbormNgEGs1sfFVFQmQbpky3Wc1BW9ztOn8nDYg9sExqgRSO+4L3TDKdUfgrqQ UtAm1kbQ88me93kCJ70GsieP1hQhvIPwbgu16SN0RB1mKBCxkc1/glkf7BEmrHSi0kX8m5ex8bS aLbq3n2N759g1//OGU06Ty9sWE5AcqCEWUzj6tnX6o14UnOQQOHsz6x8XDhpSyl9yOprEhozB19 PWZp+wUjIhaNWbsepqamvs3/K70N84OkW0yuF54niVZVPRNtADH3x8vGw/cu+seNv4MFnnn0L8d G9s7m2dCQ3DAD/cphJyxagd3XiJvQYmnvL7oWdDjxEpCf7Fw9M49NwTRTp4v20m4HdvCMw4BU3/ 0CiATwb8q1Ais7M0Ja/Qy782MC2bQxfzqsZ7RegbFJ8T9MU0YCnJ+lVafKhEOuowisezqsbpP8K zTLcAxiss4zm4k= X-Received: by 2002:a05:600c:1c19:b0:49c:fa21:1c84 with SMTP id 5b1f17b1804b1-49e7a692504mr84685885e9.25.1789459408392; Tue, 15 Sep 2026 01:03:28 -0700 (PDT) Received: from dell-desktop ([2a02:587:4b4e:8500:290c:210b:1c76:5710]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-486eb35c071sm33764675f8f.33.2026.09.15.01.03.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 15 Sep 2026 01:03:27 -0700 (PDT) From: Anastasios Papagiannis To: bpf@vger.kernel.org Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org, david@kernel.org, akpm@linux-foundation.org, andrii@kernel.org, ast@kernel.org, brauner@kernel.org, daniel@iogearbox.net, eddyz87@gmail.com, kpsingh@kernel.org, ljs@kernel.org, matt@bobrowski.net, memxor@gmail.com, song@kernel.org, sun.jian.kdev@gmail.com, utilityemal77@gmail.com, viro@zeniv.linux.org.uk, tasos.papagiannnis@gmail.com Subject: [PATCH bpf-next v7 1/5] mm: Add copy_remote_mm_str() Date: Tue, 15 Sep 2026 11:02:51 +0300 Message-ID: <20260915080255.48929-2-tasos.papagiannnis@gmail.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260915080255.48929-1-tasos.papagiannnis@gmail.com> References: <20260915080255.48929-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. Add copy_remote_mm_str(), which operates directly on a struct mm_struct. Use a common internal interface for the MMU and NOMMU implementations and define both public wrappers in mm/util.c. Preserve the existing copy_remote_vm_str() behavior, including handling zero-length requests before acquiring the task's mm. Signed-off-by: Anastasios Papagiannis Acked-by: Lorenzo Stoakes (ARM) Acked-by: David Hildenbrand (Arm) --- include/linux/mm.h | 8 +++--- mm/internal.h | 3 +++ mm/memory.c | 41 ++---------------------------- mm/nommu.c | 41 ++---------------------------- mm/util.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 73 insertions(+), 82 deletions(-) diff --git a/include/linux/mm.h b/include/linux/mm.h index dd09c438fa23..63f40e615754 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -3325,10 +3325,10 @@ extern int access_process_vm(struct task_struct *ts= k, unsigned long addr, extern int access_remote_vm(struct mm_struct *mm, unsigned long addr, void *buf, int len, unsigned int gup_flags); =20 -#ifdef CONFIG_BPF_SYSCALL -extern int copy_remote_vm_str(struct task_struct *tsk, unsigned long addr, - void *buf, int len, unsigned int gup_flags); -#endif +int copy_remote_mm_str(struct mm_struct *mm, unsigned long addr, + void *buf, int len, unsigned int gup_flags); +int copy_remote_vm_str(struct task_struct *tsk, unsigned long addr, + void *buf, int len, unsigned int gup_flags); =20 long get_user_pages_remote(struct mm_struct *mm, unsigned long start, unsigned long nr_pages, diff --git a/mm/internal.h b/mm/internal.h index 38b1165212c9..557b29381355 100644 --- a/mm/internal.h +++ b/mm/internal.h @@ -25,6 +25,9 @@ struct folio_batch; struct hstate; =20 +int __copy_remote_mm_str(struct mm_struct *mm, unsigned long addr, + void *buf, int len, unsigned int gup_flags); + struct huge_bootmem_page { struct list_head list; struct hstate *hstate; diff --git a/mm/memory.c b/mm/memory.c index 8b0c2c735d3d..fe2f5e988fb9 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -7331,8 +7331,8 @@ EXPORT_SYMBOL_GPL(access_process_vm); * Copy a string from another process's address space as given in mm. * If there is any error return -EFAULT. */ -static int __copy_remote_vm_str(struct mm_struct *mm, unsigned long addr, - void *buf, int len, unsigned int gup_flags) +int __copy_remote_mm_str(struct mm_struct *mm, unsigned long addr, + void *buf, int len, unsigned int gup_flags) { void *old_buf =3D buf; int err =3D 0; @@ -7407,43 +7407,6 @@ static int __copy_remote_vm_str(struct mm_struct *mm= , unsigned long addr, return err; return buf - old_buf; } - -/** - * copy_remote_vm_str - copy a string from another process's address space. - * @tsk: the task of the target 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 guaranteed to leave NUL-terminat= ed - * buffer. On any error, return -EFAULT. - */ -int copy_remote_vm_str(struct task_struct *tsk, unsigned long addr, - void *buf, int len, unsigned int gup_flags) -{ - struct mm_struct *mm; - int ret; - - if (unlikely(len =3D=3D 0)) - return 0; - - mm =3D get_task_mm(tsk); - if (!mm) { - *(char *)buf =3D '\0'; - return -EFAULT; - } - - ret =3D __copy_remote_vm_str(mm, addr, buf, len, gup_flags); - - mmput(mm); - - return ret; -} -EXPORT_SYMBOL_GPL(copy_remote_vm_str); #endif /* CONFIG_BPF_SYSCALL */ =20 /* diff --git a/mm/nommu.c b/mm/nommu.c index 498e01ee40b0..98596e60311f 100644 --- a/mm/nommu.c +++ b/mm/nommu.c @@ -1746,8 +1746,8 @@ EXPORT_SYMBOL_GPL(access_process_vm); * Copy a string from another process's address space as given in mm. * If there is any error return -EFAULT. */ -static int __copy_remote_vm_str(struct mm_struct *mm, unsigned long addr, - void *buf, int len) +int __copy_remote_mm_str(struct mm_struct *mm, unsigned long addr, + void *buf, int len, unsigned int gup_flags) { unsigned long addr_end; struct vm_area_struct *vma; @@ -1781,43 +1781,6 @@ static int __copy_remote_vm_str(struct mm_struct *mm= , unsigned long addr, mmap_read_unlock(mm); return ret; } - -/** - * copy_remote_vm_str - copy a string from another process's address space. - * @tsk: the task of the target 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 guaranteed to leave NUL-terminat= ed - * buffer. On any error, return -EFAULT. - */ -int copy_remote_vm_str(struct task_struct *tsk, unsigned long addr, - void *buf, int len, unsigned int gup_flags) -{ - struct mm_struct *mm; - int ret; - - if (unlikely(len =3D=3D 0)) - return 0; - - mm =3D get_task_mm(tsk); - if (!mm) { - *(char *)buf =3D '\0'; - return -EFAULT; - } - - ret =3D __copy_remote_vm_str(mm, addr, buf, len); - - mmput(mm); - - return ret; -} -EXPORT_SYMBOL_GPL(copy_remote_vm_str); #endif /* CONFIG_BPF_SYSCALL */ =20 /** diff --git a/mm/util.c b/mm/util.c index bf0513d1d3d0..47c2e3ae8496 100644 --- a/mm/util.c +++ b/mm/util.c @@ -1061,6 +1061,68 @@ int get_cmdline(struct task_struct *task, char *buff= er, int buflen) return res; } =20 +#ifdef CONFIG_BPF_SYSCALL +/** + * 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. If @len is zero, return 0 without acces= sing + * @buf. Otherwise, @buf is always NUL-terminated. 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_mm_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 + * @addr: start address to read from + * @buf: destination buffer + * @len: number of bytes to copy + * @gup_flags: flags modifying lookup behaviour + * + * Return: number of bytes copied from @addr (source) to @buf (destination= ), + * not including the trailing NUL. If @len is zero, return 0 without acces= sing + * @buf. Otherwise, @buf is always NUL-terminated. On any error, return + * -EFAULT. + */ +int copy_remote_vm_str(struct task_struct *tsk, unsigned long addr, + void *buf, int len, unsigned int gup_flags) +{ + struct mm_struct *mm; + int ret; + + if (unlikely(len =3D=3D 0)) + return 0; + + mm =3D get_task_mm(tsk); + if (!mm) { + *(char *)buf =3D '\0'; + return -EFAULT; + } + + ret =3D __copy_remote_mm_str(mm, addr, buf, len, gup_flags); + + mmput(mm); + + return ret; +} +EXPORT_SYMBOL_GPL(copy_remote_vm_str); +#endif /* CONFIG_BPF_SYSCALL */ + int __weak memcmp_pages(struct page *page1, struct page *page2) { char *addr1, *addr2; --=20 2.55.0 From nobody Fri Sep 25 07:56:45 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 8D73139EF2E for ; Tue, 15 Sep 2026 08:03:33 +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=1789459416; cv=none; b=QUUpcdVB53E9IuR+oX6ySyCJzTHoSy1FJGkWKyVd8IO3//T3YJ9JAYD7RJ5Eicfe68y6q3JvuckI+Aq7DiLyDnDkzubfz3LkBg4/AWpOAY4mzHsKgCap3FVhGlWUWZhOVOUsiBT5LfBWfZSo1W7cYUpUrrWn/hUb5wYDqLEnI6w= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789459416; c=relaxed/simple; bh=oxBm833C8T+jxHgAdbU6D4xcv4E4TYoli1xZPpTW0yQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=joSRe4bbjJBL5hTqZ6+5H2z7OIH+PWwdb4lY/07U8IYedekVz7/N9w+9eao24zA1+vwKXUV3N+LDnhVoFpbddY33iSm+73WYDjhbV2OVDklAItFpHFPsDL/Qgo/g2zYEtx10eltRL5f1B2X577ZuRD8kQ5j0VEcLG2tZC581EHc= 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=IWvY3Oh2; 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="IWvY3Oh2" Received: by mail-wm1-f52.google.com with SMTP id 5b1f17b1804b1-49e6b280cadso36587205e9.1 for ; Tue, 15 Sep 2026 01:03:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1789459411; x=1790064211; 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=BcITG13Gvl8i0HA4g724jWVmnWns/ceZ5ECxTEaQlok=; b=IWvY3Oh2hOkMZTpQDhBFLKNByCuBv/M1AtXa7HF///XG3qWAO1LqR35wT2PSYQeoQc vEY8/T6TtINWfgTX13h1Cz69IoQTyhrgMs/yWzpTgCg+5F98c0Ap+nX0Jg2PLuaFOrK+ kyqF8IeofK4zWbLMM1jzkq6kx81NW76Y/3EZ6M7Yg9TLAQgD7/RsU3EG+Wx+gWmXtvX8 lU5Wus++LBDpryNqS+GZnkpWkbv3u+/z0QryXYrmdiKCbcZ+KDKvoZhfTR4xzukVgJXN dBEvqEMDXm1ft4qulXaJDm8KopcfZQoiajqFcsrA8qQtDq2AdDGa6VmIy0rAEdPKYCi2 3PRw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1789459412; x=1790064212; 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=BcITG13Gvl8i0HA4g724jWVmnWns/ceZ5ECxTEaQlok=; b=GAg7ofmYfx0vHs0VYnU/heBPHaaLJ7lIWH+08bY33YZcKonaMsl2KO833SX5nmanGI D4dx+G2DrCegyzV/3x9u7obX1Ss+qvk5lAviNtTiWeDoqkk0ON1yblmr8OUQNSrzIWV2 0jfQV8YVzDfQh5vuCsZaDKv1chmhb1urfBX9glLyW2ir8jCvGDdy/LCezLb8ITfActZm XPUEV0BT41ty9Qn3aTLjuaHTz2F4z+jxjnkAExwNfUzsL+kumGWuxAU1497ikWzfhbAk YPWSzhBhfDa+Wcw3jWvCuzl6jfe16Y5uVXRBD7g9PvNE3opS4YwSW5mXpAo1Bfl9xQie hfSw== X-Forwarded-Encrypted: i=1; AKwUvBxwIUtEZb3ECFi03muBhIjrspU7blMx6AMuJ1nBRzEysh54qYE2NpA6oryn8hZ3RiGK+TR8vWudLcozPxc=@vger.kernel.org X-Gm-Message-State: AFuF++lQ66RLEjLTck/ZiyKUemAyOpwE3Fwzn57C0M9vJJCDAxYmySCn Cv1cDMws11D4d08q/ojrlrX2Ku1u0McIFCLq1/nfl+iyB7pqqfilhf3C X-Gm-Gg: AYBFou2rY5aeQ6a1mj0jygtBdf64wRaXVDDoRYV1tHqlmyTpnGcW6FpaDx3kk/v9fuP gqBWR8LmnEd3DdRN7I4OMLuGtBTi9aRKDXqak5Gc9Tkp+HA8xPZi4WWzV5aXKNda3YzforL1jvI 6O8CjuJE9INdX8sZgc0o7qqtAOhxhq8hJVVLnB9yscmDhbc4tghF1dxyJiFEoxvyCdsypTh3UpI h7yhIS2lZT9ywdrNxF57fGxUI8X0zSpvWX9RQ5AaoNuOIxwI99dnwFYcclOABHIHk3X5uthfOYK yVbSJfjmigVsJC99z5dpmRCEszfttBQ2hdQ6Alh+wWRISNIBjiwH//lOPu5dE684z1bsE8gjSZI 3TDwIGRv/3A02oG7cl/2ROUq0DqFBo0lc1kJTtD5EBGEd+UEgH+QBkpTLG2dJk9kZRuPSN1O9/i kvBT1AlWcxehcGQEJZ7UqCeZincXJv5hgGCGeciuAHCE/b8MkfmwPUnfnoXg26H6frNe9GDs8Sz XwQkKCH96rW956973cy8YxVmus= X-Received: by 2002:adf:e19c:0:b0:487:939:23aa with SMTP id ffacd0b85a97d-487093923e3mr1057036f8f.10.1789459411449; Tue, 15 Sep 2026 01:03:31 -0700 (PDT) Received: from dell-desktop ([2a02:587:4b4e:8500:290c:210b:1c76:5710]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-486eb35c071sm33764675f8f.33.2026.09.15.01.03.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 15 Sep 2026 01:03:31 -0700 (PDT) From: Anastasios Papagiannis To: bpf@vger.kernel.org Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org, david@kernel.org, akpm@linux-foundation.org, andrii@kernel.org, ast@kernel.org, brauner@kernel.org, daniel@iogearbox.net, eddyz87@gmail.com, kpsingh@kernel.org, ljs@kernel.org, matt@bobrowski.net, memxor@gmail.com, song@kernel.org, sun.jian.kdev@gmail.com, utilityemal77@gmail.com, viro@zeniv.linux.org.uk, tasos.papagiannnis@gmail.com Subject: [PATCH bpf-next v7 2/5] exec: Clear bprm->mm before dropping its reference Date: Tue, 15 Sep 2026 11:02:52 +0300 Message-ID: <20260915080255.48929-3-tasos.papagiannnis@gmail.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260915080255.48929-1-tasos.papagiannnis@gmail.com> References: <20260915080255.48929-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" Once mmput() drops the final reference to bprm->mm, the pointer must no longer remain accessible through struct linux_binprm. The successful exec path and the bprm initialization error path already clear bprm->mm when ownership is transferred or released. Do the same in free_bprm() before calling mmput(). This is required for BPF kfuncs where bprm->mm is either NULL or points to a live mm_struct to ensure safe access. Signed-off-by: Anastasios Papagiannis Reviewed-by: Sun Jian --- fs/exec.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/fs/exec.c b/fs/exec.c index 745f6eb5279e..4ddd403fd91c 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -1456,9 +1456,12 @@ void bprm_drop_loader(struct linux_binprm *bprm) =20 static void free_bprm(struct linux_binprm *bprm) { - if (bprm->mm) { + struct mm_struct *mm =3D bprm->mm; + + if (mm) { acct_arg_size(bprm, 0); - mmput(bprm->mm); + bprm->mm =3D NULL; + mmput(mm); } if (bprm->user_ns) put_user_ns(bprm->user_ns); --=20 2.55.0 From nobody Fri Sep 25 07:56:45 2026 Received: from mail-wr2-f12.google.com (mail-wr2-f12.google.com [74.125.225.76]) (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 BBF2C3AB28F for ; Tue, 15 Sep 2026 08:03:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.225.76 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789459419; cv=none; b=AVKZSjLxTjfOXl7pRq3bgWuTMByeINQo5V+SxXU38Q8yOHoiVQbAyenUIZ4xA9OLYp0SNm2XEdkUoKPHw/xfrVaMzcjO6BAJNFKvbFlPlZyxjmwH6Qkj52vk3RAkDBQ9KD4hduWWmTWCJzhDyfs25DT0tDGvcwdFxPNEEwOYm2k= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789459419; c=relaxed/simple; bh=Q/Mlj7u02ffjMHUUly5ZVRZxAUczNu/Z2hQt+HvgIbk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=o8akxF47i+ldn7aI4UPZd6NZpc4dQ95SlV4ZQWMjHuBckPwSEOq8F+fzF3nE/C/1ci2MYpNU/zOSy4eUs6cZML68A0FlecC4NN9gLNLHUbcyBkLv6NvPeeJAnfibI+BL5ya1TcY4gBa6ifNv7JKaF13jWmkWlhHQqs5rFyyZ5/M= 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=V2V0VAyY; arc=none smtp.client-ip=74.125.225.76 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="V2V0VAyY" Received: by mail-wr2-f12.google.com with SMTP id ffacd0b85a97d-482f6350f88so1640912f8f.2 for ; Tue, 15 Sep 2026 01:03:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1789459415; x=1790064215; 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=ByCPXnnC7KpXzoaLnGFreo/33oFOqB5OMw022838T44=; b=V2V0VAyYDjWOSmolt2VQBx7u9YD2XsoSEIC6QS2XjYOVdI47wfloaFUjuINacZLJ64 sU8axkFwfXcYrqcM32QN05tt1ZIK/RLHh40MNaUA7Kz1VeDwLjYEnDk183Aq6Q1Zauvx 8pDIhvssvfpLns9f8VuWtKR0TA2eBqkULeCbyGp06hz1mHjocsmrw6QrecoYMsP1LZej A2Ky65IQjpazIEfNOcJ2OArCesJHp1xL7Zu9WxwzLBq9ISy1+Stps6RqcoZNG3G0OBCg w+sHmLTcvGCb7JR4razaJKq/sWhFSJ3iOjlgplicJqiWHEPo/U7dKVZXkPpBsUmwM6p/ fRCA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1789459415; x=1790064215; 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=ByCPXnnC7KpXzoaLnGFreo/33oFOqB5OMw022838T44=; b=pxv12kFJWYSkI6epaAsPPSbKQETdy1r/OcosswmkzhBkTdzhjrImJhWYQB+dXl/uT1 22PdLVEuSYtBe2YaLnTvB6SFWIGTv1lkVUUScmJ5zyS8SJkE3eVaRSgj5JXEyaYmKORB oXMq8GDvKsvGGboJ8q6mddVjXFcxaMBtsC/X+gOr6Wgka4IBG1mKxqKxqvnFtxO9weg/ TIU0VkD17crF8WM1MPx6rnHx3vNuM8oQRT+8CUisLTyF4ap8sRy8NSOJ5Qnm57NLaviE PN5ApWvwSoVoegA6jUHN+IzvLGoNFL+7nXXURDk5ldmSgUGRFLJ0962dkxRXiU9TECok P85w== X-Forwarded-Encrypted: i=1; AKwUvBzmyhOs9UbkezNKI/5A2+STZMJUEwNMC/I7FqvLdWeMjH/E26Hxao84q9MBTmAB1YMUgOLWgrbftVJlXa4=@vger.kernel.org X-Gm-Message-State: AFuF++mPWxpQdssd4WLSM2xPcAZjq8xf3410arul9iByy2jXY3KoXhsM ctHyqZ515NqizZBrrASax4x/C8QRIcv1DdvQamJk+mH6vmz7xXKmgOwf X-Gm-Gg: AYBFou2Yh0G9edYkmqA5CrPI4N0Bgpxqx8oohIJlndGAzjTXQcLKvZr5jdNSBrgR9OK AuzbmzIRdAR0aYaCgCdDobuvcfaXufF1DVCTD7drigLhK1RGd1mjxQsJetWwVDxp8BsIRR7zS5s b+GBkw0NRpqItEaZcxhZffmfz2TbmAdAkwFpjadabyjHCmYIDmazvPUx2WCBF1Gciuyb3NSXLIp oCFys/rfK2f2jdFoos8/+xqejw7BTvguUv/FNUsRu3hAQltGLiRA5jHed/UQAYl2cxKH+3Wtj19 lWQXyBqdZX5MNjoIIzqt6Wof5QALoBRQZV7NG5EwJ4Fd3gxDa+5MzD752Jnyl1EscQ+Iexv4T+9 HFRsno4wb74zWoQwPxXn8BRx5RpxWg0kwYhmTZO3olMYM5u9MFyrAKzaMwskUo7+JAN/KKW2KWf S69oJMSxUOk83esslZ8Kfk9FvB5sbI/BQbdmOMpo2uPdefhoe1BA76huNrN727qz5zC4zEUBNjz gN3EajGuRF69gU= X-Received: by 2002:a05:6000:178d:b0:487:77c:f6c4 with SMTP id ffacd0b85a97d-487077cf6f9mr1897099f8f.35.1789459414412; Tue, 15 Sep 2026 01:03:34 -0700 (PDT) Received: from dell-desktop ([2a02:587:4b4e:8500:290c:210b:1c76:5710]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-486eb35c071sm33764675f8f.33.2026.09.15.01.03.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 15 Sep 2026 01:03:33 -0700 (PDT) From: Anastasios Papagiannis To: bpf@vger.kernel.org Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org, david@kernel.org, akpm@linux-foundation.org, andrii@kernel.org, ast@kernel.org, brauner@kernel.org, daniel@iogearbox.net, eddyz87@gmail.com, kpsingh@kernel.org, ljs@kernel.org, matt@bobrowski.net, memxor@gmail.com, song@kernel.org, sun.jian.kdev@gmail.com, utilityemal77@gmail.com, viro@zeniv.linux.org.uk, tasos.papagiannnis@gmail.com Subject: [PATCH bpf-next v7 3/5] bpf: Add user memory access kfuncs for mm_struct Date: Tue, 15 Sep 2026 11:02:53 +0300 Message-ID: <20260915080255.48929-4-tasos.papagiannnis@gmail.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260915080255.48929-1-tasos.papagiannnis@gmail.com> References: <20260915080255.48929-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" On CONFIG_MMU kernels, when security_bprm_check() runs, the argument and environment strings for the exec have been copied into bprm->mm. The new address space is not associated with a task_struct until exec_mmap(), so existing BPF user memory helpers cannot access it. 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. Refactor the task-based helpers and the new mm-based kfuncs to share static internal implementations. The task-based interfaces validate their arguments before acquiring and holding a reference to the task's mm for the copy. No behavior change is intended for the existing task-based interfaces. Register both new kfuncs and mark them KF_SLEEPABLE because accessing a remote address space can fault. Signed-off-by: Anastasios Papagiannis Reviewed-by: Matt Bobrowski =20 --- kernel/bpf/helpers.c | 130 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 118 insertions(+), 12 deletions(-) diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c index 051b6654e57c..f6b3eee6098a 100644 --- a/kernel/bpf/helpers.c +++ b/kernel/bpf/helpers.c @@ -679,9 +679,44 @@ const struct bpf_func_proto bpf_copy_from_user_proto = =3D { .arg3_type =3D ARG_ANYTHING, }; =20 +static int __bpf_copy_from_user_mm(void *dst, u32 size, + const void __user *user_ptr, + struct mm_struct *mm) +{ + int ret; + + ret =3D access_remote_vm(mm, (unsigned long)user_ptr, dst, size, 0); + if (ret =3D=3D size) + return 0; + + memset(dst, 0, size); + /* Return -EFAULT for partial read */ + return ret < 0 ? ret : -EFAULT; +} + +static int __bpf_copy_from_user_mm_str(void *dst, u32 size, + const void __user *user_ptr, + struct mm_struct *mm, u64 flags) +{ + int ret; + + ret =3D copy_remote_mm_str(mm, (unsigned long)user_ptr, dst, size, 0); + if (ret < 0) { + if (flags & BPF_F_PAD_ZEROS) + memset(dst, 0, size); + return ret; + } + + if (flags & BPF_F_PAD_ZEROS) + memset(dst + ret, 0, size - ret); + + return ret + 1; +} + BPF_CALL_5(bpf_copy_from_user_task, void *, dst, u32, size, const void __user *, user_ptr, struct task_struct *, tsk, u64, flags) { + struct mm_struct *mm; int ret; =20 /* flags is not used yet */ @@ -691,13 +726,16 @@ BPF_CALL_5(bpf_copy_from_user_task, void *, dst, u32,= size, if (unlikely(!size)) return 0; =20 - ret =3D access_process_vm(tsk, (unsigned long)user_ptr, dst, size, 0); - if (ret =3D=3D size) - return 0; + mm =3D get_task_mm(tsk); + if (!mm) { + memset(dst, 0, size); + return -EFAULT; + } =20 - memset(dst, 0, size); - /* Return -EFAULT for partial read */ - return ret < 0 ? ret : -EFAULT; + ret =3D __bpf_copy_from_user_mm(dst, size, user_ptr, mm); + mmput(mm); + + return ret; } =20 const struct bpf_func_proto bpf_copy_from_user_task_proto =3D { @@ -3659,6 +3697,68 @@ __bpf_kfunc int bpf_copy_from_user_str(void *dst, u3= 2 dst__sz, const void __user return ret + 1; } =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 an attempted copy cannot be completed in full. Unsupported + * flags return -EINVAL without modifying @dst. + * + * 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) +{ + if (unlikely(flags)) + return -EINVAL; + + if (unlikely(!dst__sz)) + return 0; + + return __bpf_copy_from_user_mm(dst, dst__sz, unsafe_ptr__ign, mm); +} + +/** + * 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 the flags are valid and BPF_F_PAD_ZEROS is set, the unused portion of + * @dst is cleared on success and all of @dst is cleared on a copy failure. + * Unsupported flags return -EINVAL without modifying @dst. + * + * 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) +{ + if (unlikely(flags & ~BPF_F_PAD_ZEROS)) + return -EINVAL; + + if (unlikely(dst__sz =3D=3D 0)) + return 0; + + return __bpf_copy_from_user_mm_str(dst, dst__sz, unsafe_ptr__ign, + mm, flags); +} + /** * bpf_copy_from_user_task_str() - Copy a string from an task's address sp= ace * @dst: Destination address, in kernel space. This buffer mu= st be @@ -3682,6 +3782,7 @@ __bpf_kfunc int bpf_copy_from_user_task_str(void *dst= , u32 dst__sz, const void __user *unsafe_ptr__ign, struct task_struct *tsk, u64 flags) { + struct mm_struct *mm; int ret; =20 if (unlikely(flags & ~BPF_F_PAD_ZEROS)) @@ -3690,17 +3791,20 @@ __bpf_kfunc int bpf_copy_from_user_task_str(void *d= st, u32 dst__sz, if (unlikely(dst__sz =3D=3D 0)) return 0; =20 - ret =3D copy_remote_vm_str(tsk, (unsigned long)unsafe_ptr__ign, dst, dst_= _sz, 0); - if (ret < 0) { + mm =3D get_task_mm(tsk); + if (!mm) { if (flags & BPF_F_PAD_ZEROS) memset(dst, 0, dst__sz); - return ret; + else + *(char *)dst =3D '\0'; + return -EFAULT; } =20 - if (flags & BPF_F_PAD_ZEROS) - memset(dst + ret, 0, dst__sz - ret); + ret =3D __bpf_copy_from_user_mm_str(dst, dst__sz, unsafe_ptr__ign, + mm, flags); + mmput(mm); =20 - return ret + 1; + return ret; } =20 /* Keep unsigned long in prototype so that kfunc is usable when emitted to @@ -4925,6 +5029,8 @@ BTF_ID_FLAGS(func, bpf_iter_bits_new, KF_ITER_NEW) BTF_ID_FLAGS(func, bpf_iter_bits_next, KF_ITER_NEXT | KF_RET_NULL) BTF_ID_FLAGS(func, bpf_iter_bits_destroy, KF_ITER_DESTROY) BTF_ID_FLAGS(func, bpf_copy_from_user_str, KF_SLEEPABLE) +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_copy_from_user_task_str, KF_SLEEPABLE) BTF_ID_FLAGS(func, bpf_get_kmem_cache) BTF_ID_FLAGS(func, bpf_iter_kmem_cache_new, KF_ITER_NEW | KF_SLEEPABLE) --=20 2.55.0 From nobody Fri Sep 25 07:56:45 2026 Received: from mail-wr1-f48.google.com (mail-wr1-f48.google.com [209.85.221.48]) (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 288723BBFAC for ; Tue, 15 Sep 2026 08:03:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.48 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789459421; cv=none; b=BokIXFwVB4/LJPLnN1HAUnSpSINl5lH26ch6uccXm4tnK815kWCRH99CaP7V2PQUQ40fZcKpo+DbGSXFGSG7Bv5AARJ2PSVp7G/uXOHNJaaEQuzKRNgPWhk4ymU53k+oL/wsCXWUPusYcpYOBhDF7WwQXVFJ1I0cQDNmmFBy4hU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789459421; c=relaxed/simple; bh=FiRsDZdzGXAipkwSasDiwYJgNjGQw/oWZmESPlkGMAY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=okdix+iXtZQPyA31MTIttyxMV29k7zDV9sn/RLrxXioEAThavmoqgOfp9F1cooLJ0QdpvSXxRqQX2ce24SAHXgrr+zo34R9x+pSPFloBEdzx774sR4bw1Fi443FpRcAQtoZyPmJ2CJ0etfyV0r9iwKGBwxFXia+Wf7TCDHxb0lY= 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=I+9tVjte; arc=none smtp.client-ip=209.85.221.48 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="I+9tVjte" Received: by mail-wr1-f48.google.com with SMTP id ffacd0b85a97d-48431648f33so325242f8f.0 for ; Tue, 15 Sep 2026 01:03:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1789459418; x=1790064218; 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=Lk08SIy6DJ+jXcktdOiUfMwYrHwPBwEtrnZT5485SRQ=; b=I+9tVjteYJoafgWpTthxC6aBqPi/jYqebjhFYx6ApmThzHTEdQeSPKuC6/H0MdD1ET 8jge1J31Vhao6XPidwrWw/PZSdNisyWuQZtuylu8HzTjoLmWd37ZXHAMRw2JtUqUTYKD fchU1cN5nAJvTt1H+RQfwT90OCF2U38+wbmK0qvnHoV3h8wqxb4aQujES8IGztyedjsN ZBNk8zvAxH1fvIxGRpOxfNLgU6318dS223SUql3ciodUGN/RhlbhJSZCPTOCa+Jx8XJv Yw/pINCHZQ6Af9tbGGxrvK9X3UKZnyteNcA7kEDRQ7lMaO4bgRFU4Yx0ajLthjHt+ScK 7KOg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1789459418; x=1790064218; 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=Lk08SIy6DJ+jXcktdOiUfMwYrHwPBwEtrnZT5485SRQ=; b=gOHR4/G+3nB49mt90JmMBcZQaIpisvnWfzcT8G2BAckPVsNe4sYWMV6nRIxVUMJm6W TVcZSWXCDY4s/yubUKulRFyjhzXxxhOmUiwB5QJyGbMNblazOjAw7etVORTxIXGx6grB JKlb4Sfq7fLvvMX70sXEKHLI+QaEXSGM0DoZvDnhKLwZ8xEeNzGZnPVDGR7eenRRNXFh CJXl1XffoM/8hM1BppjKrDWnHyxt8NeGNfoJt9zorD8xgwHhcVcKHtWMB0Vi18gnv9q1 eQcVgMiBdrRWI1KlgO52QK6pjxLxYPBglVe4VpNZcbg1JwrKVcSuAdntPB02MYisfW+P 6kXw== X-Forwarded-Encrypted: i=1; AKwUvBx33uprb6cQS2DuNH8wmF7Dw4AkTmSnKffP34cBS0srkuxqVSSTyEu0vTEq5TYk38WwGEE2K1sSZLH00JA=@vger.kernel.org X-Gm-Message-State: AFuF++mhmyPNsWBLRQtwnXbsv5BnknWV7Ck1TXi5qIQlZLsTPb9gnCXO K6aztSQAlbiaCWZrClzutJcT3zTu9RdUaiIC/RqqKit1ENhDUsTARjKB X-Gm-Gg: AYBFou27CWCAFqhMlcuyVVEQsxSRYplMELkUBhiFKQhNyUvFiCQwLOjS03B6mRIKlSn ASUUu88Otz3xZ9hZuJrpe3p5IyQZMCPSL5THgkbXWlxJ1tR6gdiyx8l3OTQVZWC2FgKZIJdidCL Sv0N6g/RS8Qc9IeK2hPvfBcW0DWziwWeqqVLL31A6phJWfJ07qofLWgm+ThXPKkDQHcjnqBK2rg UpH0bAxuU3ASdNLxop+aEdcayv6UeoHfTUQyioCMSQJDhtqG29gh3sxpDpNTsELUCOEks5HfYDf uhdHQC56KOWZLAzPdXsH/Cg4Y7xe0etwqp3OF9ksJzNns+x/9haYUNQlT5DdRCeOJyLXyvSTZHR aPw+dBN4ZIbF27wdsRBGWJnRM/HevOWKYOKH7nyFNlQggJ1MRk1I4ubQM8yYtomYdZp/w+8MYs6 I7iXH/DoHgvNkntGPEdbOOHGF/GUPHaaCD4cuqrneVzH4l+xUqmmtIwralwK8Ttj4ozgMUFD5Gz 73fExw77ophOX6MdLusTNw8MQ== X-Received: by 2002:a05:6000:2890:b0:486:fcf2:fdf7 with SMTP id ffacd0b85a97d-48705b90f4fmr4013554f8f.14.1789459417409; Tue, 15 Sep 2026 01:03:37 -0700 (PDT) Received: from dell-desktop ([2a02:587:4b4e:8500:290c:210b:1c76:5710]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-486eb35c071sm33764675f8f.33.2026.09.15.01.03.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 15 Sep 2026 01:03:36 -0700 (PDT) From: Anastasios Papagiannis To: bpf@vger.kernel.org Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org, david@kernel.org, akpm@linux-foundation.org, andrii@kernel.org, ast@kernel.org, brauner@kernel.org, daniel@iogearbox.net, eddyz87@gmail.com, kpsingh@kernel.org, ljs@kernel.org, matt@bobrowski.net, memxor@gmail.com, song@kernel.org, sun.jian.kdev@gmail.com, utilityemal77@gmail.com, viro@zeniv.linux.org.uk, tasos.papagiannnis@gmail.com Subject: [PATCH bpf-next v7 4/5] bpf: Mark linux_binprm->mm as trusted-or-null Date: Tue, 15 Sep 2026 11:02:54 +0300 Message-ID: <20260915080255.48929-5-tasos.papagiannnis@gmail.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260915080255.48929-1-tasos.papagiannnis@gmail.com> References: <20260915080255.48929-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 field is either NULL or points to a live mm_struct whenever BPF can access a linux_binprm. On successful exec, exec_mmap() installs the new address space before begin_new_exec() clears bprm->mm. The bprm_mm_init() error path clears the field before mmdrop(), and free_bprm() clears it before mmput(), as ensured by an earlier patch in this series. Update the existing LSM selftest to check bprm->mm for NULL before dereferencing it, as required for trusted-or-null pointers. Signed-off-by: Anastasios Papagiannis Reviewed-by: Sun Jian Reviewed-by: Matt Bobrowski --- 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 6c6b8d8520cd..3539a768b921 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -5997,6 +5997,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; }; @@ -6051,6 +6055,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 Fri Sep 25 07:56:45 2026 Received: from mail-wr2-f12.google.com (mail-wr2-f12.google.com [74.125.225.76]) (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 4D8003CEBBD for ; Tue, 15 Sep 2026 08:03:42 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.225.76 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789459424; cv=none; b=PjaZ46vNpqzaifY+IejYXI6YAJb9IR2aBDjhO7LFO5t+JyWYmOe2RbAJHgWy9Hca2d0tZa9w1ocyjGczc5AFEXGmodGZJfKJ4e4J0eGBxpsD8IwScR7zk9Vdhu10RW89sP5L+v/cN++6xxz74xIv8xLMrof+aL+XFN1wldH6Vn4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789459424; c=relaxed/simple; bh=xB2rAwluU7tS0l2mdEY9sK1jOotMoucM4DUYTDrHNek=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=aj4fIKhA6ZcK/XYnxpWEuOnR9xEE2XQrq+N0+3/0RQbi6SHvGqHU7/VvCwvTsKMRXU2EDDlhemh/D1k+CMu9B0rEB7P782H1XV8XFeu+WoVbAOuHxwgnWdVHzhWQOW1MPOUY8p/jqzvMAOCAeM0Sbx5wCsN32dMMH3h1yB9bEPI= 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=Z3pJBLmu; arc=none smtp.client-ip=74.125.225.76 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="Z3pJBLmu" Received: by mail-wr2-f12.google.com with SMTP id ffacd0b85a97d-485984ebf5cso2289417f8f.0 for ; Tue, 15 Sep 2026 01:03:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1789459420; x=1790064220; 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=JMfo0lOkU7nY+kpMSBVMONrY7JpNJm89ZLpxpQTDFY8=; b=Z3pJBLmu12QY1ysKUlG7VxUXFpj2RrliLNaF30kHzuwC3vsG/hPcONSouwMvlI8dbF G2MYw//rQbOpgWeEFjo4ADxIkxFKn5cwUZvypja3yuNjP9RCdBSwTaPf73IrtlfI2+ul mHgEjyoguhGwmhPtjkk52Jc+kjZwkGNj3FW1Ej8B2B2lVQ8U54hoiM5D8YtYpFXIXDy5 CUm1UbD7LCVExoTu+eiM943oK0loh+lg6iNpMncmUtvZ0ff6zYF2jOiDEwizEce/GzWa l3DYyyqo5Fi+Wp/Nao04X58v/rOuWjWUF8GTaKMps8TW5mE8gjJeE9RWn4ZzrdJI4iD7 Nqzw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1789459420; x=1790064220; 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=JMfo0lOkU7nY+kpMSBVMONrY7JpNJm89ZLpxpQTDFY8=; b=UPIUTUpZhjejKuLwmKm/fO7yotYKjdc3Dx4kNSCw7OXVRqpzQhiCnVAoJkL4O8eWD+ tdjdkVZ1qQGofxGpP65Rjnx0U2SvVbXAU1thp+ed/GAh58k/sdyIy0zOUjifTqSWnd4l tTPT+uG43M2+H89DRqxW+nHs3T1B5nij4fvEKjWAPUwcehZC9YGPWqIhmJkRn04/G2XC J0tiP9bbRJAEHXNLqRPdWOtzk1z/+PhkWBp30yZ8k3SrXvNV+qpbRVuKBIzKvQKn0vzA 39fA7slq44aiFvqYC+pfi6f96T3dagsWof0Mt41XjSNTzmbbFIMNeG4taX4mqOFd820d JfyA== X-Forwarded-Encrypted: i=1; AKwUvBx/k7XrC1wPOAQ7bo/S/HPzA7Jy4QpqKko9pa8CPmZcReeDuJZmRpmB0Ru6cbdg8lG50WPey2lc+Jf0C0M=@vger.kernel.org X-Gm-Message-State: AFuF++m8wsPn9dhZby3EcXdSlbY9qk8KcCJBIyo9PZuiztN3H1cvldGg TJv/DJ9eGq9R/N31Ld4rv6wFkG3j1BiPJiE+J3y9kbw2gHJK5dzM3wj1 X-Gm-Gg: AYBFou3D9P+NiUODkII7WIgHx0m4VVs8/PX4LxlY3sphLzZsxRGfdVu8tH1ZQTdTNpL kyvKUpkbiSywDkx0Hc1m6CUHDrjBMixuo2+Gsn9IjC0kk1no9IGW8cZBOwkNRfuFKfVmSna9LeA HXlVmLm5LddcV89r9cye/hXVqCMl/xDhgK92LP4Xa45HcSbDmFmVF2sEfcKz4w9hffzYraQYTMZ tJSz27zCGqwdSS+UfgmJuLnU+IL4L6l9iyr0/SyFDe2Wzp6LJRCeJhNLRJMcHXR9PhZUrqvgAUY yFX020SAZngaXAGHfGZ5RM78Q/nY4H/kOR4tohp4FTFwxXTzVaxqD//u/714o3cxRxSFc3ycotR UD0/Xx0YLH9W4ZZlAcU3r6gLQ3zLcqezwQntaEWoTfGgKDhQnh6ACA+o82uurHSHfIAPXqnYxiM fzRQz1G4+eqgGAsJXOty3489k2vIwpLdC4QL9MxumHR/kT1S2XdutGdq5H23fqIt1twlvDlyWii qhhq1bNVaINV7od X-Received: by 2002:a05:6000:381:b0:487:40d:af2a with SMTP id ffacd0b85a97d-487040db0f5mr6181796f8f.4.1789459420380; Tue, 15 Sep 2026 01:03:40 -0700 (PDT) Received: from dell-desktop ([2a02:587:4b4e:8500:290c:210b:1c76:5710]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-486eb35c071sm33764675f8f.33.2026.09.15.01.03.38 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 15 Sep 2026 01:03:39 -0700 (PDT) From: Anastasios Papagiannis To: bpf@vger.kernel.org Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org, david@kernel.org, akpm@linux-foundation.org, andrii@kernel.org, ast@kernel.org, brauner@kernel.org, daniel@iogearbox.net, eddyz87@gmail.com, kpsingh@kernel.org, ljs@kernel.org, matt@bobrowski.net, memxor@gmail.com, song@kernel.org, sun.jian.kdev@gmail.com, utilityemal77@gmail.com, viro@zeniv.linux.org.uk, tasos.papagiannnis@gmail.com Subject: [PATCH bpf-next v7 5/5] selftests/bpf: Test mm_struct user memory kfuncs with linux_binprm Date: Tue, 15 Sep 2026 11:02:55 +0300 Message-ID: <20260915080255.48929-6-tasos.papagiannnis@gmail.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260915080255.48929-1-tasos.papagiannnis@gmail.com> References: <20260915080255.48929-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() on CONFIG_MMU kernels. Starting at bprm->p, verify that bpf_copy_from_user_mm() can copy the contiguous NUL-separated argument and environment data. Then use bpf_copy_from_user_mm_str() to read each argument and environment string separately, advancing the offset by the length returned from each call. Skip the test on !CONFIG_MMU. In that configuration, exec argument and environment strings remain in bprm->page[] until the binary loader transfers them to the new process stack, so they are not accessible through bprm->mm at the bprm_check_security hook. Signed-off-by: Anastasios Papagiannis --- .../bpf/prog_tests/copy_from_user_bprm.c | 72 +++++++++++ .../selftests/bpf/progs/copy_from_user_bprm.c | 122 ++++++++++++++++++ 2 files changed, 194 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..ef351cda9348 --- /dev/null +++ b/tools/testing/selftests/bpf/prog_tests/copy_from_user_bprm.c @@ -0,0 +1,72 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include +#include +#include + +#include + +#include "copy_from_user_bprm.skel.h" + +void test_copy_from_user_bprm(void) +{ + char arg0[] =3D "first"; + char arg1[] =3D "second-argument"; + char env0[] =3D "SOME_ENV=3Da"; + char env1[] =3D "OTHER_ENV=3Dsomething"; + 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; + + /* + * On !CONFIG_MMU, exec strings are held in bprm->page[] rather than + * being mapped in bprm->mm. + */ + if (!skel->kconfig->CONFIG_MMU) { + printf("%s:SKIP: test requires CONFIG_MMU\n", __func__); + test__skip(); + goto out; + } + + 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 { arg0, arg1, NULL }; + char *const envp[] =3D { env0, env1, NULL }; + + skel->bss->monitored_pid =3D getpid(); + execvpe("true", argv, envp); + _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->bprm_envc, 2, "bprm_envc"); + ASSERT_EQ(skel->bss->data_len_match, 1, "data_len_match"); + 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, sizeof(arg0), "str_arg0_ret"); + ASSERT_EQ(skel->bss->str_arg1_ret, sizeof(arg1), "str_arg1_ret"); + ASSERT_EQ(skel->bss->str_env0_ret, sizeof(env0), "str_env0_ret"); + ASSERT_EQ(skel->bss->str_env1_ret, sizeof(env1), "str_env1_ret"); + ASSERT_EQ(skel->bss->data_match, 1, "data_match"); + ASSERT_EQ(skel->bss->str_args_match, 1, "str_args_match"); + ASSERT_EQ(skel->bss->str_envs_match, 1, "str_envs_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..07ca96d9db45 --- /dev/null +++ b/tools/testing/selftests/bpf/progs/copy_from_user_bprm.c @@ -0,0 +1,122 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include "vmlinux.h" + +#include +#include +#include + +char _license[] SEC("license") =3D "GPL"; + +static const char expected_data[] =3D "first\0second-argument\0" + "SOME_ENV=3Da\0OTHER_ENV=3Dsomething"; +static const char expected_arg0[] =3D "first"; +static const char expected_arg1[] =3D "second-argument"; +static const char expected_env0[] =3D "SOME_ENV=3Da"; +static const char expected_env1[] =3D "OTHER_ENV=3Dsomething"; + +int monitored_pid; +int bprm_argc; +int bprm_envc; +int data_len_match; +int invalid_flags_ret; +int copy_ret; +int str_arg0_ret; +int str_arg1_ret; +int str_env0_ret; +int str_env1_ret; +int data_match; +int str_args_match; +int str_envs_match; + +extern bool CONFIG_MMU __kconfig __weak; + +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) +{ + u32 pid =3D bpf_get_current_pid_tgid() >> 32; + char data[sizeof(expected_data)] =3D {}; + struct mm_struct *mm; + char arg0[32] =3D {}; + char arg1[32] =3D {}; + char env0[32] =3D {}; + char env1[32] =3D {}; + u64 offset =3D 0; + u64 data_len; + + if (!CONFIG_MMU) + return 0; + + if (pid !=3D monitored_pid) + return 0; + + mm =3D bprm->mm; + if (!mm) + return 0; + + bprm_argc =3D bprm->argc; + bprm_envc =3D bprm->envc; + + /* this is the total size of args and envs starting from bprm->p */ + data_len =3D bprm->exec - bprm->p; + data_len_match =3D data_len =3D=3D sizeof(expected_data); + + invalid_flags_ret =3D bpf_copy_from_user_mm(data, sizeof(data), + (void *)bprm->p, mm, ~0ULL); + + copy_ret =3D bpf_copy_from_user_mm(data, sizeof(data), (void *)bprm->p, + mm, 0); + if (copy_ret) + return 0; + + data_match =3D + !__builtin_memcmp(data, expected_data, sizeof(expected_data)); + + /* arg0 is at bprm->p */ + str_arg0_ret =3D bpf_copy_from_user_mm_str(arg0, sizeof(arg0), + (void *)(bprm->p + offset), + mm, BPF_F_PAD_ZEROS); + if (str_arg0_ret !=3D sizeof(expected_arg0)) + return 0; + offset +=3D str_arg0_ret; + + /* arg1 is at bprm->p + sizeof(arg0) */ + str_arg1_ret =3D bpf_copy_from_user_mm_str(arg1, sizeof(arg1), + (void *)(bprm->p + offset), + mm, BPF_F_PAD_ZEROS); + if (str_arg1_ret !=3D sizeof(expected_arg1)) + return 0; + offset +=3D str_arg1_ret; + + /* env0 is at bprm->p + sizeof(arg0) + sizeof(arg1) */ + str_env0_ret =3D bpf_copy_from_user_mm_str(env0, sizeof(env0), + (void *)(bprm->p + offset), + mm, BPF_F_PAD_ZEROS); + if (str_env0_ret !=3D sizeof(expected_env0)) + return 0; + offset +=3D str_env0_ret; + + /* env1 is at bprm->p + sizeof(arg0) + sizeof(arg1) + sizeof(env0) */ + str_env1_ret =3D bpf_copy_from_user_mm_str(env1, sizeof(env1), + (void *)(bprm->p + offset), + mm, BPF_F_PAD_ZEROS); + if (str_env1_ret !=3D sizeof(expected_env1)) + return 0; + + str_args_match =3D + !__builtin_memcmp(arg0, expected_arg0, sizeof(expected_arg0)) && + !__builtin_memcmp(arg1, expected_arg1, sizeof(expected_arg1)); + str_envs_match =3D + !__builtin_memcmp(env0, expected_env0, sizeof(expected_env0)) && + !__builtin_memcmp(env1, expected_env1, sizeof(expected_env1)); + + return data_match && str_args_match && str_envs_match ? -EPERM : 0; +} --=20 2.55.0