Skip to content

Commit c832183

Browse files
committed
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
2 parents 777f817 + d7ba853 commit c832183

5 files changed

Lines changed: 47 additions & 4 deletions

File tree

Documentation/admin-guide/LSM/ipe.rst

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,20 @@ languages when these scripts are invoked by passing these program files
9595
to the interpreter. This is because the way interpreters execute these
9696
files; the scripts themselves are not evaluated as executable code
9797
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.
99112

100113
Threat Model
101114
------------
@@ -806,8 +819,6 @@ A:
806819

807820
.. [#digest_cache_lsm] https://lore.kernel.org/lkml/20240415142436.2545003-1-roberto.sassu@huaweicloud.com/
808821
809-
.. [#interpreters] There is `some interest in solving this issue <https://lore.kernel.org/lkml/20220321161557.495388-1-mic@digikod.net/>`_.
810-
811822
.. [#devdoc] Please see :doc:`the design docs </security/ipe>` for more on
812823
this topic.
813824

security/ipe/audit.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ static const char *const audit_op_names[__IPE_OP_MAX + 1] = {
4646

4747
static const char *const audit_hook_names[__IPE_HOOK_MAX] = {
4848
"BPRM_CHECK",
49+
"BPRM_CREDS_FOR_EXEC",
4950
"MMAP",
5051
"MPROTECT",
5152
"KERNEL_READ",

security/ipe/hooks.c

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,33 @@ int ipe_bprm_check_security(struct linux_binprm *bprm)
3535
return ipe_evaluate_event(&ctx);
3636
}
3737

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+
3865
/**
3966
* ipe_mmap_file() - ipe security hook function for mmap check.
4067
* @f: File being mmap'd. Can be NULL in the case of anonymous memory.
@@ -312,4 +339,4 @@ int ipe_inode_setintegrity(const struct inode *inode,
312339

313340
return -EINVAL;
314341
}
315-
#endif /* CONFIG_CONFIG_IPE_PROP_FS_VERITY_BUILTIN_SIG */
342+
#endif /* CONFIG_IPE_PROP_FS_VERITY_BUILTIN_SIG */

security/ipe/hooks.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
enum ipe_hook_type {
1515
IPE_HOOK_BPRM_CHECK = 0,
16+
IPE_HOOK_BPRM_CREDS_FOR_EXEC,
1617
IPE_HOOK_MMAP,
1718
IPE_HOOK_MPROTECT,
1819
IPE_HOOK_KERNEL_READ,
@@ -24,6 +25,8 @@ enum ipe_hook_type {
2425

2526
int ipe_bprm_check_security(struct linux_binprm *bprm);
2627

28+
int ipe_bprm_creds_for_exec(struct linux_binprm *bprm);
29+
2730
int ipe_mmap_file(struct file *f, unsigned long reqprot, unsigned long prot,
2831
unsigned long flags);
2932

security/ipe/ipe.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ struct ipe_inode *ipe_inode(const struct inode *inode)
4747

4848
static struct security_hook_list ipe_hooks[] __ro_after_init = {
4949
LSM_HOOK_INIT(bprm_check_security, ipe_bprm_check_security),
50+
LSM_HOOK_INIT(bprm_creds_for_exec, ipe_bprm_creds_for_exec),
5051
LSM_HOOK_INIT(mmap_file, ipe_mmap_file),
5152
LSM_HOOK_INIT(file_mprotect, ipe_file_mprotect),
5253
LSM_HOOK_INIT(kernel_read_file, ipe_kernel_read_file),

0 commit comments

Comments
 (0)