The new SECBIT_EXEC_RESTRICT_FILE, SECBIT_EXEC_DENY_INTERACTIVE, and
their *_LOCKED counterparts are designed to be set by processes setting
up an execution environment, such as a user session, a container, or a
security sandbox. Unlike other securebits, these ones can be set by
unprivileged processes. Like seccomp filters or Landlock domains, the
securebits are inherited across processes.
When SECBIT_EXEC_RESTRICT_FILE is set, programs interpreting code should
control executable resources according to execveat(2) + AT_CHECK (see
previous commit).
When SECBIT_EXEC_DENY_INTERACTIVE is set, a process should deny
execution of user interactive commands (which excludes executable
regular files).
Being able to configure each of these securebits enables system
administrators or owner of image containers to gradually validate the
related changes and to identify potential issues (e.g. with interpreter
or audit logs).
It should be noted that unlike other security bits, the
SECBIT_EXEC_RESTRICT_FILE and SECBIT_EXEC_DENY_INTERACTIVE bits are
dedicated to user space willing to restrict itself. Because of that,
they only make sense in the context of a trusted environment (e.g.
sandbox, container, user session, full system) where the process
changing its behavior (according to these bits) and all its parent
processes are trusted. Otherwise, any parent process could just execute
its own malicious code (interpreting a script or not), or even enforce a
seccomp filter to mask these bits.
Such a secure environment can be achieved with an appropriate access
control (e.g. mount's noexec option, file access rights, LSM policy) and
an enlighten ld.so checking that libraries are allowed for execution
e.g., to protect against illegitimate use of LD_PRELOAD.
Ptrace restrictions according to these securebits would not make sense
because of the processes' trust assumption.
Scripts may need some changes to deal with untrusted data (e.g. stdin,
environment variables), but that is outside the scope of the kernel.
See chromeOS's documentation about script execution control and the
related threat model:
https://www.chromium.org/chromium-os/developer-library/guides/security/noexec-shell-scripts/
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: Andy Lutomirski <luto@amacapital.net>
Cc: Christian Brauner <brauner@kernel.org>
Cc: Kees Cook <keescook@chromium.org>
Cc: Paul Moore <paul@paul-moore.com>
Cc: Serge Hallyn <serge@hallyn.com>
Signed-off-by: Mickaël Salaün <mic@digikod.net>
Link: https://lore.kernel.org/r/20241011184422.977903-3-mic@digikod.net
---
Changes since v19:
* Replace SECBIT_SHOULD_EXEC_CHECK and SECBIT_SHOULD_EXEC_RESTRICT with
SECBIT_EXEC_RESTRICT_FILE and SECBIT_EXEC_DENY_INTERACTIVE:
https://lore.kernel.org/all/20240710.eiKohpa4Phai@digikod.net/
* Remove the ptrace restrictions, suggested by Andy.
* Improve documentation according to the discussion with Jeff.
New design since v18:
https://lore.kernel.org/r/20220104155024.48023-3-mic@digikod.net
---
include/uapi/linux/securebits.h | 113 +++++++++++++++++++++++++++++++-
security/commoncap.c | 29 ++++++--
2 files changed, 135 insertions(+), 7 deletions(-)
diff --git a/include/uapi/linux/securebits.h b/include/uapi/linux/securebits.h
index d6d98877ff1a..351b6ecefc76 100644
--- a/include/uapi/linux/securebits.h
+++ b/include/uapi/linux/securebits.h
@@ -52,10 +52,121 @@
#define SECBIT_NO_CAP_AMBIENT_RAISE_LOCKED \
(issecure_mask(SECURE_NO_CAP_AMBIENT_RAISE_LOCKED))
+/*
+ * The SECBIT_EXEC_RESTRICT_FILE and SECBIT_EXEC_DENY_INTERACTIVE securebits
+ * are intended for script interpreters and dynamic linkers to enforce a
+ * consistent execution security policy handled by the kernel.
+ *
+ * Whether an interpreter should check these securebits or not depends on the
+ * security risk of running malicious scripts with respect to the execution
+ * environment, and whether the kernel can check if a script is trustworthy or
+ * not. For instance, Python scripts running on a server can use arbitrary
+ * syscalls and access arbitrary files. Such interpreters should then be
+ * enlighten to use these securebits and let users define their security
+ * policy. However, a JavaScript engine running in a web browser should
+ * already be sandboxed and then should not be able to harm the user's
+ * environment.
+ *
+ * When SECBIT_EXEC_RESTRICT_FILE is set, a process should only interpret or
+ * execute a file if a call to execveat(2) with the related file descriptor and
+ * the AT_CHECK flag succeed.
+ *
+ * This secure bit may be set by user session managers, service managers,
+ * container runtimes, sandboxer tools... Except for test environments, the
+ * related SECBIT_EXEC_RESTRICT_FILE_LOCKED bit should also be set.
+ *
+ * Programs should only enforce consistent restrictions according to the
+ * securebits but without relying on any other user-controlled configuration.
+ * Indeed, the use case for these securebits is to only trust executable code
+ * vetted by the system configuration (through the kernel), so we should be
+ * careful to not let untrusted users control this configuration.
+ *
+ * However, script interpreters may still use user configuration such as
+ * environment variables as long as it is not a way to disable the securebits
+ * checks. For instance, the PATH and LD_PRELOAD variables can be set by a
+ * script's caller. Changing these variables may lead to unintended code
+ * executions, but only from vetted executable programs, which is OK. For this
+ * to make sense, the system should provide a consistent security policy to
+ * avoid arbitrary code execution e.g., by enforcing a write xor execute
+ * policy.
+ *
+ * SECBIT_EXEC_RESTRICT_FILE is complementary and should also be checked.
+ */
+#define SECURE_EXEC_RESTRICT_FILE 8
+#define SECURE_EXEC_RESTRICT_FILE_LOCKED 9 /* make bit-8 immutable */
+
+#define SECBIT_EXEC_RESTRICT_FILE (issecure_mask(SECURE_EXEC_RESTRICT_FILE))
+#define SECBIT_EXEC_RESTRICT_FILE_LOCKED \
+ (issecure_mask(SECURE_EXEC_RESTRICT_FILE_LOCKED))
+
+/*
+ * When SECBIT_EXEC_DENY_INTERACTIVE is set, a process should never interpret
+ * interactive user commands (e.g. scripts). However, if such commands are
+ * passed through a file descriptor (e.g. stdin), its content should be
+ * interpreted if a call to execveat(2) with the related file descriptor and
+ * the AT_CHECK flag succeed.
+ *
+ * For instance, script interpreters called with a script snippet as argument
+ * should always deny such execution if SECBIT_EXEC_DENY_INTERACTIVE is set.
+ *
+ * This secure bit may be set by user session managers, service managers,
+ * container runtimes, sandboxer tools... Except for test environments, the
+ * related SECBIT_EXEC_DENY_INTERACTIVE_LOCKED bit should also be set.
+ *
+ * See the SECBIT_EXEC_RESTRICT_FILE documentation.
+ *
+ * Here is the expected behavior for a script interpreter according to
+ * combination of any exec securebits:
+ *
+ * 1. SECURE_EXEC_RESTRICT_FILE=0 SECURE_EXEC_DENY_INTERACTIVE=0 (default)
+ * Always interpret scripts, and allow arbitrary user commands.
+ * => No threat, everyone and everything is trusted, but we can get ahead of
+ * potential issues thanks to the call to execveat with AT_CHECK which
+ * should always be performed but ignored by the script interpreter.
+ * Indeed, this check is still important to enable systems administrators
+ * to verify requests (e.g. with audit) and prepare for migration to a
+ * secure mode.
+ *
+ * 2. SECURE_EXEC_RESTRICT_FILE=1 SECURE_EXEC_DENY_INTERACTIVE=0
+ * Deny script interpretation if they are not executable, but allow
+ * arbitrary user commands.
+ * => The threat is (potential) malicious scripts run by trusted (and not
+ * fooled) users. That can protect against unintended script executions
+ * (e.g. sh /tmp/*.sh). This makes sense for (semi-restricted) user
+ * sessions.
+ *
+ * 3. SECURE_EXEC_RESTRICT_FILE=0 SECURE_EXEC_DENY_INTERACTIVE=1
+ * Always interpret scripts, but deny arbitrary user commands.
+ * => This use case may be useful for secure services (i.e. without
+ * interactive user session) where scripts' integrity is verified (e.g.
+ * with IMA/EVM or dm-verity/IPE) but where access rights might not be
+ * ready yet. Indeed, arbitrary interactive commands would be much more
+ * difficult to check.
+ *
+ * 4. SECURE_EXEC_RESTRICT_FILE=1 SECURE_EXEC_DENY_INTERACTIVE=1
+ * Deny script interpretation if they are not executable, and also deny
+ * any arbitrary user commands.
+ * => The threat is malicious scripts run by untrusted users (but trusted
+ * code). This makes sense for system services that may only execute
+ * trusted scripts.
+ */
+#define SECURE_EXEC_DENY_INTERACTIVE 10
+#define SECURE_EXEC_DENY_INTERACTIVE_LOCKED 11 /* make bit-10 immutable */
+
+#define SECBIT_EXEC_DENY_INTERACTIVE \
+ (issecure_mask(SECURE_EXEC_DENY_INTERACTIVE))
+#define SECBIT_EXEC_DENY_INTERACTIVE_LOCKED \
+ (issecure_mask(SECURE_EXEC_DENY_INTERACTIVE_LOCKED))
+
#define SECURE_ALL_BITS (issecure_mask(SECURE_NOROOT) | \
issecure_mask(SECURE_NO_SETUID_FIXUP) | \
issecure_mask(SECURE_KEEP_CAPS) | \
- issecure_mask(SECURE_NO_CAP_AMBIENT_RAISE))
+ issecure_mask(SECURE_NO_CAP_AMBIENT_RAISE) | \
+ issecure_mask(SECURE_EXEC_RESTRICT_FILE) | \
+ issecure_mask(SECURE_EXEC_DENY_INTERACTIVE))
#define SECURE_ALL_LOCKS (SECURE_ALL_BITS << 1)
+#define SECURE_ALL_UNPRIVILEGED (issecure_mask(SECURE_EXEC_RESTRICT_FILE) | \
+ issecure_mask(SECURE_EXEC_DENY_INTERACTIVE))
+
#endif /* _UAPI_LINUX_SECUREBITS_H */
diff --git a/security/commoncap.c b/security/commoncap.c
index cefad323a0b1..52ea01acb453 100644
--- a/security/commoncap.c
+++ b/security/commoncap.c
@@ -1302,21 +1302,38 @@ int cap_task_prctl(int option, unsigned long arg2, unsigned long arg3,
& (old->securebits ^ arg2)) /*[1]*/
|| ((old->securebits & SECURE_ALL_LOCKS & ~arg2)) /*[2]*/
|| (arg2 & ~(SECURE_ALL_LOCKS | SECURE_ALL_BITS)) /*[3]*/
- || (cap_capable(current_cred(),
- current_cred()->user_ns,
- CAP_SETPCAP,
- CAP_OPT_NONE) != 0) /*[4]*/
/*
* [1] no changing of bits that are locked
* [2] no unlocking of locks
* [3] no setting of unsupported bits
- * [4] doing anything requires privilege (go read about
- * the "sendmail capabilities bug")
*/
)
/* cannot change a locked bit */
return -EPERM;
+ /*
+ * Doing anything requires privilege (go read about the
+ * "sendmail capabilities bug"), except for unprivileged bits.
+ * Indeed, the SECURE_ALL_UNPRIVILEGED bits are not
+ * restrictions enforced by the kernel but by user space on
+ * itself.
+ */
+ if (cap_capable(current_cred(), current_cred()->user_ns,
+ CAP_SETPCAP, CAP_OPT_NONE) != 0) {
+ const unsigned long unpriv_and_locks =
+ SECURE_ALL_UNPRIVILEGED |
+ SECURE_ALL_UNPRIVILEGED << 1;
+ const unsigned long changed = old->securebits ^ arg2;
+
+ /* For legacy reason, denies non-change. */
+ if (!changed)
+ return -EPERM;
+
+ /* Denies privileged changes. */
+ if (changed & ~unpriv_and_locks)
+ return -EPERM;
+ }
+
new = prepare_creds();
if (!new)
return -ENOMEM;
--
2.46.1
On Fri, Oct 11, 2024 at 08:44:18PM +0200, Mickaël Salaün wrote: > The new SECBIT_EXEC_RESTRICT_FILE, SECBIT_EXEC_DENY_INTERACTIVE, and > their *_LOCKED counterparts are designed to be set by processes setting > up an execution environment, such as a user session, a container, or a > security sandbox. Unlike other securebits, these ones can be set by > unprivileged processes. Like seccomp filters or Landlock domains, the > securebits are inherited across processes. > > When SECBIT_EXEC_RESTRICT_FILE is set, programs interpreting code should > control executable resources according to execveat(2) + AT_CHECK (see > previous commit). > > When SECBIT_EXEC_DENY_INTERACTIVE is set, a process should deny > execution of user interactive commands (which excludes executable > regular files). > > Being able to configure each of these securebits enables system > administrators or owner of image containers to gradually validate the > related changes and to identify potential issues (e.g. with interpreter > or audit logs). > > It should be noted that unlike other security bits, the > SECBIT_EXEC_RESTRICT_FILE and SECBIT_EXEC_DENY_INTERACTIVE bits are > dedicated to user space willing to restrict itself. Because of that, > they only make sense in the context of a trusted environment (e.g. > sandbox, container, user session, full system) where the process > changing its behavior (according to these bits) and all its parent > processes are trusted. Otherwise, any parent process could just execute > its own malicious code (interpreting a script or not), or even enforce a > seccomp filter to mask these bits. > > Such a secure environment can be achieved with an appropriate access > control (e.g. mount's noexec option, file access rights, LSM policy) and > an enlighten ld.so checking that libraries are allowed for execution > e.g., to protect against illegitimate use of LD_PRELOAD. > > Ptrace restrictions according to these securebits would not make sense > because of the processes' trust assumption. > > Scripts may need some changes to deal with untrusted data (e.g. stdin, > environment variables), but that is outside the scope of the kernel. > > See chromeOS's documentation about script execution control and the > related threat model: > https://www.chromium.org/chromium-os/developer-library/guides/security/noexec-shell-scripts/ > > Cc: Al Viro <viro@zeniv.linux.org.uk> > Cc: Andy Lutomirski <luto@amacapital.net> > Cc: Christian Brauner <brauner@kernel.org> > Cc: Kees Cook <keescook@chromium.org> > Cc: Paul Moore <paul@paul-moore.com> > Cc: Serge Hallyn <serge@hallyn.com> Reviewed-by: Serge Hallyn <serge@hallyn.com> thanks, -serge > Signed-off-by: Mickaël Salaün <mic@digikod.net> > Link: https://lore.kernel.org/r/20241011184422.977903-3-mic@digikod.net > --- > > Changes since v19: > * Replace SECBIT_SHOULD_EXEC_CHECK and SECBIT_SHOULD_EXEC_RESTRICT with > SECBIT_EXEC_RESTRICT_FILE and SECBIT_EXEC_DENY_INTERACTIVE: > https://lore.kernel.org/all/20240710.eiKohpa4Phai@digikod.net/ > * Remove the ptrace restrictions, suggested by Andy. > * Improve documentation according to the discussion with Jeff. > > New design since v18: > https://lore.kernel.org/r/20220104155024.48023-3-mic@digikod.net > --- > include/uapi/linux/securebits.h | 113 +++++++++++++++++++++++++++++++- > security/commoncap.c | 29 ++++++-- > 2 files changed, 135 insertions(+), 7 deletions(-) > > diff --git a/include/uapi/linux/securebits.h b/include/uapi/linux/securebits.h > index d6d98877ff1a..351b6ecefc76 100644 > --- a/include/uapi/linux/securebits.h > +++ b/include/uapi/linux/securebits.h > @@ -52,10 +52,121 @@ > #define SECBIT_NO_CAP_AMBIENT_RAISE_LOCKED \ > (issecure_mask(SECURE_NO_CAP_AMBIENT_RAISE_LOCKED)) > > +/* > + * The SECBIT_EXEC_RESTRICT_FILE and SECBIT_EXEC_DENY_INTERACTIVE securebits > + * are intended for script interpreters and dynamic linkers to enforce a > + * consistent execution security policy handled by the kernel. > + * > + * Whether an interpreter should check these securebits or not depends on the > + * security risk of running malicious scripts with respect to the execution > + * environment, and whether the kernel can check if a script is trustworthy or > + * not. For instance, Python scripts running on a server can use arbitrary > + * syscalls and access arbitrary files. Such interpreters should then be > + * enlighten to use these securebits and let users define their security > + * policy. However, a JavaScript engine running in a web browser should > + * already be sandboxed and then should not be able to harm the user's > + * environment. > + * > + * When SECBIT_EXEC_RESTRICT_FILE is set, a process should only interpret or > + * execute a file if a call to execveat(2) with the related file descriptor and > + * the AT_CHECK flag succeed. > + * > + * This secure bit may be set by user session managers, service managers, > + * container runtimes, sandboxer tools... Except for test environments, the > + * related SECBIT_EXEC_RESTRICT_FILE_LOCKED bit should also be set. > + * > + * Programs should only enforce consistent restrictions according to the > + * securebits but without relying on any other user-controlled configuration. > + * Indeed, the use case for these securebits is to only trust executable code > + * vetted by the system configuration (through the kernel), so we should be > + * careful to not let untrusted users control this configuration. > + * > + * However, script interpreters may still use user configuration such as > + * environment variables as long as it is not a way to disable the securebits > + * checks. For instance, the PATH and LD_PRELOAD variables can be set by a > + * script's caller. Changing these variables may lead to unintended code > + * executions, but only from vetted executable programs, which is OK. For this > + * to make sense, the system should provide a consistent security policy to > + * avoid arbitrary code execution e.g., by enforcing a write xor execute > + * policy. > + * > + * SECBIT_EXEC_RESTRICT_FILE is complementary and should also be checked. > + */ > +#define SECURE_EXEC_RESTRICT_FILE 8 > +#define SECURE_EXEC_RESTRICT_FILE_LOCKED 9 /* make bit-8 immutable */ > + > +#define SECBIT_EXEC_RESTRICT_FILE (issecure_mask(SECURE_EXEC_RESTRICT_FILE)) > +#define SECBIT_EXEC_RESTRICT_FILE_LOCKED \ > + (issecure_mask(SECURE_EXEC_RESTRICT_FILE_LOCKED)) > + > +/* > + * When SECBIT_EXEC_DENY_INTERACTIVE is set, a process should never interpret > + * interactive user commands (e.g. scripts). However, if such commands are > + * passed through a file descriptor (e.g. stdin), its content should be > + * interpreted if a call to execveat(2) with the related file descriptor and > + * the AT_CHECK flag succeed. > + * > + * For instance, script interpreters called with a script snippet as argument > + * should always deny such execution if SECBIT_EXEC_DENY_INTERACTIVE is set. > + * > + * This secure bit may be set by user session managers, service managers, > + * container runtimes, sandboxer tools... Except for test environments, the > + * related SECBIT_EXEC_DENY_INTERACTIVE_LOCKED bit should also be set. > + * > + * See the SECBIT_EXEC_RESTRICT_FILE documentation. > + * > + * Here is the expected behavior for a script interpreter according to > + * combination of any exec securebits: > + * > + * 1. SECURE_EXEC_RESTRICT_FILE=0 SECURE_EXEC_DENY_INTERACTIVE=0 (default) > + * Always interpret scripts, and allow arbitrary user commands. > + * => No threat, everyone and everything is trusted, but we can get ahead of > + * potential issues thanks to the call to execveat with AT_CHECK which > + * should always be performed but ignored by the script interpreter. > + * Indeed, this check is still important to enable systems administrators > + * to verify requests (e.g. with audit) and prepare for migration to a > + * secure mode. > + * > + * 2. SECURE_EXEC_RESTRICT_FILE=1 SECURE_EXEC_DENY_INTERACTIVE=0 > + * Deny script interpretation if they are not executable, but allow > + * arbitrary user commands. > + * => The threat is (potential) malicious scripts run by trusted (and not > + * fooled) users. That can protect against unintended script executions > + * (e.g. sh /tmp/*.sh). This makes sense for (semi-restricted) user > + * sessions. > + * > + * 3. SECURE_EXEC_RESTRICT_FILE=0 SECURE_EXEC_DENY_INTERACTIVE=1 > + * Always interpret scripts, but deny arbitrary user commands. > + * => This use case may be useful for secure services (i.e. without > + * interactive user session) where scripts' integrity is verified (e.g. > + * with IMA/EVM or dm-verity/IPE) but where access rights might not be > + * ready yet. Indeed, arbitrary interactive commands would be much more > + * difficult to check. > + * > + * 4. SECURE_EXEC_RESTRICT_FILE=1 SECURE_EXEC_DENY_INTERACTIVE=1 > + * Deny script interpretation if they are not executable, and also deny > + * any arbitrary user commands. > + * => The threat is malicious scripts run by untrusted users (but trusted > + * code). This makes sense for system services that may only execute > + * trusted scripts. > + */ > +#define SECURE_EXEC_DENY_INTERACTIVE 10 > +#define SECURE_EXEC_DENY_INTERACTIVE_LOCKED 11 /* make bit-10 immutable */ > + > +#define SECBIT_EXEC_DENY_INTERACTIVE \ > + (issecure_mask(SECURE_EXEC_DENY_INTERACTIVE)) > +#define SECBIT_EXEC_DENY_INTERACTIVE_LOCKED \ > + (issecure_mask(SECURE_EXEC_DENY_INTERACTIVE_LOCKED)) > + > #define SECURE_ALL_BITS (issecure_mask(SECURE_NOROOT) | \ > issecure_mask(SECURE_NO_SETUID_FIXUP) | \ > issecure_mask(SECURE_KEEP_CAPS) | \ > - issecure_mask(SECURE_NO_CAP_AMBIENT_RAISE)) > + issecure_mask(SECURE_NO_CAP_AMBIENT_RAISE) | \ > + issecure_mask(SECURE_EXEC_RESTRICT_FILE) | \ > + issecure_mask(SECURE_EXEC_DENY_INTERACTIVE)) > #define SECURE_ALL_LOCKS (SECURE_ALL_BITS << 1) > > +#define SECURE_ALL_UNPRIVILEGED (issecure_mask(SECURE_EXEC_RESTRICT_FILE) | \ > + issecure_mask(SECURE_EXEC_DENY_INTERACTIVE)) > + > #endif /* _UAPI_LINUX_SECUREBITS_H */ > diff --git a/security/commoncap.c b/security/commoncap.c > index cefad323a0b1..52ea01acb453 100644 > --- a/security/commoncap.c > +++ b/security/commoncap.c > @@ -1302,21 +1302,38 @@ int cap_task_prctl(int option, unsigned long arg2, unsigned long arg3, > & (old->securebits ^ arg2)) /*[1]*/ > || ((old->securebits & SECURE_ALL_LOCKS & ~arg2)) /*[2]*/ > || (arg2 & ~(SECURE_ALL_LOCKS | SECURE_ALL_BITS)) /*[3]*/ > - || (cap_capable(current_cred(), > - current_cred()->user_ns, > - CAP_SETPCAP, > - CAP_OPT_NONE) != 0) /*[4]*/ > /* > * [1] no changing of bits that are locked > * [2] no unlocking of locks > * [3] no setting of unsupported bits > - * [4] doing anything requires privilege (go read about > - * the "sendmail capabilities bug") > */ > ) > /* cannot change a locked bit */ > return -EPERM; > > + /* > + * Doing anything requires privilege (go read about the > + * "sendmail capabilities bug"), except for unprivileged bits. > + * Indeed, the SECURE_ALL_UNPRIVILEGED bits are not > + * restrictions enforced by the kernel but by user space on > + * itself. > + */ > + if (cap_capable(current_cred(), current_cred()->user_ns, > + CAP_SETPCAP, CAP_OPT_NONE) != 0) { > + const unsigned long unpriv_and_locks = > + SECURE_ALL_UNPRIVILEGED | > + SECURE_ALL_UNPRIVILEGED << 1; > + const unsigned long changed = old->securebits ^ arg2; > + > + /* For legacy reason, denies non-change. */ > + if (!changed) > + return -EPERM; > + > + /* Denies privileged changes. */ > + if (changed & ~unpriv_and_locks) > + return -EPERM; > + } > + > new = prepare_creds(); > if (!new) > return -ENOMEM; > -- > 2.46.1 >
Hi Mickaël, kernel test robot noticed the following build warnings: [auto build test WARNING on 8cf0b93919e13d1e8d4466eb4080a4c4d9d66d7b] url: https://github.com/intel-lab-lkp/linux/commits/Micka-l-Sala-n/exec-Add-a-new-AT_CHECK-flag-to-execveat-2/20241012-024801 base: 8cf0b93919e13d1e8d4466eb4080a4c4d9d66d7b patch link: https://lore.kernel.org/r/20241011184422.977903-3-mic%40digikod.net patch subject: [PATCH v20 2/6] security: Add EXEC_RESTRICT_FILE and EXEC_DENY_INTERACTIVE securebits config: arm-allnoconfig (https://download.01.org/0day-ci/archive/20241015/202410150756.KOkRl5oz-lkp@intel.com/config) compiler: clang version 20.0.0git (https://github.com/llvm/llvm-project 70e0a7e7e6a8541bcc46908c592eed561850e416) reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241015/202410150756.KOkRl5oz-lkp@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@intel.com> | Closes: https://lore.kernel.org/oe-kbuild-all/202410150756.KOkRl5oz-lkp@intel.com/ All warnings (new ones prefixed by >>): In file included from init/init_task.c:2: In file included from include/linux/init_task.h:9: In file included from include/linux/ftrace.h:13: In file included from include/linux/kallsyms.h:13: In file included from include/linux/mm.h:2213: include/linux/vmstat.h:518:36: warning: arithmetic between different enumeration types ('enum node_stat_item' and 'enum lru_list') [-Wenum-enum-conversion] 518 | return node_stat_name(NR_LRU_BASE + lru) + 3; // skip "nr_" | ~~~~~~~~~~~ ^ ~~~ In file included from init/init_task.c:2: In file included from include/linux/init_task.h:13: In file included from include/linux/securebits.h:5: >> include/uapi/linux/securebits.h:135:23: warning: '/*' within block comment [-Wcomment] 135 | * (e.g. sh /tmp/*.sh). This makes sense for (semi-restricted) user | ^ 2 warnings generated. vim +135 include/uapi/linux/securebits.h 97 98 #define SECBIT_EXEC_RESTRICT_FILE (issecure_mask(SECURE_EXEC_RESTRICT_FILE)) 99 #define SECBIT_EXEC_RESTRICT_FILE_LOCKED \ 100 (issecure_mask(SECURE_EXEC_RESTRICT_FILE_LOCKED)) 101 102 /* 103 * When SECBIT_EXEC_DENY_INTERACTIVE is set, a process should never interpret 104 * interactive user commands (e.g. scripts). However, if such commands are 105 * passed through a file descriptor (e.g. stdin), its content should be 106 * interpreted if a call to execveat(2) with the related file descriptor and 107 * the AT_CHECK flag succeed. 108 * 109 * For instance, script interpreters called with a script snippet as argument 110 * should always deny such execution if SECBIT_EXEC_DENY_INTERACTIVE is set. 111 * 112 * This secure bit may be set by user session managers, service managers, 113 * container runtimes, sandboxer tools... Except for test environments, the 114 * related SECBIT_EXEC_DENY_INTERACTIVE_LOCKED bit should also be set. 115 * 116 * See the SECBIT_EXEC_RESTRICT_FILE documentation. 117 * 118 * Here is the expected behavior for a script interpreter according to 119 * combination of any exec securebits: 120 * 121 * 1. SECURE_EXEC_RESTRICT_FILE=0 SECURE_EXEC_DENY_INTERACTIVE=0 (default) 122 * Always interpret scripts, and allow arbitrary user commands. 123 * => No threat, everyone and everything is trusted, but we can get ahead of 124 * potential issues thanks to the call to execveat with AT_CHECK which 125 * should always be performed but ignored by the script interpreter. 126 * Indeed, this check is still important to enable systems administrators 127 * to verify requests (e.g. with audit) and prepare for migration to a 128 * secure mode. 129 * 130 * 2. SECURE_EXEC_RESTRICT_FILE=1 SECURE_EXEC_DENY_INTERACTIVE=0 131 * Deny script interpretation if they are not executable, but allow 132 * arbitrary user commands. 133 * => The threat is (potential) malicious scripts run by trusted (and not 134 * fooled) users. That can protect against unintended script executions > 135 * (e.g. sh /tmp/*.sh). This makes sense for (semi-restricted) user 136 * sessions. 137 * 138 * 3. SECURE_EXEC_RESTRICT_FILE=0 SECURE_EXEC_DENY_INTERACTIVE=1 139 * Always interpret scripts, but deny arbitrary user commands. 140 * => This use case may be useful for secure services (i.e. without 141 * interactive user session) where scripts' integrity is verified (e.g. 142 * with IMA/EVM or dm-verity/IPE) but where access rights might not be 143 * ready yet. Indeed, arbitrary interactive commands would be much more 144 * difficult to check. 145 * 146 * 4. SECURE_EXEC_RESTRICT_FILE=1 SECURE_EXEC_DENY_INTERACTIVE=1 147 * Deny script interpretation if they are not executable, and also deny 148 * any arbitrary user commands. 149 * => The threat is malicious scripts run by untrusted users (but trusted 150 * code). This makes sense for system services that may only execute 151 * trusted scripts. 152 */ 153 #define SECURE_EXEC_DENY_INTERACTIVE 10 154 #define SECURE_EXEC_DENY_INTERACTIVE_LOCKED 11 /* make bit-10 immutable */ 155 -- 0-DAY CI Kernel Test Service https://github.com/intel/lkp-tests/wiki
Hi Mickaël, kernel test robot noticed the following build warnings: [auto build test WARNING on 8cf0b93919e13d1e8d4466eb4080a4c4d9d66d7b] url: https://github.com/intel-lab-lkp/linux/commits/Micka-l-Sala-n/exec-Add-a-new-AT_CHECK-flag-to-execveat-2/20241012-024801 base: 8cf0b93919e13d1e8d4466eb4080a4c4d9d66d7b patch link: https://lore.kernel.org/r/20241011184422.977903-3-mic%40digikod.net patch subject: [PATCH v20 2/6] security: Add EXEC_RESTRICT_FILE and EXEC_DENY_INTERACTIVE securebits config: alpha-allnoconfig (https://download.01.org/0day-ci/archive/20241015/202410150702.GVWMEEA4-lkp@intel.com/config) compiler: alpha-linux-gcc (GCC) 13.3.0 reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241015/202410150702.GVWMEEA4-lkp@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@intel.com> | Closes: https://lore.kernel.org/oe-kbuild-all/202410150702.GVWMEEA4-lkp@intel.com/ All warnings (new ones prefixed by >>): In file included from include/linux/securebits.h:5, from include/linux/init_task.h:13, from init/init_task.c:2: >> include/uapi/linux/securebits.h:135:23: warning: "/*" within comment [-Wcomment] 135 | * (e.g. sh /tmp/*.sh). This makes sense for (semi-restricted) user | vim +135 include/uapi/linux/securebits.h 97 98 #define SECBIT_EXEC_RESTRICT_FILE (issecure_mask(SECURE_EXEC_RESTRICT_FILE)) 99 #define SECBIT_EXEC_RESTRICT_FILE_LOCKED \ 100 (issecure_mask(SECURE_EXEC_RESTRICT_FILE_LOCKED)) 101 102 /* 103 * When SECBIT_EXEC_DENY_INTERACTIVE is set, a process should never interpret 104 * interactive user commands (e.g. scripts). However, if such commands are 105 * passed through a file descriptor (e.g. stdin), its content should be 106 * interpreted if a call to execveat(2) with the related file descriptor and 107 * the AT_CHECK flag succeed. 108 * 109 * For instance, script interpreters called with a script snippet as argument 110 * should always deny such execution if SECBIT_EXEC_DENY_INTERACTIVE is set. 111 * 112 * This secure bit may be set by user session managers, service managers, 113 * container runtimes, sandboxer tools... Except for test environments, the 114 * related SECBIT_EXEC_DENY_INTERACTIVE_LOCKED bit should also be set. 115 * 116 * See the SECBIT_EXEC_RESTRICT_FILE documentation. 117 * 118 * Here is the expected behavior for a script interpreter according to 119 * combination of any exec securebits: 120 * 121 * 1. SECURE_EXEC_RESTRICT_FILE=0 SECURE_EXEC_DENY_INTERACTIVE=0 (default) 122 * Always interpret scripts, and allow arbitrary user commands. 123 * => No threat, everyone and everything is trusted, but we can get ahead of 124 * potential issues thanks to the call to execveat with AT_CHECK which 125 * should always be performed but ignored by the script interpreter. 126 * Indeed, this check is still important to enable systems administrators 127 * to verify requests (e.g. with audit) and prepare for migration to a 128 * secure mode. 129 * 130 * 2. SECURE_EXEC_RESTRICT_FILE=1 SECURE_EXEC_DENY_INTERACTIVE=0 131 * Deny script interpretation if they are not executable, but allow 132 * arbitrary user commands. 133 * => The threat is (potential) malicious scripts run by trusted (and not 134 * fooled) users. That can protect against unintended script executions > 135 * (e.g. sh /tmp/*.sh). This makes sense for (semi-restricted) user 136 * sessions. 137 * 138 * 3. SECURE_EXEC_RESTRICT_FILE=0 SECURE_EXEC_DENY_INTERACTIVE=1 139 * Always interpret scripts, but deny arbitrary user commands. 140 * => This use case may be useful for secure services (i.e. without 141 * interactive user session) where scripts' integrity is verified (e.g. 142 * with IMA/EVM or dm-verity/IPE) but where access rights might not be 143 * ready yet. Indeed, arbitrary interactive commands would be much more 144 * difficult to check. 145 * 146 * 4. SECURE_EXEC_RESTRICT_FILE=1 SECURE_EXEC_DENY_INTERACTIVE=1 147 * Deny script interpretation if they are not executable, and also deny 148 * any arbitrary user commands. 149 * => The threat is malicious scripts run by untrusted users (but trusted 150 * code). This makes sense for system services that may only execute 151 * trusted scripts. 152 */ 153 #define SECURE_EXEC_DENY_INTERACTIVE 10 154 #define SECURE_EXEC_DENY_INTERACTIVE_LOCKED 11 /* make bit-10 immutable */ 155 -- 0-DAY CI Kernel Test Service https://github.com/intel/lkp-tests/wiki
On Fri, Oct 11, 2024 at 08:44:18PM +0200, Mickaël Salaün wrote: > The new SECBIT_EXEC_RESTRICT_FILE, SECBIT_EXEC_DENY_INTERACTIVE, and > their *_LOCKED counterparts are designed to be set by processes setting > up an execution environment, such as a user session, a container, or a > security sandbox. Unlike other securebits, these ones can be set by > unprivileged processes. Like seccomp filters or Landlock domains, the > securebits are inherited across processes. > > When SECBIT_EXEC_RESTRICT_FILE is set, programs interpreting code should > control executable resources according to execveat(2) + AT_CHECK (see > previous commit). > > When SECBIT_EXEC_DENY_INTERACTIVE is set, a process should deny > execution of user interactive commands (which excludes executable > regular files). > > Being able to configure each of these securebits enables system > administrators or owner of image containers to gradually validate the > related changes and to identify potential issues (e.g. with interpreter > or audit logs). > > It should be noted that unlike other security bits, the > SECBIT_EXEC_RESTRICT_FILE and SECBIT_EXEC_DENY_INTERACTIVE bits are > dedicated to user space willing to restrict itself. Because of that, > they only make sense in the context of a trusted environment (e.g. > sandbox, container, user session, full system) where the process > changing its behavior (according to these bits) and all its parent > processes are trusted. Otherwise, any parent process could just execute > its own malicious code (interpreting a script or not), or even enforce a > seccomp filter to mask these bits. > > Such a secure environment can be achieved with an appropriate access > control (e.g. mount's noexec option, file access rights, LSM policy) and > an enlighten ld.so checking that libraries are allowed for execution > e.g., to protect against illegitimate use of LD_PRELOAD. > > Ptrace restrictions according to these securebits would not make sense > because of the processes' trust assumption. > > Scripts may need some changes to deal with untrusted data (e.g. stdin, > environment variables), but that is outside the scope of the kernel. > > See chromeOS's documentation about script execution control and the > related threat model: > https://www.chromium.org/chromium-os/developer-library/guides/security/noexec-shell-scripts/ > > Cc: Al Viro <viro@zeniv.linux.org.uk> > Cc: Andy Lutomirski <luto@amacapital.net> > Cc: Christian Brauner <brauner@kernel.org> > Cc: Kees Cook <keescook@chromium.org> > Cc: Paul Moore <paul@paul-moore.com> > Cc: Serge Hallyn <serge@hallyn.com> > Signed-off-by: Mickaël Salaün <mic@digikod.net> > Link: https://lore.kernel.org/r/20241011184422.977903-3-mic@digikod.net > --- > > Changes since v19: > * Replace SECBIT_SHOULD_EXEC_CHECK and SECBIT_SHOULD_EXEC_RESTRICT with > SECBIT_EXEC_RESTRICT_FILE and SECBIT_EXEC_DENY_INTERACTIVE: > https://lore.kernel.org/all/20240710.eiKohpa4Phai@digikod.net/ > * Remove the ptrace restrictions, suggested by Andy. > * Improve documentation according to the discussion with Jeff. > > New design since v18: > https://lore.kernel.org/r/20220104155024.48023-3-mic@digikod.net > --- > include/uapi/linux/securebits.h | 113 +++++++++++++++++++++++++++++++- > security/commoncap.c | 29 ++++++-- > 2 files changed, 135 insertions(+), 7 deletions(-) > > diff --git a/include/uapi/linux/securebits.h b/include/uapi/linux/securebits.h > index d6d98877ff1a..351b6ecefc76 100644 > --- a/include/uapi/linux/securebits.h > +++ b/include/uapi/linux/securebits.h > @@ -52,10 +52,121 @@ > #define SECBIT_NO_CAP_AMBIENT_RAISE_LOCKED \ > (issecure_mask(SECURE_NO_CAP_AMBIENT_RAISE_LOCKED)) > > +/* > + * The SECBIT_EXEC_RESTRICT_FILE and SECBIT_EXEC_DENY_INTERACTIVE securebits > + * are intended for script interpreters and dynamic linkers to enforce a > + * consistent execution security policy handled by the kernel. > + * > + * Whether an interpreter should check these securebits or not depends on the > + * security risk of running malicious scripts with respect to the execution > + * environment, and whether the kernel can check if a script is trustworthy or > + * not. For instance, Python scripts running on a server can use arbitrary > + * syscalls and access arbitrary files. Such interpreters should then be > + * enlighten to use these securebits and let users define their security > + * policy. However, a JavaScript engine running in a web browser should > + * already be sandboxed and then should not be able to harm the user's > + * environment. > + * > + * When SECBIT_EXEC_RESTRICT_FILE is set, a process should only interpret or > + * execute a file if a call to execveat(2) with the related file descriptor and > + * the AT_CHECK flag succeed. > + * > + * This secure bit may be set by user session managers, service managers, > + * container runtimes, sandboxer tools... Except for test environments, the > + * related SECBIT_EXEC_RESTRICT_FILE_LOCKED bit should also be set. > + * > + * Programs should only enforce consistent restrictions according to the > + * securebits but without relying on any other user-controlled configuration. > + * Indeed, the use case for these securebits is to only trust executable code > + * vetted by the system configuration (through the kernel), so we should be > + * careful to not let untrusted users control this configuration. > + * > + * However, script interpreters may still use user configuration such as > + * environment variables as long as it is not a way to disable the securebits > + * checks. For instance, the PATH and LD_PRELOAD variables can be set by a > + * script's caller. Changing these variables may lead to unintended code > + * executions, but only from vetted executable programs, which is OK. For this > + * to make sense, the system should provide a consistent security policy to > + * avoid arbitrary code execution e.g., by enforcing a write xor execute > + * policy. > + * > + * SECBIT_EXEC_RESTRICT_FILE is complementary and should also be checked. > + */ > +#define SECURE_EXEC_RESTRICT_FILE 8 > +#define SECURE_EXEC_RESTRICT_FILE_LOCKED 9 /* make bit-8 immutable */ > + > +#define SECBIT_EXEC_RESTRICT_FILE (issecure_mask(SECURE_EXEC_RESTRICT_FILE)) > +#define SECBIT_EXEC_RESTRICT_FILE_LOCKED \ > + (issecure_mask(SECURE_EXEC_RESTRICT_FILE_LOCKED)) > + > +/* > + * When SECBIT_EXEC_DENY_INTERACTIVE is set, a process should never interpret > + * interactive user commands (e.g. scripts). However, if such commands are > + * passed through a file descriptor (e.g. stdin), its content should be > + * interpreted if a call to execveat(2) with the related file descriptor and > + * the AT_CHECK flag succeed. > + * > + * For instance, script interpreters called with a script snippet as argument > + * should always deny such execution if SECBIT_EXEC_DENY_INTERACTIVE is set. > + * > + * This secure bit may be set by user session managers, service managers, > + * container runtimes, sandboxer tools... Except for test environments, the > + * related SECBIT_EXEC_DENY_INTERACTIVE_LOCKED bit should also be set. > + * > + * See the SECBIT_EXEC_RESTRICT_FILE documentation. > + * > + * Here is the expected behavior for a script interpreter according to > + * combination of any exec securebits: > + * > + * 1. SECURE_EXEC_RESTRICT_FILE=0 SECURE_EXEC_DENY_INTERACTIVE=0 (default) > + * Always interpret scripts, and allow arbitrary user commands. > + * => No threat, everyone and everything is trusted, but we can get ahead of > + * potential issues thanks to the call to execveat with AT_CHECK which > + * should always be performed but ignored by the script interpreter. > + * Indeed, this check is still important to enable systems administrators > + * to verify requests (e.g. with audit) and prepare for migration to a > + * secure mode. > + * > + * 2. SECURE_EXEC_RESTRICT_FILE=1 SECURE_EXEC_DENY_INTERACTIVE=0 > + * Deny script interpretation if they are not executable, but allow > + * arbitrary user commands. > + * => The threat is (potential) malicious scripts run by trusted (and not > + * fooled) users. That can protect against unintended script executions > + * (e.g. sh /tmp/*.sh). This makes sense for (semi-restricted) user > + * sessions. > + * > + * 3. SECURE_EXEC_RESTRICT_FILE=0 SECURE_EXEC_DENY_INTERACTIVE=1 > + * Always interpret scripts, but deny arbitrary user commands. > + * => This use case may be useful for secure services (i.e. without > + * interactive user session) where scripts' integrity is verified (e.g. > + * with IMA/EVM or dm-verity/IPE) but where access rights might not be > + * ready yet. Indeed, arbitrary interactive commands would be much more > + * difficult to check. > + * > + * 4. SECURE_EXEC_RESTRICT_FILE=1 SECURE_EXEC_DENY_INTERACTIVE=1 > + * Deny script interpretation if they are not executable, and also deny > + * any arbitrary user commands. > + * => The threat is malicious scripts run by untrusted users (but trusted > + * code). This makes sense for system services that may only execute > + * trusted scripts. > + */ > +#define SECURE_EXEC_DENY_INTERACTIVE 10 > +#define SECURE_EXEC_DENY_INTERACTIVE_LOCKED 11 /* make bit-10 immutable */ > + > +#define SECBIT_EXEC_DENY_INTERACTIVE \ > + (issecure_mask(SECURE_EXEC_DENY_INTERACTIVE)) > +#define SECBIT_EXEC_DENY_INTERACTIVE_LOCKED \ > + (issecure_mask(SECURE_EXEC_DENY_INTERACTIVE_LOCKED)) > + > #define SECURE_ALL_BITS (issecure_mask(SECURE_NOROOT) | \ > issecure_mask(SECURE_NO_SETUID_FIXUP) | \ > issecure_mask(SECURE_KEEP_CAPS) | \ > - issecure_mask(SECURE_NO_CAP_AMBIENT_RAISE)) > + issecure_mask(SECURE_NO_CAP_AMBIENT_RAISE) | \ > + issecure_mask(SECURE_EXEC_RESTRICT_FILE) | \ > + issecure_mask(SECURE_EXEC_DENY_INTERACTIVE)) > #define SECURE_ALL_LOCKS (SECURE_ALL_BITS << 1) > > +#define SECURE_ALL_UNPRIVILEGED (issecure_mask(SECURE_EXEC_RESTRICT_FILE) | \ > + issecure_mask(SECURE_EXEC_DENY_INTERACTIVE)) > + > #endif /* _UAPI_LINUX_SECUREBITS_H */ > diff --git a/security/commoncap.c b/security/commoncap.c > index cefad323a0b1..52ea01acb453 100644 > --- a/security/commoncap.c > +++ b/security/commoncap.c > @@ -1302,21 +1302,38 @@ int cap_task_prctl(int option, unsigned long arg2, unsigned long arg3, > & (old->securebits ^ arg2)) /*[1]*/ > || ((old->securebits & SECURE_ALL_LOCKS & ~arg2)) /*[2]*/ > || (arg2 & ~(SECURE_ALL_LOCKS | SECURE_ALL_BITS)) /*[3]*/ > - || (cap_capable(current_cred(), > - current_cred()->user_ns, > - CAP_SETPCAP, > - CAP_OPT_NONE) != 0) /*[4]*/ > /* > * [1] no changing of bits that are locked > * [2] no unlocking of locks > * [3] no setting of unsupported bits > - * [4] doing anything requires privilege (go read about > - * the "sendmail capabilities bug") > */ > ) > /* cannot change a locked bit */ > return -EPERM; > > + /* > + * Doing anything requires privilege (go read about the > + * "sendmail capabilities bug"), except for unprivileged bits. > + * Indeed, the SECURE_ALL_UNPRIVILEGED bits are not > + * restrictions enforced by the kernel but by user space on > + * itself. > + */ > + if (cap_capable(current_cred(), current_cred()->user_ns, > + CAP_SETPCAP, CAP_OPT_NONE) != 0) { > + const unsigned long unpriv_and_locks = > + SECURE_ALL_UNPRIVILEGED | > + SECURE_ALL_UNPRIVILEGED << 1; > + const unsigned long changed = old->securebits ^ arg2; > + > + /* For legacy reason, denies non-change. */ > + if (!changed) > + return -EPERM; This is odd to me. You say for legacy reasons, but, currently, calling PR_SET_SECUREBITS with no changes returns 0. So you may be breaking a lot of programs here, unless I'm mistaken. > + > + /* Denies privileged changes. */ > + if (changed & ~unpriv_and_locks) > + return -EPERM; > + } > + > new = prepare_creds(); > if (!new) > return -ENOMEM; > -- > 2.46.1
On Sat, Oct 12, 2024 at 09:51:50PM -0500, Serge E. Hallyn wrote: > On Fri, Oct 11, 2024 at 08:44:18PM +0200, Mickaël Salaün wrote: > > The new SECBIT_EXEC_RESTRICT_FILE, SECBIT_EXEC_DENY_INTERACTIVE, and > > their *_LOCKED counterparts are designed to be set by processes setting > > up an execution environment, such as a user session, a container, or a > > security sandbox. Unlike other securebits, these ones can be set by > > unprivileged processes. Like seccomp filters or Landlock domains, the > > securebits are inherited across processes. > > > > When SECBIT_EXEC_RESTRICT_FILE is set, programs interpreting code should > > control executable resources according to execveat(2) + AT_CHECK (see > > previous commit). > > > > When SECBIT_EXEC_DENY_INTERACTIVE is set, a process should deny > > execution of user interactive commands (which excludes executable > > regular files). > > > > Being able to configure each of these securebits enables system > > administrators or owner of image containers to gradually validate the > > related changes and to identify potential issues (e.g. with interpreter > > or audit logs). > > > > It should be noted that unlike other security bits, the > > SECBIT_EXEC_RESTRICT_FILE and SECBIT_EXEC_DENY_INTERACTIVE bits are > > dedicated to user space willing to restrict itself. Because of that, > > they only make sense in the context of a trusted environment (e.g. > > sandbox, container, user session, full system) where the process > > changing its behavior (according to these bits) and all its parent > > processes are trusted. Otherwise, any parent process could just execute > > its own malicious code (interpreting a script or not), or even enforce a > > seccomp filter to mask these bits. > > > > Such a secure environment can be achieved with an appropriate access > > control (e.g. mount's noexec option, file access rights, LSM policy) and > > an enlighten ld.so checking that libraries are allowed for execution > > e.g., to protect against illegitimate use of LD_PRELOAD. > > > > Ptrace restrictions according to these securebits would not make sense > > because of the processes' trust assumption. > > > > Scripts may need some changes to deal with untrusted data (e.g. stdin, > > environment variables), but that is outside the scope of the kernel. > > > > See chromeOS's documentation about script execution control and the > > related threat model: > > https://www.chromium.org/chromium-os/developer-library/guides/security/noexec-shell-scripts/ > > > > Cc: Al Viro <viro@zeniv.linux.org.uk> > > Cc: Andy Lutomirski <luto@amacapital.net> > > Cc: Christian Brauner <brauner@kernel.org> > > Cc: Kees Cook <keescook@chromium.org> > > Cc: Paul Moore <paul@paul-moore.com> > > Cc: Serge Hallyn <serge@hallyn.com> > > Signed-off-by: Mickaël Salaün <mic@digikod.net> > > Link: https://lore.kernel.org/r/20241011184422.977903-3-mic@digikod.net > > --- > > > > Changes since v19: > > * Replace SECBIT_SHOULD_EXEC_CHECK and SECBIT_SHOULD_EXEC_RESTRICT with > > SECBIT_EXEC_RESTRICT_FILE and SECBIT_EXEC_DENY_INTERACTIVE: > > https://lore.kernel.org/all/20240710.eiKohpa4Phai@digikod.net/ > > * Remove the ptrace restrictions, suggested by Andy. > > * Improve documentation according to the discussion with Jeff. > > > > New design since v18: > > https://lore.kernel.org/r/20220104155024.48023-3-mic@digikod.net > > --- > > include/uapi/linux/securebits.h | 113 +++++++++++++++++++++++++++++++- > > security/commoncap.c | 29 ++++++-- > > 2 files changed, 135 insertions(+), 7 deletions(-) > > > > diff --git a/include/uapi/linux/securebits.h b/include/uapi/linux/securebits.h > > index d6d98877ff1a..351b6ecefc76 100644 > > --- a/include/uapi/linux/securebits.h > > +++ b/include/uapi/linux/securebits.h > > @@ -52,10 +52,121 @@ > > #define SECBIT_NO_CAP_AMBIENT_RAISE_LOCKED \ > > (issecure_mask(SECURE_NO_CAP_AMBIENT_RAISE_LOCKED)) > > > > +/* > > + * The SECBIT_EXEC_RESTRICT_FILE and SECBIT_EXEC_DENY_INTERACTIVE securebits > > + * are intended for script interpreters and dynamic linkers to enforce a > > + * consistent execution security policy handled by the kernel. > > + * > > + * Whether an interpreter should check these securebits or not depends on the > > + * security risk of running malicious scripts with respect to the execution > > + * environment, and whether the kernel can check if a script is trustworthy or > > + * not. For instance, Python scripts running on a server can use arbitrary > > + * syscalls and access arbitrary files. Such interpreters should then be > > + * enlighten to use these securebits and let users define their security > > + * policy. However, a JavaScript engine running in a web browser should > > + * already be sandboxed and then should not be able to harm the user's > > + * environment. > > + * > > + * When SECBIT_EXEC_RESTRICT_FILE is set, a process should only interpret or > > + * execute a file if a call to execveat(2) with the related file descriptor and > > + * the AT_CHECK flag succeed. > > + * > > + * This secure bit may be set by user session managers, service managers, > > + * container runtimes, sandboxer tools... Except for test environments, the > > + * related SECBIT_EXEC_RESTRICT_FILE_LOCKED bit should also be set. > > + * > > + * Programs should only enforce consistent restrictions according to the > > + * securebits but without relying on any other user-controlled configuration. > > + * Indeed, the use case for these securebits is to only trust executable code > > + * vetted by the system configuration (through the kernel), so we should be > > + * careful to not let untrusted users control this configuration. > > + * > > + * However, script interpreters may still use user configuration such as > > + * environment variables as long as it is not a way to disable the securebits > > + * checks. For instance, the PATH and LD_PRELOAD variables can be set by a > > + * script's caller. Changing these variables may lead to unintended code > > + * executions, but only from vetted executable programs, which is OK. For this > > + * to make sense, the system should provide a consistent security policy to > > + * avoid arbitrary code execution e.g., by enforcing a write xor execute > > + * policy. > > + * > > + * SECBIT_EXEC_RESTRICT_FILE is complementary and should also be checked. > > + */ > > +#define SECURE_EXEC_RESTRICT_FILE 8 > > +#define SECURE_EXEC_RESTRICT_FILE_LOCKED 9 /* make bit-8 immutable */ > > + > > +#define SECBIT_EXEC_RESTRICT_FILE (issecure_mask(SECURE_EXEC_RESTRICT_FILE)) > > +#define SECBIT_EXEC_RESTRICT_FILE_LOCKED \ > > + (issecure_mask(SECURE_EXEC_RESTRICT_FILE_LOCKED)) > > + > > +/* > > + * When SECBIT_EXEC_DENY_INTERACTIVE is set, a process should never interpret > > + * interactive user commands (e.g. scripts). However, if such commands are > > + * passed through a file descriptor (e.g. stdin), its content should be > > + * interpreted if a call to execveat(2) with the related file descriptor and > > + * the AT_CHECK flag succeed. > > + * > > + * For instance, script interpreters called with a script snippet as argument > > + * should always deny such execution if SECBIT_EXEC_DENY_INTERACTIVE is set. > > + * > > + * This secure bit may be set by user session managers, service managers, > > + * container runtimes, sandboxer tools... Except for test environments, the > > + * related SECBIT_EXEC_DENY_INTERACTIVE_LOCKED bit should also be set. > > + * > > + * See the SECBIT_EXEC_RESTRICT_FILE documentation. > > + * > > + * Here is the expected behavior for a script interpreter according to > > + * combination of any exec securebits: > > + * > > + * 1. SECURE_EXEC_RESTRICT_FILE=0 SECURE_EXEC_DENY_INTERACTIVE=0 (default) > > + * Always interpret scripts, and allow arbitrary user commands. > > + * => No threat, everyone and everything is trusted, but we can get ahead of > > + * potential issues thanks to the call to execveat with AT_CHECK which > > + * should always be performed but ignored by the script interpreter. > > + * Indeed, this check is still important to enable systems administrators > > + * to verify requests (e.g. with audit) and prepare for migration to a > > + * secure mode. > > + * > > + * 2. SECURE_EXEC_RESTRICT_FILE=1 SECURE_EXEC_DENY_INTERACTIVE=0 > > + * Deny script interpretation if they are not executable, but allow > > + * arbitrary user commands. > > + * => The threat is (potential) malicious scripts run by trusted (and not > > + * fooled) users. That can protect against unintended script executions > > + * (e.g. sh /tmp/*.sh). This makes sense for (semi-restricted) user > > + * sessions. > > + * > > + * 3. SECURE_EXEC_RESTRICT_FILE=0 SECURE_EXEC_DENY_INTERACTIVE=1 > > + * Always interpret scripts, but deny arbitrary user commands. > > + * => This use case may be useful for secure services (i.e. without > > + * interactive user session) where scripts' integrity is verified (e.g. > > + * with IMA/EVM or dm-verity/IPE) but where access rights might not be > > + * ready yet. Indeed, arbitrary interactive commands would be much more > > + * difficult to check. > > + * > > + * 4. SECURE_EXEC_RESTRICT_FILE=1 SECURE_EXEC_DENY_INTERACTIVE=1 > > + * Deny script interpretation if they are not executable, and also deny > > + * any arbitrary user commands. > > + * => The threat is malicious scripts run by untrusted users (but trusted > > + * code). This makes sense for system services that may only execute > > + * trusted scripts. > > + */ > > +#define SECURE_EXEC_DENY_INTERACTIVE 10 > > +#define SECURE_EXEC_DENY_INTERACTIVE_LOCKED 11 /* make bit-10 immutable */ > > + > > +#define SECBIT_EXEC_DENY_INTERACTIVE \ > > + (issecure_mask(SECURE_EXEC_DENY_INTERACTIVE)) > > +#define SECBIT_EXEC_DENY_INTERACTIVE_LOCKED \ > > + (issecure_mask(SECURE_EXEC_DENY_INTERACTIVE_LOCKED)) > > + > > #define SECURE_ALL_BITS (issecure_mask(SECURE_NOROOT) | \ > > issecure_mask(SECURE_NO_SETUID_FIXUP) | \ > > issecure_mask(SECURE_KEEP_CAPS) | \ > > - issecure_mask(SECURE_NO_CAP_AMBIENT_RAISE)) > > + issecure_mask(SECURE_NO_CAP_AMBIENT_RAISE) | \ > > + issecure_mask(SECURE_EXEC_RESTRICT_FILE) | \ > > + issecure_mask(SECURE_EXEC_DENY_INTERACTIVE)) > > #define SECURE_ALL_LOCKS (SECURE_ALL_BITS << 1) > > > > +#define SECURE_ALL_UNPRIVILEGED (issecure_mask(SECURE_EXEC_RESTRICT_FILE) | \ > > + issecure_mask(SECURE_EXEC_DENY_INTERACTIVE)) > > + > > #endif /* _UAPI_LINUX_SECUREBITS_H */ > > diff --git a/security/commoncap.c b/security/commoncap.c > > index cefad323a0b1..52ea01acb453 100644 > > --- a/security/commoncap.c > > +++ b/security/commoncap.c > > @@ -1302,21 +1302,38 @@ int cap_task_prctl(int option, unsigned long arg2, unsigned long arg3, > > & (old->securebits ^ arg2)) /*[1]*/ > > || ((old->securebits & SECURE_ALL_LOCKS & ~arg2)) /*[2]*/ > > || (arg2 & ~(SECURE_ALL_LOCKS | SECURE_ALL_BITS)) /*[3]*/ > > - || (cap_capable(current_cred(), > > - current_cred()->user_ns, > > - CAP_SETPCAP, > > - CAP_OPT_NONE) != 0) /*[4]*/ > > /* > > * [1] no changing of bits that are locked > > * [2] no unlocking of locks > > * [3] no setting of unsupported bits > > - * [4] doing anything requires privilege (go read about > > - * the "sendmail capabilities bug") > > */ > > ) > > /* cannot change a locked bit */ > > return -EPERM; > > > > + /* > > + * Doing anything requires privilege (go read about the > > + * "sendmail capabilities bug"), except for unprivileged bits. > > + * Indeed, the SECURE_ALL_UNPRIVILEGED bits are not > > + * restrictions enforced by the kernel but by user space on > > + * itself. > > + */ > > + if (cap_capable(current_cred(), current_cred()->user_ns, > > + CAP_SETPCAP, CAP_OPT_NONE) != 0) { > > + const unsigned long unpriv_and_locks = > > + SECURE_ALL_UNPRIVILEGED | > > + SECURE_ALL_UNPRIVILEGED << 1; > > + const unsigned long changed = old->securebits ^ arg2; > > + > > + /* For legacy reason, denies non-change. */ > > + if (!changed) > > + return -EPERM; > > This is odd to me. You say for legacy reasons, but, currently, calling > PR_SET_SECUREBITS with no changes returns 0. So you may be breaking > a lot of programs here, unless I'm mistaken. When we call PR_SET_SECUREBITS with 0 (and if it was 0 too), it currently goes through the capability check and return -EPERM if the caller doesn't have CAP_SETCAP. This is tested with TEST_F(secbits, legacy) in tools/testing/selftests/exec/check-exec.c (patch 3/6). > > > + > > + /* Denies privileged changes. */ > > + if (changed & ~unpriv_and_locks) > > + return -EPERM; > > + } > > + > > new = prepare_creds(); > > if (!new) > > return -ENOMEM; > > -- > > 2.46.1 >
On Mon, Oct 14, 2024 at 09:40:34AM +0200, Mickaël Salaün wrote: > On Sat, Oct 12, 2024 at 09:51:50PM -0500, Serge E. Hallyn wrote: > > On Fri, Oct 11, 2024 at 08:44:18PM +0200, Mickaël Salaün wrote: > > > The new SECBIT_EXEC_RESTRICT_FILE, SECBIT_EXEC_DENY_INTERACTIVE, and > > > their *_LOCKED counterparts are designed to be set by processes setting > > > up an execution environment, such as a user session, a container, or a > > > security sandbox. Unlike other securebits, these ones can be set by > > > unprivileged processes. Like seccomp filters or Landlock domains, the > > > securebits are inherited across processes. > > > > > > When SECBIT_EXEC_RESTRICT_FILE is set, programs interpreting code should > > > control executable resources according to execveat(2) + AT_CHECK (see > > > previous commit). > > > > > > When SECBIT_EXEC_DENY_INTERACTIVE is set, a process should deny > > > execution of user interactive commands (which excludes executable > > > regular files). > > > > > > Being able to configure each of these securebits enables system > > > administrators or owner of image containers to gradually validate the > > > related changes and to identify potential issues (e.g. with interpreter > > > or audit logs). > > > > > > It should be noted that unlike other security bits, the > > > SECBIT_EXEC_RESTRICT_FILE and SECBIT_EXEC_DENY_INTERACTIVE bits are > > > dedicated to user space willing to restrict itself. Because of that, > > > they only make sense in the context of a trusted environment (e.g. > > > sandbox, container, user session, full system) where the process > > > changing its behavior (according to these bits) and all its parent > > > processes are trusted. Otherwise, any parent process could just execute > > > its own malicious code (interpreting a script or not), or even enforce a > > > seccomp filter to mask these bits. > > > > > > Such a secure environment can be achieved with an appropriate access > > > control (e.g. mount's noexec option, file access rights, LSM policy) and > > > an enlighten ld.so checking that libraries are allowed for execution > > > e.g., to protect against illegitimate use of LD_PRELOAD. > > > > > > Ptrace restrictions according to these securebits would not make sense > > > because of the processes' trust assumption. > > > > > > Scripts may need some changes to deal with untrusted data (e.g. stdin, > > > environment variables), but that is outside the scope of the kernel. > > > > > > See chromeOS's documentation about script execution control and the > > > related threat model: > > > https://www.chromium.org/chromium-os/developer-library/guides/security/noexec-shell-scripts/ > > > > > > Cc: Al Viro <viro@zeniv.linux.org.uk> > > > Cc: Andy Lutomirski <luto@amacapital.net> > > > Cc: Christian Brauner <brauner@kernel.org> > > > Cc: Kees Cook <keescook@chromium.org> > > > Cc: Paul Moore <paul@paul-moore.com> > > > Cc: Serge Hallyn <serge@hallyn.com> > > > Signed-off-by: Mickaël Salaün <mic@digikod.net> > > > Link: https://lore.kernel.org/r/20241011184422.977903-3-mic@digikod.net > > > --- > > > > > > Changes since v19: > > > * Replace SECBIT_SHOULD_EXEC_CHECK and SECBIT_SHOULD_EXEC_RESTRICT with > > > SECBIT_EXEC_RESTRICT_FILE and SECBIT_EXEC_DENY_INTERACTIVE: > > > https://lore.kernel.org/all/20240710.eiKohpa4Phai@digikod.net/ > > > * Remove the ptrace restrictions, suggested by Andy. > > > * Improve documentation according to the discussion with Jeff. > > > > > > New design since v18: > > > https://lore.kernel.org/r/20220104155024.48023-3-mic@digikod.net > > > --- > > > include/uapi/linux/securebits.h | 113 +++++++++++++++++++++++++++++++- > > > security/commoncap.c | 29 ++++++-- > > > 2 files changed, 135 insertions(+), 7 deletions(-) > > > > > > diff --git a/include/uapi/linux/securebits.h b/include/uapi/linux/securebits.h > > > index d6d98877ff1a..351b6ecefc76 100644 > > > --- a/include/uapi/linux/securebits.h > > > +++ b/include/uapi/linux/securebits.h > > > @@ -52,10 +52,121 @@ > > > #define SECBIT_NO_CAP_AMBIENT_RAISE_LOCKED \ > > > (issecure_mask(SECURE_NO_CAP_AMBIENT_RAISE_LOCKED)) > > > > > > +/* > > > + * The SECBIT_EXEC_RESTRICT_FILE and SECBIT_EXEC_DENY_INTERACTIVE securebits > > > + * are intended for script interpreters and dynamic linkers to enforce a > > > + * consistent execution security policy handled by the kernel. > > > + * > > > + * Whether an interpreter should check these securebits or not depends on the > > > + * security risk of running malicious scripts with respect to the execution > > > + * environment, and whether the kernel can check if a script is trustworthy or > > > + * not. For instance, Python scripts running on a server can use arbitrary > > > + * syscalls and access arbitrary files. Such interpreters should then be > > > + * enlighten to use these securebits and let users define their security > > > + * policy. However, a JavaScript engine running in a web browser should > > > + * already be sandboxed and then should not be able to harm the user's > > > + * environment. > > > + * > > > + * When SECBIT_EXEC_RESTRICT_FILE is set, a process should only interpret or > > > + * execute a file if a call to execveat(2) with the related file descriptor and > > > + * the AT_CHECK flag succeed. > > > + * > > > + * This secure bit may be set by user session managers, service managers, > > > + * container runtimes, sandboxer tools... Except for test environments, the > > > + * related SECBIT_EXEC_RESTRICT_FILE_LOCKED bit should also be set. > > > + * > > > + * Programs should only enforce consistent restrictions according to the > > > + * securebits but without relying on any other user-controlled configuration. > > > + * Indeed, the use case for these securebits is to only trust executable code > > > + * vetted by the system configuration (through the kernel), so we should be > > > + * careful to not let untrusted users control this configuration. > > > + * > > > + * However, script interpreters may still use user configuration such as > > > + * environment variables as long as it is not a way to disable the securebits > > > + * checks. For instance, the PATH and LD_PRELOAD variables can be set by a > > > + * script's caller. Changing these variables may lead to unintended code > > > + * executions, but only from vetted executable programs, which is OK. For this > > > + * to make sense, the system should provide a consistent security policy to > > > + * avoid arbitrary code execution e.g., by enforcing a write xor execute > > > + * policy. > > > + * > > > + * SECBIT_EXEC_RESTRICT_FILE is complementary and should also be checked. > > > + */ > > > +#define SECURE_EXEC_RESTRICT_FILE 8 > > > +#define SECURE_EXEC_RESTRICT_FILE_LOCKED 9 /* make bit-8 immutable */ > > > + > > > +#define SECBIT_EXEC_RESTRICT_FILE (issecure_mask(SECURE_EXEC_RESTRICT_FILE)) > > > +#define SECBIT_EXEC_RESTRICT_FILE_LOCKED \ > > > + (issecure_mask(SECURE_EXEC_RESTRICT_FILE_LOCKED)) > > > + > > > +/* > > > + * When SECBIT_EXEC_DENY_INTERACTIVE is set, a process should never interpret > > > + * interactive user commands (e.g. scripts). However, if such commands are > > > + * passed through a file descriptor (e.g. stdin), its content should be > > > + * interpreted if a call to execveat(2) with the related file descriptor and > > > + * the AT_CHECK flag succeed. > > > + * > > > + * For instance, script interpreters called with a script snippet as argument > > > + * should always deny such execution if SECBIT_EXEC_DENY_INTERACTIVE is set. > > > + * > > > + * This secure bit may be set by user session managers, service managers, > > > + * container runtimes, sandboxer tools... Except for test environments, the > > > + * related SECBIT_EXEC_DENY_INTERACTIVE_LOCKED bit should also be set. > > > + * > > > + * See the SECBIT_EXEC_RESTRICT_FILE documentation. > > > + * > > > + * Here is the expected behavior for a script interpreter according to > > > + * combination of any exec securebits: > > > + * > > > + * 1. SECURE_EXEC_RESTRICT_FILE=0 SECURE_EXEC_DENY_INTERACTIVE=0 (default) > > > + * Always interpret scripts, and allow arbitrary user commands. > > > + * => No threat, everyone and everything is trusted, but we can get ahead of > > > + * potential issues thanks to the call to execveat with AT_CHECK which > > > + * should always be performed but ignored by the script interpreter. > > > + * Indeed, this check is still important to enable systems administrators > > > + * to verify requests (e.g. with audit) and prepare for migration to a > > > + * secure mode. > > > + * > > > + * 2. SECURE_EXEC_RESTRICT_FILE=1 SECURE_EXEC_DENY_INTERACTIVE=0 > > > + * Deny script interpretation if they are not executable, but allow > > > + * arbitrary user commands. > > > + * => The threat is (potential) malicious scripts run by trusted (and not > > > + * fooled) users. That can protect against unintended script executions > > > + * (e.g. sh /tmp/*.sh). This makes sense for (semi-restricted) user > > > + * sessions. > > > + * > > > + * 3. SECURE_EXEC_RESTRICT_FILE=0 SECURE_EXEC_DENY_INTERACTIVE=1 > > > + * Always interpret scripts, but deny arbitrary user commands. > > > + * => This use case may be useful for secure services (i.e. without > > > + * interactive user session) where scripts' integrity is verified (e.g. > > > + * with IMA/EVM or dm-verity/IPE) but where access rights might not be > > > + * ready yet. Indeed, arbitrary interactive commands would be much more > > > + * difficult to check. > > > + * > > > + * 4. SECURE_EXEC_RESTRICT_FILE=1 SECURE_EXEC_DENY_INTERACTIVE=1 > > > + * Deny script interpretation if they are not executable, and also deny > > > + * any arbitrary user commands. > > > + * => The threat is malicious scripts run by untrusted users (but trusted > > > + * code). This makes sense for system services that may only execute > > > + * trusted scripts. > > > + */ > > > +#define SECURE_EXEC_DENY_INTERACTIVE 10 > > > +#define SECURE_EXEC_DENY_INTERACTIVE_LOCKED 11 /* make bit-10 immutable */ > > > + > > > +#define SECBIT_EXEC_DENY_INTERACTIVE \ > > > + (issecure_mask(SECURE_EXEC_DENY_INTERACTIVE)) > > > +#define SECBIT_EXEC_DENY_INTERACTIVE_LOCKED \ > > > + (issecure_mask(SECURE_EXEC_DENY_INTERACTIVE_LOCKED)) > > > + > > > #define SECURE_ALL_BITS (issecure_mask(SECURE_NOROOT) | \ > > > issecure_mask(SECURE_NO_SETUID_FIXUP) | \ > > > issecure_mask(SECURE_KEEP_CAPS) | \ > > > - issecure_mask(SECURE_NO_CAP_AMBIENT_RAISE)) > > > + issecure_mask(SECURE_NO_CAP_AMBIENT_RAISE) | \ > > > + issecure_mask(SECURE_EXEC_RESTRICT_FILE) | \ > > > + issecure_mask(SECURE_EXEC_DENY_INTERACTIVE)) > > > #define SECURE_ALL_LOCKS (SECURE_ALL_BITS << 1) > > > > > > +#define SECURE_ALL_UNPRIVILEGED (issecure_mask(SECURE_EXEC_RESTRICT_FILE) | \ > > > + issecure_mask(SECURE_EXEC_DENY_INTERACTIVE)) > > > + > > > #endif /* _UAPI_LINUX_SECUREBITS_H */ > > > diff --git a/security/commoncap.c b/security/commoncap.c > > > index cefad323a0b1..52ea01acb453 100644 > > > --- a/security/commoncap.c > > > +++ b/security/commoncap.c > > > @@ -1302,21 +1302,38 @@ int cap_task_prctl(int option, unsigned long arg2, unsigned long arg3, > > > & (old->securebits ^ arg2)) /*[1]*/ > > > || ((old->securebits & SECURE_ALL_LOCKS & ~arg2)) /*[2]*/ > > > || (arg2 & ~(SECURE_ALL_LOCKS | SECURE_ALL_BITS)) /*[3]*/ > > > - || (cap_capable(current_cred(), > > > - current_cred()->user_ns, > > > - CAP_SETPCAP, > > > - CAP_OPT_NONE) != 0) /*[4]*/ > > > /* > > > * [1] no changing of bits that are locked > > > * [2] no unlocking of locks > > > * [3] no setting of unsupported bits > > > - * [4] doing anything requires privilege (go read about > > > - * the "sendmail capabilities bug") > > > */ > > > ) > > > /* cannot change a locked bit */ > > > return -EPERM; > > > > > > + /* > > > + * Doing anything requires privilege (go read about the > > > + * "sendmail capabilities bug"), except for unprivileged bits. > > > + * Indeed, the SECURE_ALL_UNPRIVILEGED bits are not > > > + * restrictions enforced by the kernel but by user space on > > > + * itself. > > > + */ > > > + if (cap_capable(current_cred(), current_cred()->user_ns, > > > + CAP_SETPCAP, CAP_OPT_NONE) != 0) { > > > + const unsigned long unpriv_and_locks = > > > + SECURE_ALL_UNPRIVILEGED | > > > + SECURE_ALL_UNPRIVILEGED << 1; > > > + const unsigned long changed = old->securebits ^ arg2; > > > + > > > + /* For legacy reason, denies non-change. */ > > > + if (!changed) > > > + return -EPERM; > > > > This is odd to me. You say for legacy reasons, but, currently, calling > > PR_SET_SECUREBITS with no changes returns 0. So you may be breaking > > a lot of programs here, unless I'm mistaken. > > When we call PR_SET_SECUREBITS with 0 (and if it was 0 too), it > currently goes through the capability check and return -EPERM if the > caller doesn't have CAP_SETCAP. This is tested with > TEST_F(secbits, legacy) in tools/testing/selftests/exec/check-exec.c > (patch 3/6). Drat, my manual test case had a typo. Right you are - it fails now. thanks, -serge
© 2016 - 2024 Red Hat, Inc.