[PATCH bpf-next v8 0/5] bpf: Add user memory access kfuncs for mm_struct
Anastasios Papagiannis <[email protected]>
| Newsgroups | org.kernel.vger.linux-fsdevel,org.kernel.vger.bpf,org.kernel.vger.linux-kernel,org.kvack.linux-mm |
|---|---|
| Message-ID | <[email protected]> |
On MMU systems, during exec, argument and environment strings are copied into the new address space held by struct linux_binprm before that address space is installed on the task_struct. Existing BPF user memory helpers operate on the current address space or one associated with a task_struct. Because no task_struct refers to the new address space at this point, programs cannot access these strings from the bprm_check_security LSM hook. This series adds two sleepable BPF kfuncs for copying bytes or NUL-terminated strings from a trusted struct mm_struct. It also marks linux_binprm->mm as trusted-or-null, allowing BPF LSM programs to pass it to the kfuncs after a NULL check and inspect exec arguments before allowing the exec to continue. To make the trusted-or-null annotation safe, the exec paths are hardened to clear bprm->mm before dropping the reference it owns. On NOMMU systems, exec argument and environment strings remain in bprm->page[] until they are transferred to the new process stack. They cannot be accessed through bprm->mm at the bprm_check_security hook. The new kfuncs remain available on NOMMU for address ranges represented by a supplied struct mm_struct. The series adds selftests covering both kfuncs while reading argument and environment strings from linux_binprm during exec. Changes in v8: - Removed CONFIG_BPF_SYSCALL #ifdefs from mm/memory.c and mm/nommu.c. - Reformatted the selftest to use 120-character lines. - Removed the CONFIG_MMU check from the selftests. - Removed the extern declarations from the selftests, as they already exist in vmlinux.h. - Moved the checks to user space in the selftests. Changes in v7: - Use execvpe() instead of a hardcoded /bin/true path in the copy_from_user_bprm selftest while retaining the controlled environment. - Remove the unused bpf_misc.h include. - Rewrap the invalid-flags kfunc call to stay within 80 columns. - Fix indent in mm patches. Changes in v6: - Drop redundant extern keywords and CONFIG_BPF_SYSCALL guards from the remote memory copy declarations. - Drop the explicit bpf_copy_from_user_mm() prototype and share copy logic through inlineable static internal helpers instead of calling between kfunc/helper entry points. - Validate flags and zero-length requests before acquiring the task's mm, preserving existing behavior and ensuring internal helpers are called only with a live mm. - Drop the verifier relaxation for unchecked reads through trusted-or-null pointers and its tests. - Fix the existing LSM selftest to explicitly NULL-check bprm->mm after marking the field trusted-or-null. Changes in v5: - Move the shared wrappers to mm/util.c and handle zero-length requests at the entry points. Changes in v4: - Add negative verifier tests for atomic RMW and load-acquire accesses through trusted-or-null BTF pointers. - Preserve explicit nullability-marking coverage for tracepoint arguments, dentry->d_inode, and sched_ext .dispatch. - Use the already-nullable mmap_file argument for the negative store test, avoiding dependency on the later linux_binprm->mm marking. - Clarify the bprm->mm lifetime invariant and move its lifetime fix before the mm_struct kfunc patch. - Reword the trusted-or-null read change in imperative mood and remove its redundant before-and-after summary. - Document that the existing task-based user-memory interfaces delegate to the new mm-based implementations, reorder the string-copy kfuncs to remove an unnecessary declaration, and annotate the remaining declaration with __bpf_kfunc. Changes in v3: - Replace the linux_binprm-specific kfuncs with generic struct mm_struct kfuncs, as suggested by Andrii Nakryiko. - Move the kfuncs next to the existing user memory helpers and make the task-based variants delegate to the new mm-based implementations, as suggested by Andrii Nakryiko. - Clear bprm->mm before dropping its reference on exec error paths. - Mark linux_binprm->mm as trusted-or-null. - Allow fault-protected reads through trusted-or-null BTF pointers to preserve compatibility with existing BPF programs, as suggested by Andrii Nakryiko. - Add verifier and runtime selftests for trusted-or-null BTF pointer reads. - Rename __copy_remote_vm_str() to __copy_remote_mm_str(), as suggested by Andrii Nakryiko. - Clarify that reading exec strings through bprm->mm is limited to MMU systems, while the generic mm-based kfuncs remain available on NOMMU. Changes in v2: - Register the kfuncs on NOMMU systems and return -EOPNOTSUPP when called, as suggested by Justin Suess. - Add selftest coverage for reading environment strings, as suggested by Justin Suess. - Clarify that copy_remote_mm_str() leaves the destination untouched when called with a zero-length buffer. - Use sizeof() instead of hardcoded argument lengths in the selftests. - Use ~0ULL for invalid-flags checks in the selftests. v7: https://lore.kernel.org/bpf/[email protected]/ v6: https://lore.kernel.org/all/[email protected]/ v5: https://lore.kernel.org/bpf/[email protected]/ v4: https://lore.kernel.org/bpf/[email protected]/ v3: https://lore.kernel.org/bpf/[email protected]/ v2: https://lore.kernel.org/bpf/[email protected]/ v1: https://lore.kernel.org/bpf/[email protected]/ Anastasios Papagiannis (5): mm: Add copy_remote_mm_str() exec: Clear bprm->mm before dropping its reference bpf: Add user memory access kfuncs for mm_struct bpf: Mark linux_binprm->mm as trusted-or-null selftests/bpf: Test mm_struct user memory kfuncs with linux_binprm fs/exec.c | 7 +- include/linux/mm.h | 8 +- kernel/bpf/helpers.c | 130 ++++++++++++++++-- kernel/bpf/verifier.c | 5 + mm/internal.h | 3 + mm/memory.c | 43 +----- mm/nommu.c | 43 +----- mm/util.c | 62 +++++++++ .../bpf/prog_tests/copy_from_user_bprm.c | 65 +++++++++ .../selftests/bpf/progs/copy_from_user_bprm.c | 69 ++++++++++ tools/testing/selftests/bpf/progs/lsm.c | 5 +- 11 files changed, 339 insertions(+), 101 deletions(-) create mode 100644 tools/testing/selftests/bpf/prog_tests/copy_from_user_bprm.c create mode 100644 tools/testing/selftests/bpf/progs/copy_from_user_bprm.c base-commit: 961b8946acb482b6d7a39c266d623e5f9c4e873f -- 2.55.0