1.. SPDX-License-Identifier: GPL-2.0 2.. Copyright © 2024 Microsoft Corporation 3 4=================== 5Executability check 6=================== 7 8The ``AT_EXECVE_CHECK`` :manpage:`execveat(2)` flag, and the 9``SECBIT_EXEC_RESTRICT_FILE`` and ``SECBIT_EXEC_DENY_INTERACTIVE`` securebits 10are intended for script interpreters and dynamic linkers to enforce a 11consistent execution security policy handled by the kernel. See the 12`samples/check-exec/inc.c`_ example. 13 14Whether an interpreter should check these securebits or not depends on the 15security risk of running malicious scripts with respect to the execution 16environment, and whether the kernel can check if a script is trustworthy or 17not. For instance, Python scripts running on a server can use arbitrary 18syscalls and access arbitrary files. Such interpreters should then be 19enlighten to use these securebits and let users define their security policy. 20However, a JavaScript engine running in a web browser should already be 21sandboxed and then should not be able to harm the user's environment. 22 23Script interpreters or dynamic linkers built for tailored execution environments 24(e.g. hardened Linux distributions or hermetic container images) could use 25``AT_EXECVE_CHECK`` without checking the related securebits if backward 26compatibility is handled by something else (e.g. atomic update ensuring that 27all legitimate libraries are allowed to be executed). It is then recommended 28for script interpreters and dynamic linkers to check the securebits at run time 29by default, but also to provide the ability for custom builds to behave like if 30``SECBIT_EXEC_RESTRICT_FILE`` or ``SECBIT_EXEC_DENY_INTERACTIVE`` were always 31set to 1 (i.e. always enforce restrictions). 32 33AT_EXECVE_CHECK 34=============== 35 36Passing the ``AT_EXECVE_CHECK`` flag to :manpage:`execveat(2)` only performs a 37check on a regular file and returns 0 if execution of this file would be 38allowed, ignoring the file format and then the related interpreter dependencies 39(e.g. ELF libraries, script's shebang). 40 41Programs should always perform this check to apply kernel-level checks against 42files that are not directly executed by the kernel but passed to a user space 43interpreter instead. All files that contain executable code, from the point of 44view of the interpreter, should be checked. However the result of this check 45should only be enforced according to ``SECBIT_EXEC_RESTRICT_FILE`` or 46``SECBIT_EXEC_DENY_INTERACTIVE.``. 47 48The main purpose of this flag is to improve the security and consistency of an 49execution environment to ensure that direct file execution (e.g. 50``./script.sh``) and indirect file execution (e.g. ``sh script.sh``) lead to 51the same result. For instance, this can be used to check if a file is 52trustworthy according to the caller's environment. 53 54In a secure environment, libraries and any executable dependencies should also 55be checked. For instance, dynamic linking should make sure that all libraries 56are allowed for execution to avoid trivial bypass (e.g. using ``LD_PRELOAD``). 57For such secure execution environment to make sense, only trusted code should 58be executable, which also requires integrity guarantees. 59 60To avoid race conditions leading to time-of-check to time-of-use issues, 61``AT_EXECVE_CHECK`` should be used with ``AT_EMPTY_PATH`` to check against a 62file descriptor instead of a path. 63 64SECBIT_EXEC_RESTRICT_FILE and SECBIT_EXEC_DENY_INTERACTIVE 65========================================================== 66 67When ``SECBIT_EXEC_RESTRICT_FILE`` is set, a process should only interpret or 68execute a file if a call to :manpage:`execveat(2)` with the related file 69descriptor and the ``AT_EXECVE_CHECK`` flag succeed. 70 71This secure bit may be set by user session managers, service managers, 72container runtimes, sandboxer tools... Except for test environments, the 73related ``SECBIT_EXEC_RESTRICT_FILE_LOCKED`` bit should also be set. 74 75Programs should only enforce consistent restrictions according to the 76securebits but without relying on any other user-controlled configuration. 77Indeed, the use case for these securebits is to only trust executable code 78vetted by the system configuration (through the kernel), so we should be 79careful to not let untrusted users control this configuration. 80 81However, script interpreters may still use user configuration such as 82environment variables as long as it is not a way to disable the securebits 83checks. For instance, the ``PATH`` and ``LD_PRELOAD`` variables can be set by 84a script's caller. Changing these variables may lead to unintended code 85executions, but only from vetted executable programs, which is OK. For this to 86make sense, the system should provide a consistent security policy to avoid 87arbitrary code execution e.g., by enforcing a write xor execute policy. 88 89When ``SECBIT_EXEC_DENY_INTERACTIVE`` is set, a process should never interpret 90interactive user commands (e.g. scripts). However, if such commands are passed 91through a file descriptor (e.g. stdin), its content should be interpreted if a 92call to :manpage:`execveat(2)` with the related file descriptor and the 93``AT_EXECVE_CHECK`` flag succeed. 94 95For instance, script interpreters called with a script snippet as argument 96should always deny such execution if ``SECBIT_EXEC_DENY_INTERACTIVE`` is set. 97 98This secure bit may be set by user session managers, service managers, 99container runtimes, sandboxer tools... Except for test environments, the 100related ``SECBIT_EXEC_DENY_INTERACTIVE_LOCKED`` bit should also be set. 101 102Here is the expected behavior for a script interpreter according to combination 103of any exec securebits: 104 1051. ``SECBIT_EXEC_RESTRICT_FILE=0`` and ``SECBIT_EXEC_DENY_INTERACTIVE=0`` 106 107 Always interpret scripts, and allow arbitrary user commands (default). 108 109 No threat, everyone and everything is trusted, but we can get ahead of 110 potential issues thanks to the call to :manpage:`execveat(2)` with 111 ``AT_EXECVE_CHECK`` which should always be performed but ignored by the 112 script interpreter. Indeed, this check is still important to enable systems 113 administrators to verify requests (e.g. with audit) and prepare for 114 migration to a secure mode. 115 1162. ``SECBIT_EXEC_RESTRICT_FILE=1`` and ``SECBIT_EXEC_DENY_INTERACTIVE=0`` 117 118 Deny script interpretation if they are not executable, but allow 119 arbitrary user commands. 120 121 The threat is (potential) malicious scripts run by trusted (and not fooled) 122 users. That can protect against unintended script executions (e.g. ``sh 123 /tmp/*.sh``). This makes sense for (semi-restricted) user sessions. 124 1253. ``SECBIT_EXEC_RESTRICT_FILE=0`` and ``SECBIT_EXEC_DENY_INTERACTIVE=1`` 126 127 Always interpret scripts, but deny arbitrary user commands. 128 129 This use case may be useful for secure services (i.e. without interactive 130 user session) where scripts' integrity is verified (e.g. with IMA/EVM or 131 dm-verity/IPE) but where access rights might not be ready yet. Indeed, 132 arbitrary interactive commands would be much more difficult to check. 133 1344. ``SECBIT_EXEC_RESTRICT_FILE=1`` and ``SECBIT_EXEC_DENY_INTERACTIVE=1`` 135 136 Deny script interpretation if they are not executable, and also deny 137 any arbitrary user commands. 138 139 The threat is malicious scripts run by untrusted users (but trusted code). 140 This makes sense for system services that may only execute trusted scripts. 141 142.. Links 143.. _samples/check-exec/inc.c: 144 https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/samples/check-exec/inc.c 145