check_exec.rst 7.3 KB

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