Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'ipe-pr-20251202' of git://git.kernel.org/pub/scm/linux/kernel/git/wufan/ipe

Pull IPE udates from Fan Wu:
"The primary change is the addition of support for the AT_EXECVE_CHECK
flag. This allows interpreters to signal the kernel to perform IPE
security checks on script files before execution, extending IPE
enforcement to indirectly executed scripts.

Update documentation for it, and also fix a comment"

* tag 'ipe-pr-20251202' of git://git.kernel.org/pub/scm/linux/kernel/git/wufan/ipe:
ipe: Update documentation for script enforcement
ipe: Add AT_EXECVE_CHECK support for script enforcement
ipe: Drop a duplicated CONFIG_ prefix in the ifdeffery

+47 -4
+14 -3
Documentation/admin-guide/LSM/ipe.rst
··· 95 95 to the interpreter. This is because the way interpreters execute these 96 96 files; the scripts themselves are not evaluated as executable code 97 97 through one of IPE's hooks, but they are merely text files that are read 98 - (as opposed to compiled executables) [#interpreters]_. 98 + (as opposed to compiled executables). However, with the introduction of the 99 + ``AT_EXECVE_CHECK`` flag (:doc:`AT_EXECVE_CHECK </userspace-api/check_exec>`), 100 + interpreters can use it to signal the kernel that a script file will be executed, 101 + and request the kernel to perform LSM security checks on it. 102 + 103 + IPE's EXECUTE operation enforcement differs between compiled executables and 104 + interpreted scripts: For compiled executables, enforcement is triggered 105 + automatically by the kernel during ``execve()``, ``execveat()``, ``mmap()`` 106 + and ``mprotect()`` syscalls when loading executable content. For interpreted 107 + scripts, enforcement requires explicit interpreter integration using 108 + ``execveat()`` with ``AT_EXECVE_CHECK`` flag. Unlike exec syscalls that IPE 109 + intercepts during the execution process, this mechanism needs the interpreter 110 + to take the initiative, and existing interpreters won't be automatically 111 + supported unless the signal call is added. 99 112 100 113 Threat Model 101 114 ------------ ··· 818 805 ----------- 819 806 820 807 .. [#digest_cache_lsm] https://lore.kernel.org/lkml/20240415142436.2545003-1-roberto.sassu@huaweicloud.com/ 821 - 822 - .. [#interpreters] There is `some interest in solving this issue <https://lore.kernel.org/lkml/20220321161557.495388-1-mic@digikod.net/>`_. 823 808 824 809 .. [#devdoc] Please see :doc:`the design docs </security/ipe>` for more on 825 810 this topic.
+1
security/ipe/audit.c
··· 46 46 47 47 static const char *const audit_hook_names[__IPE_HOOK_MAX] = { 48 48 "BPRM_CHECK", 49 + "BPRM_CREDS_FOR_EXEC", 49 50 "MMAP", 50 51 "MPROTECT", 51 52 "KERNEL_READ",
+28 -1
security/ipe/hooks.c
··· 36 36 } 37 37 38 38 /** 39 + * ipe_bprm_creds_for_exec() - ipe security hook function for bprm creds check. 40 + * @bprm: Supplies a pointer to a linux_binprm structure to source the file 41 + * being evaluated. 42 + * 43 + * This LSM hook is called when userspace signals the kernel to check a file 44 + * for execution through the execveat syscall with the AT_EXECVE_CHECK flag. 45 + * The hook triggers IPE policy evaluation on the script file and returns 46 + * the policy decision to userspace. The userspace program receives the 47 + * return code and can decide whether to proceed with script execution. 48 + * 49 + * Return: 50 + * * %0 - Success 51 + * * %-EACCES - Did not pass IPE policy 52 + */ 53 + int ipe_bprm_creds_for_exec(struct linux_binprm *bprm) 54 + { 55 + struct ipe_eval_ctx ctx = IPE_EVAL_CTX_INIT; 56 + 57 + if (!bprm->is_check) 58 + return 0; 59 + 60 + ipe_build_eval_ctx(&ctx, bprm->file, IPE_OP_EXEC, 61 + IPE_HOOK_BPRM_CREDS_FOR_EXEC); 62 + return ipe_evaluate_event(&ctx); 63 + } 64 + 65 + /** 39 66 * ipe_mmap_file() - ipe security hook function for mmap check. 40 67 * @f: File being mmap'd. Can be NULL in the case of anonymous memory. 41 68 * @reqprot: The requested protection on the mmap, passed from usermode. ··· 339 312 340 313 return -EINVAL; 341 314 } 342 - #endif /* CONFIG_CONFIG_IPE_PROP_FS_VERITY_BUILTIN_SIG */ 315 + #endif /* CONFIG_IPE_PROP_FS_VERITY_BUILTIN_SIG */
+3
security/ipe/hooks.h
··· 13 13 14 14 enum ipe_hook_type { 15 15 IPE_HOOK_BPRM_CHECK = 0, 16 + IPE_HOOK_BPRM_CREDS_FOR_EXEC, 16 17 IPE_HOOK_MMAP, 17 18 IPE_HOOK_MPROTECT, 18 19 IPE_HOOK_KERNEL_READ, ··· 24 23 #define IPE_HOOK_INVALID __IPE_HOOK_MAX 25 24 26 25 int ipe_bprm_check_security(struct linux_binprm *bprm); 26 + 27 + int ipe_bprm_creds_for_exec(struct linux_binprm *bprm); 27 28 28 29 int ipe_mmap_file(struct file *f, unsigned long reqprot, unsigned long prot, 29 30 unsigned long flags);
+1
security/ipe/ipe.c
··· 47 47 48 48 static struct security_hook_list ipe_hooks[] __ro_after_init = { 49 49 LSM_HOOK_INIT(bprm_check_security, ipe_bprm_check_security), 50 + LSM_HOOK_INIT(bprm_creds_for_exec, ipe_bprm_creds_for_exec), 50 51 LSM_HOOK_INIT(mmap_file, ipe_mmap_file), 51 52 LSM_HOOK_INIT(file_mprotect, ipe_file_mprotect), 52 53 LSM_HOOK_INIT(kernel_read_file, ipe_kernel_read_file),