| 1 | |
| 2 | |
| 3 |
|
| 4 | ===================
|
| 5 | Executability check
|
| 6 | ===================
|
| 7 |
|
| 8 | The ``AT_EXECVE_CHECK`` :manpage:`execveat(2)` flag, and the
|
| 9 | ``SECBIT_EXEC_RESTRICT_FILE`` and ``SECBIT_EXEC_DENY_INTERACTIVE`` securebits
|
| 10 | are intended for script interpreters and dynamic linkers to enforce a
|
| 11 | consistent execution security policy handled by the kernel. See the
|
| 12 | `samples/check-exec/inc.c`_ example.
|
| 13 |
|
| 14 | Whether an interpreter should check these securebits or not depends on the
|
| 15 | security risk of running malicious scripts with respect to the execution
|
| 16 | environment, and whether the kernel can check if a script is trustworthy or
|
| 17 | not. For instance, Python scripts running on a server can use arbitrary
|
| 18 | syscalls and access arbitrary files. Such interpreters should then be
|
| 19 | enlighten to use these securebits and let users define their security policy.
|
| 20 | However, a JavaScript engine running in a web browser should already be
|
| 21 | sandboxed and then should not be able to harm the user's environment.
|
| 22 |
|
| 23 | Script 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
|
| 26 | compatibility is handled by something else (e.g. atomic update ensuring that
|
| 27 | all legitimate libraries are allowed to be executed). It is then recommended
|
| 28 | for script interpreters and dynamic linkers to check the securebits at run time
|
| 29 | by 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
|
| 31 | set to 1 (i.e. always enforce restrictions).
|
| 32 |
|
| 33 | AT_EXECVE_CHECK
|
| 34 | ===============
|
| 35 |
|
| 36 | Passing the ``AT_EXECVE_CHECK`` flag to :manpage:`execveat(2)` only performs a
|
| 37 | check on a regular file and returns 0 if execution of this file would be
|
| 38 | allowed, ignoring the file format and then the related interpreter dependencies
|
| 39 | (e.g. ELF libraries, script's shebang).
|
| 40 |
|
| 41 | Programs should always perform this check to apply kernel-level checks against
|
| 42 | files that are not directly executed by the kernel but passed to a user space
|
| 43 | interpreter instead. All files that contain executable code, from the point of
|
| 44 | view of the interpreter, should be checked. However the result of this check
|
| 45 | should only be enforced according to ``SECBIT_EXEC_RESTRICT_FILE`` or
|
| 46 | ``SECBIT_EXEC_DENY_INTERACTIVE.``.
|
| 47 |
|
| 48 | The main purpose of this flag is to improve the security and consistency of an
|
| 49 | execution environment to ensure that direct file execution (e.g.
|
| 50 | ``./script.sh``) and indirect file execution (e.g. ``sh script.sh``) lead to
|
| 51 | the same result. For instance, this can be used to check if a file is
|
| 52 | trustworthy according to the caller's environment.
|
| 53 |
|
| 54 | In a secure environment, libraries and any executable dependencies should also
|
| 55 | be checked. For instance, dynamic linking should make sure that all libraries
|
| 56 | are allowed for execution to avoid trivial bypass (e.g. using ``LD_PRELOAD``).
|
| 57 | For such secure execution environment to make sense, only trusted code should
|
| 58 | be executable, which also requires integrity guarantees.
|
| 59 |
|
| 60 | To 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
|
| 62 | file descriptor instead of a path.
|
| 63 |
|
| 64 | SECBIT_EXEC_RESTRICT_FILE and SECBIT_EXEC_DENY_INTERACTIVE
|
| 65 | ==========================================================
|
| 66 |
|
| 67 | When ``SECBIT_EXEC_RESTRICT_FILE`` is set, a process should only interpret or
|
| 68 | execute a file if a call to :manpage:`execveat(2)` with the related file
|
| 69 | descriptor and the ``AT_EXECVE_CHECK`` flag succeed.
|
| 70 |
|
| 71 | This secure bit may be set by user session managers, service managers,
|
| 72 | container runtimes, sandboxer tools... Except for test environments, the
|
| 73 | related ``SECBIT_EXEC_RESTRICT_FILE_LOCKED`` bit should also be set.
|
| 74 |
|
| 75 | Programs should only enforce consistent restrictions according to the
|
| 76 | securebits but without relying on any other user-controlled configuration.
|
| 77 | Indeed, the use case for these securebits is to only trust executable code
|
| 78 | vetted by the system configuration (through the kernel), so we should be
|
| 79 | careful to not let untrusted users control this configuration.
|
| 80 |
|
| 81 | However, script interpreters may still use user configuration such as
|
| 82 | environment variables as long as it is not a way to disable the securebits
|
| 83 | checks. For instance, the ``PATH`` and ``LD_PRELOAD`` variables can be set by
|
| 84 | a script's caller. Changing these variables may lead to unintended code
|
| 85 | executions, but only from vetted executable programs, which is OK. For this to
|
| 86 | make sense, the system should provide a consistent security policy to avoid
|
| 87 | arbitrary code execution e.g., by enforcing a write xor execute policy.
|
| 88 |
|
| 89 | When ``SECBIT_EXEC_DENY_INTERACTIVE`` is set, a process should never interpret
|
| 90 | interactive user commands (e.g. scripts). However, if such commands are passed
|
| 91 | through a file descriptor (e.g. stdin), its content should be interpreted if a
|
| 92 | call to :manpage:`execveat(2)` with the related file descriptor and the
|
| 93 | ``AT_EXECVE_CHECK`` flag succeed.
|
| 94 |
|
| 95 | For instance, script interpreters called with a script snippet as argument
|
| 96 | should always deny such execution if ``SECBIT_EXEC_DENY_INTERACTIVE`` is set.
|
| 97 |
|
| 98 | This secure bit may be set by user session managers, service managers,
|
| 99 | container runtimes, sandboxer tools... Except for test environments, the
|
| 100 | related ``SECBIT_EXEC_DENY_INTERACTIVE_LOCKED`` bit should also be set.
|
| 101 |
|
| 102 | Here is the expected behavior for a script interpreter according to combination
|
| 103 | of any exec securebits:
|
| 104 |
|
| 105 | 1. ``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 |
|
| 116 | 2. ``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 |
|
| 125 | 3. ``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 |
|
| 134 | 4. ``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 | |
| 143 | |
| 144 | https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/samples/check-exec/inc.c
|