Hi,
This seventh patch series do not set __FMODE_EXEC for the sake of
simplicity. A notification feature could be added later if needed. The
handling of all file types is now well defined and tested: by default,
when opening a path, access to a directory is denied (with EISDIR),
access to a regular file depends on the sysctl policy, and access to
other file types (i.e. fifo, device, socket) is denied if there is any
enforced policy. There is new tests covering all these cases (cf.
test_file_types() ).
As requested by Mimi Zohar, I completed the series with one of her
patches for IMA. I also picked Kees Cook's patches to consolidate exec
permission checking into do_filp_open()'s flow.
# Goal of O_MAYEXEC
The goal of this patch series is to enable to control script execution
with interpreters help. A new O_MAYEXEC flag, usable through
openat2(2), is added to enable userspace script interpreters to delegate
to the kernel (and thus the system security policy) the permission to
interpret/execute scripts or other files containing what can be seen as
commands.
A simple system-wide security policy can be enforced by the system
administrator through a sysctl configuration consistent with the mount
points or the file access rights. The documentation patch explains the
prerequisites.
Furthermore, the security policy can also be delegated to an LSM, either
a MAC system or an integrity system. For instance, the new kernel
MAY_OPENEXEC flag closes a major IMA measurement/appraisal interpreter
integrity gap by bringing the ability to check the use of scripts [1].
Other uses are expected, such as for magic-links [2], SGX integration
[3], bpffs [4] or IPE [5].
# Prerequisite of its use
Userspace needs to adapt to take advantage of this new feature. For
example, the PEP 578 [6] (Runtime Audit Hooks) enables Python 3.8 to be
extended with policy enforcement points related to code interpretation,
which can be used to align with the PowerShell audit features.
Additional Python security improvements (e.g. a limited interpreter
withou -c, stdin piping of code) are on their way [7].
# Examples
The initial idea comes from CLIP OS 4 and the original implementation
has been used for more than 12 years:
https://github.com/clipos-archive/clipos4_doc
Chrome OS has a similar approach:
https://chromium.googlesource.com/chromiumos/docs/+/master/security/noexec_shell_scripts.md
Userland patches can be found here:
https://github.com/clipos-archive/clipos4_portage-overlay/search?q=O_MAYEXEC
Actually, there is more than the O_MAYEXEC changes (which matches this search)
e.g., to prevent Python interactive execution. There are patches for
Bash, Wine, Java (Icedtea), Busybox's ash, Perl and Python. There are
also some related patches which do not directly rely on O_MAYEXEC but
which restrict the use of browser plugins and extensions, which may be
seen as scripts too:
https://github.com/clipos-archive/clipos4_portage-overlay/tree/master/www-client
An introduction to O_MAYEXEC was given at the Linux Security Summit
Europe 2018 - Linux Kernel Security Contributions by ANSSI:
https://www.youtube.com/watch?v=chNjCRtPKQY&t=17m15s
The "write xor execute" principle was explained at Kernel Recipes 2018 -
CLIP OS: a defense-in-depth OS:
https://www.youtube.com/watch?v=PjRE0uBtkHU&t=11m14s
See also an overview article: https://lwn.net/Articles/820000/
This patch series can be applied on top of v5.8-rc5 . This can be tested
with CONFIG_SYSCTL. I would really appreciate constructive comments on
this patch series.
Previous version:
https://lore.kernel.org/lkml/20200505153156.925111-1-mic@digikod.net/
[1] https://lore.kernel.org/lkml/1544647356.4028.105.camel@linux.ibm.com/
[2] https://lore.kernel.org/lkml/20190904201933.10736-6-cyphar@cyphar.com/
[3] https://lore.kernel.org/lkml/CALCETrVovr8XNZSroey7pHF46O=kj_c5D9K8h=z2T_cNrpvMig@mail.gmail.com/
[4] https://lore.kernel.org/lkml/CALCETrVeZ0eufFXwfhtaG_j+AdvbzEWE0M3wjXMWVEO7pj+xkw@mail.gmail.com/
[5] https://lore.kernel.org/lkml/20200406221439.1469862-12-deven.desai@linux.microsoft.com/
[6] https://www.python.org/dev/peps/pep-0578/
[7] https://lore.kernel.org/lkml/0c70debd-e79e-d514-06c6-4cd1e021fa8b@python.org/
Regards,
Kees Cook (3):
exec: Change uselib(2) IS_SREG() failure to EACCES
exec: Move S_ISREG() check earlier
exec: Move path_noexec() check earlier
Mickaël Salaün (3):
fs: Introduce O_MAYEXEC flag for openat2(2)
fs,doc: Enable to enforce noexec mounts or file exec through O_MAYEXEC
selftest/openat2: Add tests for O_MAYEXEC enforcing
Mimi Zohar (1):
ima: add policy support for the new file open MAY_OPENEXEC flag
Documentation/ABI/testing/ima_policy | 2 +-
Documentation/admin-guide/sysctl/fs.rst | 49 +++
fs/exec.c | 23 +-
fs/fcntl.c | 2 +-
fs/namei.c | 36 +-
fs/open.c | 12 +-
include/linux/fcntl.h | 2 +-
include/linux/fs.h | 3 +
include/uapi/asm-generic/fcntl.h | 7 +
kernel/sysctl.c | 12 +-
security/integrity/ima/ima_main.c | 3 +-
security/integrity/ima/ima_policy.c | 15 +-
tools/testing/selftests/kselftest_harness.h | 3 +
tools/testing/selftests/openat2/Makefile | 3 +-
tools/testing/selftests/openat2/config | 1 +
tools/testing/selftests/openat2/helpers.h | 1 +
.../testing/selftests/openat2/omayexec_test.c | 325 ++++++++++++++++++
17 files changed, 470 insertions(+), 29 deletions(-)
create mode 100644 tools/testing/selftests/openat2/config
create mode 100644 tools/testing/selftests/openat2/omayexec_test.c
--
2.27.0
When the O_MAYEXEC flag is passed, openat2(2) may be subject to
additional restrictions depending on a security policy managed by the
kernel through a sysctl or implemented by an LSM thanks to the
inode_permission hook. This new flag is ignored by open(2) and
openat(2) because of their unspecified flags handling. When used with
openat2(2), the default behavior is only to forbid to open a directory.
The underlying idea is to be able to restrict scripts interpretation
according to a policy defined by the system administrator. For this to
be possible, script interpreters must use the O_MAYEXEC flag
appropriately. To be fully effective, these interpreters also need to
handle the other ways to execute code: command line parameters (e.g.,
option -e for Perl), module loading (e.g., option -m for Python), stdin,
file sourcing, environment variables, configuration files, etc.
According to the threat model, it may be acceptable to allow some script
interpreters (e.g. Bash) to interpret commands from stdin, may it be a
TTY or a pipe, because it may not be enough to (directly) perform
syscalls. Further documentation can be found in a following patch.
Even without enforced security policy, userland interpreters can set it
to enforce the system policy at their level, knowing that it will not
break anything on running systems which do not care about this feature.
However, on systems which want this feature enforced, there will be
knowledgeable people (i.e. sysadmins who enforced O_MAYEXEC
deliberately) to manage it. A simple security policy implementation,
configured through a dedicated sysctl, is available in a following
patch.
O_MAYEXEC should not be confused with the O_EXEC flag which is intended
for execute-only, which obviously doesn't work for scripts. However, a
similar behavior could be implemented in userland with O_PATH:
https://lore.kernel.org/lkml/1e2f6913-42f2-3578-28ed-567f6a4bdda1@digikod.net/
The implementation of O_MAYEXEC almost duplicates what execve(2) and
uselib(2) are already doing: setting MAY_OPENEXEC in acc_mode (which can
then be checked as MAY_EXEC, if enforced).
This is an updated subset of the patch initially written by Vincent
Strubel for CLIP OS 4:
https://github.com/clipos-archive/src_platform_clip-patches/blob/f5cb330d6b684752e403b4e41b39f7004d88e561/1901_open_mayexec.patch
This patch has been used for more than 12 years with customized script
interpreters. Some examples (with the original O_MAYEXEC) can be found
here:
https://github.com/clipos-archive/clipos4_portage-overlay/search?q=O_MAYEXEC
Co-developed-by: Vincent Strubel <redacted>
Signed-off-by: Vincent Strubel <redacted>
Co-developed-by: Thibaut Sautereau <redacted>
Signed-off-by: Thibaut Sautereau <redacted>
Signed-off-by: Mickaël Salaün <mic@digikod.net>
Cc: Aleksa Sarai <redacted>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: Deven Bowers <redacted>
Cc: Kees Cook <redacted>
---
Changes since v6:
* Do not set __FMODE_EXEC for now because of inconsistent behavior:
https://lore.kernel.org/lkml/202007160822.CCDB5478@keescook/
* Returns EISDIR when opening a directory with O_MAYEXEC.
* Removed Deven Bowers and Kees Cook Reviewed-by tags because of the
current update.
Changes since v5:
* Update commit message.
Changes since v3:
* Switch back to O_MAYEXEC, but only handle it with openat2(2) which
checks unknown flags (suggested by Aleksa Sarai). Cf.
https://lore.kernel.org/lkml/20200430015429.wuob7m5ofdewubui@yavin.dot.cyphar.com/
Changes since v2:
* Replace O_MAYEXEC with RESOLVE_MAYEXEC from openat2(2). This change
enables to not break existing application using bogus O_* flags that
may be ignored by current kernels by using a new dedicated flag, only
usable through openat2(2) (suggested by Jeff Layton). Using this flag
will results in an error if the running kernel does not support it.
User space needs to manage this case, as with other RESOLVE_* flags.
The best effort approach to security (for most common distros) will
simply consists of ignoring such an error and retry without
RESOLVE_MAYEXEC. However, a fully controlled system may which to
error out if such an inconsistency is detected.
Changes since v1:
* Set __FMODE_EXEC when using O_MAYEXEC to make this information
available through the new fanotify/FAN_OPEN_EXEC event (suggested by
Jan Kara and Matthew Bobrowski):
https://lore.kernel.org/lkml/20181213094658.GA996@lithium.mbobrowski.org/
---
fs/fcntl.c | 2 +-
fs/namei.c | 4 ++--
fs/open.c | 6 ++++++
include/linux/fcntl.h | 2 +-
include/linux/fs.h | 2 ++
include/uapi/asm-generic/fcntl.h | 7 +++++++
6 files changed, 19 insertions(+), 4 deletions(-)
@@ -1033,7 +1033,7 @@ static int __init fcntl_init(void)*Exceptions:O_NONBLOCKisatwobitdefineonparisc;O_NDELAY*isdefinedasO_NONBLOCKonsomeplatformsandnotonothers.*/-BUILD_BUG_ON(21-1/* for O_RDONLY being 0 */!=+BUILD_BUG_ON(22-1/* for O_RDONLY being 0 */!=HWEIGHT32((VALID_OPEN_FLAGS&~(O_NONBLOCK|O_NDELAY))|__FMODE_EXEC|__FMODE_NONOTIFY));
@@ -428,7 +428,7 @@ static int sb_permission(struct super_block *sb, struct inode *inode, int mask)/***inode_permission-Checkforaccessrightstoagiveninode*@inode:Inodetocheckpermissionon-*@mask:Righttocheckfor(%MAY_READ,%MAY_WRITE,%MAY_EXEC)+*@mask:Righttocheckfor(%MAY_READ,%MAY_WRITE,%MAY_EXEC,%MAY_OPENEXEC)**Checkforread/write/executepermissionsonaninode.Weusefs[ug]idfor*this,lettingussetarbitrarypermissionsforfilesystemaccesswithout
@@ -2849,7 +2849,7 @@ static int may_open(const struct path *path, int acc_mode, int flag)caseS_IFLNK:return-ELOOP;caseS_IFDIR:-if(acc_mode&(MAY_WRITE|MAY_EXEC))+if(acc_mode&(MAY_WRITE|MAY_EXEC|MAY_OPENEXEC))return-EISDIR;break;caseS_IFBLK:
@@ -10,7 +10,7 @@(O_RDONLY|O_WRONLY|O_RDWR|O_CREAT|O_EXCL|O_NOCTTY|O_TRUNC|\O_APPEND|O_NDELAY|O_NONBLOCK|O_NDELAY|__O_SYNC|O_DSYNC|\FASYNC|O_DIRECT|O_LARGEFILE|O_DIRECTORY|O_NOFOLLOW|\-O_NOATIME|O_CLOEXEC|O_PATH|__O_TMPFILE)+O_NOATIME|O_CLOEXEC|O_PATH|__O_TMPFILE|O_MAYEXEC)/* List of all valid flags for the how->upgrade_mask argument: */#define VALID_UPGRADE_FLAGS \
@@ -101,6 +101,8 @@ typedef int (dio_iodone_t)(struct kiocb *iocb, loff_t offset,#define MAY_CHDIR 0x00000040/* called from RCU mode, don't block */#define MAY_NOT_BLOCK 0x00000080+/* the inode is opened with O_MAYEXEC */+#define MAY_OPENEXEC 0x00000100/**flagsinfile.f_mode.NotethatFMODE_READandFMODE_WRITEmustcorrespond
Allow for the enforcement of the O_MAYEXEC openat2(2) flag. Thanks to
the noexec option from the underlying VFS mount, or to the file execute
permission, userspace can enforce these execution policies. This may
allow script interpreters to check execution permission before reading
commands from a file, or dynamic linkers to allow shared object loading.
Add a new sysctl fs.open_mayexec_enforce to enable system administrators
to enforce two complementary security policies according to the
installed system: enforce the noexec mount option, and enforce
executable file permission. Indeed, because of compatibility with
installed systems, only system administrators are able to check that
this new enforcement is in line with the system mount points and file
permissions. A following patch adds documentation.
Being able to restrict execution also enables to protect the kernel by
restricting arbitrary syscalls that an attacker could perform with a
crafted binary or certain script languages. It also improves multilevel
isolation by reducing the ability of an attacker to use side channels
with specific code. These restrictions can natively be enforced for ELF
binaries (with the noexec mount option) but require this kernel
extension to properly handle scripts (e.g., Python, Perl). To get a
consistent execution policy, additional memory restrictions should also
be enforced (e.g. thanks to SELinux).
Because the O_MAYEXEC flag is a meant to enforce a system-wide security
policy (but not application-centric policies), it does not make sense
for userland to check the sysctl value. Indeed, this new flag only
enables to extend the system ability to enforce a policy thanks to (some
trusted) userland collaboration. Moreover, additional security policies
could be managed by LSMs. This is a best-effort approach from the
application developer point of view:
https://lore.kernel.org/lkml/1477d3d7-4b36-afad-7077-a38f42322238@digikod.net/
Signed-off-by: Mickaël Salaün <mic@digikod.net>
Reviewed-by: Thibaut Sautereau <redacted>
Cc: Aleksa Sarai <redacted>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: Jonathan Corbet <corbet@lwn.net>
Cc: Kees Cook <redacted>
Cc: Randy Dunlap <redacted>
---
Changes since v6:
* Allow opening pipes, block devices and character devices with
O_MAYEXEC when there is no enforced policy, but forbid any non-regular
file opened with O_MAYEXEC otherwise (i.e. for any enforced policy).
* Add a paragraph about the non-regular files policy.
* Move path_noexec() calls out of the fast-path (suggested by Kees
Cook).
Changes since v5:
* Remove the static enforcement configuration through Kconfig because it
makes the code more simple like this, and because the current sysctl
configuration can only be set with CAP_SYS_ADMIN, the same way mount
options (i.e. noexec) can be set. If an harden distro wants to
enforce a configuration, it should restrict capabilities or sysctl
configuration. Furthermore, an LSM can easily leverage O_MAYEXEC to
fit its need.
* Move checks from inode_permission() to may_open() and make the error
codes more consistent according to file types (in line with a previous
commit): opening a directory with O_MAYEXEC returns EISDIR and other
non-regular file types may return EACCES.
* In may_open(), when OMAYEXEC_ENFORCE_FILE is set, replace explicit
call to generic_permission() with an artificial MAY_EXEC to avoid
double calls. This makes sense especially when an LSM policy forbids
execution of a file.
* Replace the custom proc_omayexec() with
proc_dointvec_minmax_sysadmin(), and then replace the CAP_MAC_ADMIN
check with a CAP_SYS_ADMIN one (suggested by Kees Cook and Stephen
Smalley).
* Use BIT() (suggested by Kees Cook).
* Rename variables (suggested by Kees Cook).
* Reword the kconfig help.
* Import the documentation patch (suggested by Kees Cook):
https://lore.kernel.org/lkml/20200505153156.925111-6-mic@digikod.net/
* Update documentation and add LWN.net article.
Changes since v4:
* Add kernel configuration options to enforce O_MAYEXEC at build time,
and disable the sysctl in such case (requested by James Morris).
* Reword commit message.
Changes since v3:
* Update comment with O_MAYEXEC.
Changes since v2:
* Cosmetic changes.
Changes since v1:
* Move code from Yama to the FS subsystem (suggested by Kees Cook).
* Make omayexec_inode_permission() static (suggested by Jann Horn).
* Use mode 0600 for the sysctl.
* Only match regular files (not directories nor other types), which
follows the same semantic as commit 73601ea5b7b1 ("fs/open.c: allow
opening only regular files during execve()").
---
Documentation/admin-guide/sysctl/fs.rst | 49 +++++++++++++++++++++++++
fs/namei.c | 24 ++++++++++++
include/linux/fs.h | 1 +
kernel/sysctl.c | 12 +++++-
4 files changed, 84 insertions(+), 2 deletions(-)
@@ -37,6 +37,7 @@ Currently, these files are in /proc/sys/fs:- inode-nr- inode-state- nr_open+- open_mayexec_enforce- overflowuid- overflowgid- pipe-user-pages-hard
@@ -165,6 +166,54 @@ system needs to prune the inode list instead of allocating more.+open_mayexec_enforce+--------------------++While being ignored by :manpage:`open(2)` and :manpage:`openat(2)`, the+``O_MAYEXEC`` flag can be passed to :manpage:`openat2(2)` to only open regular+files that are expected to be executable. If the file is not identified as+executable, then the syscall returns -EACCES. This may allow a script+interpreter to check executable permission before reading commands from a file,+or a dynamic linker to only load executable shared objects. One interesting+use case is to enforce a "write xor execute" policy through interpreters.++The ability to restrict code execution must be thought as a system-wide policy,+which first starts by restricting mount points with the ``noexec`` option.+This option is also automatically applied to special filesystems such as /proc .+This prevents files on such mount points to be directly executed by the kernel+or mapped as executable memory (e.g. libraries). With script interpreters+using the ``O_MAYEXEC`` flag, the executable permission can then be checked+before reading commands from files. This makes it possible to enforce the+``noexec`` at the interpreter level, and thus propagates this security policy+to scripts. To be fully effective, these interpreters also need to handle the+other ways to execute code: command line parameters (e.g., option ``-e`` for+Perl), module loading (e.g., option ``-m`` for Python), stdin, file sourcing,+environment variables, configuration files, etc. According to the threat+model, it may be acceptable to allow some script interpreters (e.g. Bash) to+interpret commands from stdin, may it be a TTY or a pipe, because it may not be+enough to (directly) perform syscalls.++There are two complementary security policies: enforce the ``noexec`` mount+option, and enforce executable file permission. These policies are handled by+the ``fs.open_mayexec_enforce`` sysctl (writable only with ``CAP_SYS_ADMIN``)+as a bitmask:++1 - Mount restriction: checks that the mount options for the underlying VFS+ mount do not prevent execution.++2 - File permission restriction: checks that the to-be-opened file is marked as+ executable for the current process (e.g., POSIX permissions).++Note that as long as a policy is enforced, opening any non-regular file with+``O_MAYEXEC`` is denied (e.g. TTYs, pipe), even when such a file is marked as+executable or is on an executable mount point.++Code samples can be found in tools/testing/selftests/openat2/omayexec_test.c+and interpreter patches (for the original O_MAYEXEC version) may be found at+https://github.com/clipos-archive/clipos4_portage-overlay/search?q=O_MAYEXEC .+See also an overview article: https://lwn.net/Articles/820000/ .++ overflowgid & overflowuid -------------------------
@@ -425,6 +426,11 @@ static int sb_permission(struct super_block *sb, struct inode *inode, int mask)return0;}+#define OPEN_MAYEXEC_ENFORCE_MOUNT BIT(0)+#define OPEN_MAYEXEC_ENFORCE_FILE BIT(1)++intsysctl_open_mayexec_enforce__read_mostly;+/***inode_permission-Checkforaccessrightstoagiveninode*@inode:Inodetocheckpermissionon
@@ -2861,11 +2867,29 @@ static int may_open(const struct path *path, int acc_mode, int flag)caseS_IFSOCK:if(acc_mode&MAY_EXEC)return-EACCES;+/*+*Openingdevices(e.g.TTYs)orpipeswithO_MAYEXECmaybe+*legitimatewhenthereisnoenforcedpolicy.+*/+if((acc_mode&MAY_OPENEXEC)&&sysctl_open_mayexec_enforce)+return-EACCES;flag&=~O_TRUNC;break;caseS_IFREG:if((acc_mode&MAY_EXEC)&&path_noexec(path))return-EACCES;+if(acc_mode&MAY_OPENEXEC){+if((sysctl_open_mayexec_enforce&OPEN_MAYEXEC_ENFORCE_MOUNT)+&&path_noexec(path))+return-EACCES;+if(sysctl_open_mayexec_enforce&OPEN_MAYEXEC_ENFORCE_FILE)+/*+*Becauseacc_modemaychangehere,thenextandonly+*useofacc_modeshouldthenbebythefollowingcall+*toinode_permission().+*/+acc_mode|=MAY_EXEC;+}break;}
From: Mimi Zohar <zohar@linux.ibm.com>
The kernel has no way of differentiating between a file containing data
or code being opened by an interpreter. The proposed O_MAYEXEC
openat2(2) flag bridges this gap by defining and enabling the
MAY_OPENEXEC flag.
This patch adds IMA policy support for the new MAY_OPENEXEC flag.
Example:
measure func=FILE_CHECK mask=^MAY_OPENEXEC
appraise func=FILE_CHECK appraise_type=imasig mask=^MAY_OPENEXEC
Signed-off-by: Mickaël Salaün <mic@digikod.net>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
Reviewed-by: Lakshmi Ramasubramanian <redacted>
Link: https://lore.kernel.org/r/1588167523-7866-3-git-send-email-zohar@linux.ibm.com
---
Documentation/ABI/testing/ima_policy | 2 +-
security/integrity/ima/ima_main.c | 3 ++-
security/integrity/ima/ima_policy.c | 15 +++++++++++----
3 files changed, 14 insertions(+), 6 deletions(-)
@@ -490,7 +490,8 @@ int ima_file_check(struct file *file, int mask)security_task_getsecid(current,&secid);returnprocess_measurement(file,current_cred(),secid,NULL,0,-mask&(MAY_READ|MAY_WRITE|MAY_EXEC|+mask&(MAY_READ|MAY_WRITE|+MAY_EXEC|MAY_OPENEXEC|MAY_APPEND),FILE_CHECK);}EXPORT_SYMBOL_GPL(ima_file_check);
Test propagation of noexec mount points or file executability through
files open with or without O_MAYEXEC, thanks to the
fs.open_mayexec_enforce sysctl.
Signed-off-by: Mickaël Salaün <mic@digikod.net>
Reviewed-by: Thibaut Sautereau <redacted>
Cc: Aleksa Sarai <redacted>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: Kees Cook <redacted>
Cc: Shuah Khan <shuah@kernel.org>
---
Changes since v6:
* Add full combination tests for all file types, including block
devices, character devices, fifos, sockets and symlinks.
* Properly save and restore initial sysctl value for all tests.
Changes since v5:
* Refactor with FIXTURE_VARIANT, which make the tests much more easy to
read and maintain.
* Save and restore initial sysctl value (suggested by Kees Cook).
* Test with a sysctl value of 0.
* Check errno in sysctl_access_write test.
* Update tests for the CAP_SYS_ADMIN switch.
* Update tests to check -EISDIR (replacing -EACCES).
* Replace FIXTURE_DATA() with FIXTURE() (spotted by Kees Cook).
* Use global const strings.
Changes since v3:
* Replace RESOLVE_MAYEXEC with O_MAYEXEC.
* Add tests to check that O_MAYEXEC is ignored by open(2) and openat(2).
Changes since v2:
* Move tests from exec/ to openat2/ .
* Replace O_MAYEXEC with RESOLVE_MAYEXEC from openat2(2).
* Cleanup tests.
Changes since v1:
* Move tests from yama/ to exec/ .
* Fix _GNU_SOURCE in kselftest_harness.h .
* Add a new test sysctl_access_write to check if CAP_MAC_ADMIN is taken
into account.
* Test directory execution which is always forbidden since commit
73601ea5b7b1 ("fs/open.c: allow opening only regular files during
execve()"), and also check that even the root user can not bypass file
execution checks.
* Make sure delete_workspace() always as enough right to succeed.
* Cosmetic cleanup.
---
tools/testing/selftests/kselftest_harness.h | 3 +
tools/testing/selftests/openat2/Makefile | 3 +-
tools/testing/selftests/openat2/config | 1 +
tools/testing/selftests/openat2/helpers.h | 1 +
.../testing/selftests/openat2/omayexec_test.c | 325 ++++++++++++++++++
5 files changed, 332 insertions(+), 1 deletion(-)
create mode 100644 tools/testing/selftests/openat2/config
create mode 100644 tools/testing/selftests/openat2/omayexec_test.c
From: Kees Cook <redacted>
The path_noexec() check, like the regular file check, was happening too
late, letting LSMs see impossible execve()s. Check it earlier as well
in may_open() and collect the redundant fs/exec.c path_noexec() test
under the same robustness comment as the S_ISREG() check.
My notes on the call path, and related arguments, checks, etc:
do_open_execat()
struct open_flags open_exec_flags = {
.open_flag = O_LARGEFILE | O_RDONLY | __FMODE_EXEC,
.acc_mode = MAY_EXEC,
...
do_filp_open(dfd, filename, open_flags)
path_openat(nameidata, open_flags, flags)
file = alloc_empty_file(open_flags, current_cred());
do_open(nameidata, file, open_flags)
may_open(path, acc_mode, open_flag)
/* new location of MAY_EXEC vs path_noexec() test */
inode_permission(inode, MAY_OPEN | acc_mode)
security_inode_permission(inode, acc_mode)
vfs_open(path, file)
do_dentry_open(file, path->dentry->d_inode, open)
security_file_open(f)
open()
/* old location of path_noexec() test */
Signed-off-by: Mickaël Salaün <mic@digikod.net>
Signed-off-by: Kees Cook <redacted>
Link: https://lore.kernel.org/r/20200605160013.3954297-4-keescook@chromium.org
---
fs/exec.c | 12 ++++--------
fs/namei.c | 4 ++++
2 files changed, 8 insertions(+), 8 deletions(-)
@@ -2863,6 +2863,10 @@ static int may_open(const struct path *path, int acc_mode, int flag)return-EACCES;flag&=~O_TRUNC;break;+caseS_IFREG:+if((acc_mode&MAY_EXEC)&&path_noexec(path))+return-EACCES;+break;}error=inode_permission(inode,MAY_OPEN|acc_mode);
From: Kees Cook <redacted>
The execve(2)/uselib(2) syscalls have always rejected non-regular
files. Recently, it was noticed that a deadlock was introduced when trying
to execute pipes, as the S_ISREG() test was happening too late. This was
fixed in commit 73601ea5b7b1 ("fs/open.c: allow opening only regular files
during execve()"), but it was added after inode_permission() had already
run, which meant LSMs could see bogus attempts to execute non-regular
files.
Move the test into the other inode type checks (which already look
for other pathological conditions[1]). Since there is no need to use
FMODE_EXEC while we still have access to "acc_mode", also switch the
test to MAY_EXEC.
Also include a comment with the redundant S_ISREG() checks at the end of
execve(2)/uselib(2) to note that they are present to avoid any mistakes.
My notes on the call path, and related arguments, checks, etc:
do_open_execat()
struct open_flags open_exec_flags = {
.open_flag = O_LARGEFILE | O_RDONLY | __FMODE_EXEC,
.acc_mode = MAY_EXEC,
...
do_filp_open(dfd, filename, open_flags)
path_openat(nameidata, open_flags, flags)
file = alloc_empty_file(open_flags, current_cred());
do_open(nameidata, file, open_flags)
may_open(path, acc_mode, open_flag)
/* new location of MAY_EXEC vs S_ISREG() test */
inode_permission(inode, MAY_OPEN | acc_mode)
security_inode_permission(inode, acc_mode)
vfs_open(path, file)
do_dentry_open(file, path->dentry->d_inode, open)
/* old location of FMODE_EXEC vs S_ISREG() test */
security_file_open(f)
open()
[1] https://lore.kernel.org/lkml/202006041910.9EF0C602@keescook/
Signed-off-by: Mickaël Salaün <mic@digikod.net>
Signed-off-by: Kees Cook <redacted>
Link: https://lore.kernel.org/r/20200605160013.3954297-3-keescook@chromium.org
---
fs/exec.c | 14 ++++++++++++--
fs/namei.c | 6 ++++--
fs/open.c | 6 ------
3 files changed, 16 insertions(+), 10 deletions(-)
@@ -2849,16 +2849,18 @@ static int may_open(const struct path *path, int acc_mode, int flag)caseS_IFLNK:return-ELOOP;caseS_IFDIR:-if(acc_mode&MAY_WRITE)+if(acc_mode&(MAY_WRITE|MAY_EXEC))return-EISDIR;break;caseS_IFBLK:caseS_IFCHR:if(!may_open_dev(path))return-EACCES;-/*FALLTHRU*/+fallthrough;caseS_IFIFO:caseS_IFSOCK:+if(acc_mode&MAY_EXEC)+return-EACCES;flag&=~O_TRUNC;break;}
@@ -784,12 +784,6 @@ static int do_dentry_open(struct file *f,return0;}-/* Any file opened for execve()/uselib() has to be a regular file. */-if(unlikely(f->f_flags&FMODE_EXEC&&!S_ISREG(inode->i_mode))){-error=-EACCES;-gotocleanup_file;-}-if(f->f_mode&FMODE_WRITE&&!special_file(inode->i_mode)){error=get_write_access(inode);if(unlikely(error))
On Thu, Jul 23, 2020 at 07:12:24PM +0200, Mickaël Salaün wrote:
When the O_MAYEXEC flag is passed, openat2(2) may be subject to
additional restrictions depending on a security policy managed by the
kernel through a sysctl or implemented by an LSM thanks to the
inode_permission hook. This new flag is ignored by open(2) and
openat(2) because of their unspecified flags handling. When used with
openat2(2), the default behavior is only to forbid to open a directory.
The underlying idea is to be able to restrict scripts interpretation
according to a policy defined by the system administrator. For this to
be possible, script interpreters must use the O_MAYEXEC flag
appropriately. To be fully effective, these interpreters also need to
handle the other ways to execute code: command line parameters (e.g.,
option -e for Perl), module loading (e.g., option -m for Python), stdin,
file sourcing, environment variables, configuration files, etc.
According to the threat model, it may be acceptable to allow some script
interpreters (e.g. Bash) to interpret commands from stdin, may it be a
TTY or a pipe, because it may not be enough to (directly) perform
syscalls. Further documentation can be found in a following patch.
Even without enforced security policy, userland interpreters can set it
to enforce the system policy at their level, knowing that it will not
break anything on running systems which do not care about this feature.
However, on systems which want this feature enforced, there will be
knowledgeable people (i.e. sysadmins who enforced O_MAYEXEC
deliberately) to manage it. A simple security policy implementation,
configured through a dedicated sysctl, is available in a following
patch.
O_MAYEXEC should not be confused with the O_EXEC flag which is intended
for execute-only, which obviously doesn't work for scripts. However, a
similar behavior could be implemented in userland with O_PATH:
https://lore.kernel.org/lkml/1e2f6913-42f2-3578-28ed-567f6a4bdda1@digikod.net/
The implementation of O_MAYEXEC almost duplicates what execve(2) and
uselib(2) are already doing: setting MAY_OPENEXEC in acc_mode (which can
then be checked as MAY_EXEC, if enforced).
This is an updated subset of the patch initially written by Vincent
Strubel for CLIP OS 4:
https://github.com/clipos-archive/src_platform_clip-patches/blob/f5cb330d6b684752e403b4e41b39f7004d88e561/1901_open_mayexec.patch
This patch has been used for more than 12 years with customized script
interpreters. Some examples (with the original O_MAYEXEC) can be found
here:
https://github.com/clipos-archive/clipos4_portage-overlay/search?q=O_MAYEXEC
Co-developed-by: Vincent Strubel <redacted>
Signed-off-by: Vincent Strubel <redacted>
On Thu, Jul 23, 2020 at 07:12:25PM +0200, Mickaël Salaün wrote:
Allow for the enforcement of the O_MAYEXEC openat2(2) flag. Thanks to
the noexec option from the underlying VFS mount, or to the file execute
permission, userspace can enforce these execution policies. This may
allow script interpreters to check execution permission before reading
commands from a file, or dynamic linkers to allow shared object loading.
Add a new sysctl fs.open_mayexec_enforce to enable system administrators
to enforce two complementary security policies according to the
installed system: enforce the noexec mount option, and enforce
executable file permission. Indeed, because of compatibility with
installed systems, only system administrators are able to check that
this new enforcement is in line with the system mount points and file
permissions. A following patch adds documentation.
Being able to restrict execution also enables to protect the kernel by
restricting arbitrary syscalls that an attacker could perform with a
crafted binary or certain script languages. It also improves multilevel
isolation by reducing the ability of an attacker to use side channels
with specific code. These restrictions can natively be enforced for ELF
binaries (with the noexec mount option) but require this kernel
extension to properly handle scripts (e.g., Python, Perl). To get a
consistent execution policy, additional memory restrictions should also
be enforced (e.g. thanks to SELinux).
Because the O_MAYEXEC flag is a meant to enforce a system-wide security
policy (but not application-centric policies), it does not make sense
for userland to check the sysctl value. Indeed, this new flag only
enables to extend the system ability to enforce a policy thanks to (some
trusted) userland collaboration. Moreover, additional security policies
could be managed by LSMs. This is a best-effort approach from the
application developer point of view:
https://lore.kernel.org/lkml/1477d3d7-4b36-afad-7077-a38f42322238@digikod.net/
Signed-off-by: Mickaël Salaün <mic@digikod.net>
On Thu, Jul 23, 2020 at 07:12:26PM +0200, Mickaël Salaün wrote:
Test propagation of noexec mount points or file executability through
files open with or without O_MAYEXEC, thanks to the
fs.open_mayexec_enforce sysctl.
Signed-off-by: Mickaël Salaün <mic@digikod.net>
On Thu, Jul 23, 2020 at 07:12:27PM +0200, Mickaël Salaün wrote:
From: Mimi Zohar <zohar@linux.ibm.com>
The kernel has no way of differentiating between a file containing data
or code being opened by an interpreter. The proposed O_MAYEXEC
openat2(2) flag bridges this gap by defining and enabling the
MAY_OPENEXEC flag.
This patch adds IMA policy support for the new MAY_OPENEXEC flag.
Example:
measure func=FILE_CHECK mask=^MAY_OPENEXEC
appraise func=FILE_CHECK appraise_type=imasig mask=^MAY_OPENEXEC
Signed-off-by: Mickaël Salaün <mic@digikod.net>
I think this looks good now.
Andrew, since you're already carrying my exec clean-ups (repeated here
in patch 1-3), can you pick the rest of this series too?
Thanks!
-Kees
On Thu, Jul 23, 2020 at 07:12:20PM +0200, Mickaël Salaün wrote:
Hi,
This seventh patch series do not set __FMODE_EXEC for the sake of
simplicity. A notification feature could be added later if needed. The
handling of all file types is now well defined and tested: by default,
when opening a path, access to a directory is denied (with EISDIR),
access to a regular file depends on the sysctl policy, and access to
other file types (i.e. fifo, device, socket) is denied if there is any
enforced policy. There is new tests covering all these cases (cf.
test_file_types() ).
As requested by Mimi Zohar, I completed the series with one of her
patches for IMA. I also picked Kees Cook's patches to consolidate exec
permission checking into do_filp_open()'s flow.
# Goal of O_MAYEXEC
The goal of this patch series is to enable to control script execution
with interpreters help. A new O_MAYEXEC flag, usable through
openat2(2), is added to enable userspace script interpreters to delegate
to the kernel (and thus the system security policy) the permission to
interpret/execute scripts or other files containing what can be seen as
commands.
A simple system-wide security policy can be enforced by the system
administrator through a sysctl configuration consistent with the mount
points or the file access rights. The documentation patch explains the
prerequisites.
Furthermore, the security policy can also be delegated to an LSM, either
a MAC system or an integrity system. For instance, the new kernel
MAY_OPENEXEC flag closes a major IMA measurement/appraisal interpreter
integrity gap by bringing the ability to check the use of scripts [1].
Other uses are expected, such as for magic-links [2], SGX integration
[3], bpffs [4] or IPE [5].
# Prerequisite of its use
Userspace needs to adapt to take advantage of this new feature. For
example, the PEP 578 [6] (Runtime Audit Hooks) enables Python 3.8 to be
extended with policy enforcement points related to code interpretation,
which can be used to align with the PowerShell audit features.
Additional Python security improvements (e.g. a limited interpreter
withou -c, stdin piping of code) are on their way [7].
# Examples
The initial idea comes from CLIP OS 4 and the original implementation
has been used for more than 12 years:
https://github.com/clipos-archive/clipos4_doc
Chrome OS has a similar approach:
https://chromium.googlesource.com/chromiumos/docs/+/master/security/noexec_shell_scripts.md
Userland patches can be found here:
https://github.com/clipos-archive/clipos4_portage-overlay/search?q=O_MAYEXEC
Actually, there is more than the O_MAYEXEC changes (which matches this search)
e.g., to prevent Python interactive execution. There are patches for
Bash, Wine, Java (Icedtea), Busybox's ash, Perl and Python. There are
also some related patches which do not directly rely on O_MAYEXEC but
which restrict the use of browser plugins and extensions, which may be
seen as scripts too:
https://github.com/clipos-archive/clipos4_portage-overlay/tree/master/www-client
An introduction to O_MAYEXEC was given at the Linux Security Summit
Europe 2018 - Linux Kernel Security Contributions by ANSSI:
https://www.youtube.com/watch?v=chNjCRtPKQY&t=17m15s
The "write xor execute" principle was explained at Kernel Recipes 2018 -
CLIP OS: a defense-in-depth OS:
https://www.youtube.com/watch?v=PjRE0uBtkHU&t=11m14s
See also an overview article: https://lwn.net/Articles/820000/
This patch series can be applied on top of v5.8-rc5 . This can be tested
with CONFIG_SYSCTL. I would really appreciate constructive comments on
this patch series.
Previous version:
https://lore.kernel.org/lkml/20200505153156.925111-1-mic@digikod.net/
[1] https://lore.kernel.org/lkml/1544647356.4028.105.camel@linux.ibm.com/
[2] https://lore.kernel.org/lkml/20190904201933.10736-6-cyphar@cyphar.com/
[3] https://lore.kernel.org/lkml/CALCETrVovr8XNZSroey7pHF46O=kj_c5D9K8h=z2T_cNrpvMig@mail.gmail.com/
[4] https://lore.kernel.org/lkml/CALCETrVeZ0eufFXwfhtaG_j+AdvbzEWE0M3wjXMWVEO7pj+xkw@mail.gmail.com/
[5] https://lore.kernel.org/lkml/20200406221439.1469862-12-deven.desai@linux.microsoft.com/
[6] https://www.python.org/dev/peps/pep-0578/
[7] https://lore.kernel.org/lkml/0c70debd-e79e-d514-06c6-4cd1e021fa8b@python.org/
Regards,
Kees Cook (3):
exec: Change uselib(2) IS_SREG() failure to EACCES
exec: Move S_ISREG() check earlier
exec: Move path_noexec() check earlier
Mickaël Salaün (3):
fs: Introduce O_MAYEXEC flag for openat2(2)
fs,doc: Enable to enforce noexec mounts or file exec through O_MAYEXEC
selftest/openat2: Add tests for O_MAYEXEC enforcing
Mimi Zohar (1):
ima: add policy support for the new file open MAY_OPENEXEC flag
Documentation/ABI/testing/ima_policy | 2 +-
Documentation/admin-guide/sysctl/fs.rst | 49 +++
fs/exec.c | 23 +-
fs/fcntl.c | 2 +-
fs/namei.c | 36 +-
fs/open.c | 12 +-
include/linux/fcntl.h | 2 +-
include/linux/fs.h | 3 +
include/uapi/asm-generic/fcntl.h | 7 +
kernel/sysctl.c | 12 +-
security/integrity/ima/ima_main.c | 3 +-
security/integrity/ima/ima_policy.c | 15 +-
tools/testing/selftests/kselftest_harness.h | 3 +
tools/testing/selftests/openat2/Makefile | 3 +-
tools/testing/selftests/openat2/config | 1 +
tools/testing/selftests/openat2/helpers.h | 1 +
.../testing/selftests/openat2/omayexec_test.c | 325 ++++++++++++++++++
17 files changed, 470 insertions(+), 29 deletions(-)
create mode 100644 tools/testing/selftests/openat2/config
create mode 100644 tools/testing/selftests/openat2/omayexec_test.c
--
2.27.0
From: Christian Brauner <hidden> Date: 2020-07-25 11:18:58
On Fri, Jul 24, 2020 at 12:06:53PM -0700, Kees Cook wrote:
I think this looks good now.
Andrew, since you're already carrying my exec clean-ups (repeated here
in patch 1-3), can you pick the rest of this series too?
Al,
Not sure if you have already re-surfaced from your
csum()/raw_copy_from_user() work completely yet but you had thoughts
about this series iirc.
Aleksa, thoughts?
Thanks!
Christian
From: Al Viro <viro@zeniv.linux.org.uk> Date: 2020-07-27 04:21:26
On Thu, Jul 23, 2020 at 07:12:24PM +0200, Mickaël Salaün wrote:
When the O_MAYEXEC flag is passed, openat2(2) may be subject to
additional restrictions depending on a security policy managed by the
kernel through a sysctl or implemented by an LSM thanks to the
inode_permission hook. This new flag is ignored by open(2) and
openat(2) because of their unspecified flags handling. When used with
openat2(2), the default behavior is only to forbid to open a directory.
Correct me if I'm wrong, but it looks like you are introducing a magical
flag that would mean "let the Linux S&M take an extra special whip
for this open()".
Why is it done during open? If the caller is passing it deliberately,
why not have an explicit request to apply given torture device to an
already opened file? Why not sys_masochism(int fd, char *hurt_flavour),
for that matter?
It seems that there is no more complains nor questions. Do you want me
to send another series to fix the order of the S-o-b in patch 7?
On 24/07/2020 21:06, Kees Cook wrote:
I think this looks good now.
Andrew, since you're already carrying my exec clean-ups (repeated here
in patch 1-3), can you pick the rest of this series too?
Thanks!
-Kees
On Thu, Jul 23, 2020 at 07:12:20PM +0200, Mickaël Salaün wrote:
quoted
Hi,
This seventh patch series do not set __FMODE_EXEC for the sake of
simplicity. A notification feature could be added later if needed. The
handling of all file types is now well defined and tested: by default,
when opening a path, access to a directory is denied (with EISDIR),
access to a regular file depends on the sysctl policy, and access to
other file types (i.e. fifo, device, socket) is denied if there is any
enforced policy. There is new tests covering all these cases (cf.
test_file_types() ).
As requested by Mimi Zohar, I completed the series with one of her
patches for IMA. I also picked Kees Cook's patches to consolidate exec
permission checking into do_filp_open()'s flow.
# Goal of O_MAYEXEC
The goal of this patch series is to enable to control script execution
with interpreters help. A new O_MAYEXEC flag, usable through
openat2(2), is added to enable userspace script interpreters to delegate
to the kernel (and thus the system security policy) the permission to
interpret/execute scripts or other files containing what can be seen as
commands.
A simple system-wide security policy can be enforced by the system
administrator through a sysctl configuration consistent with the mount
points or the file access rights. The documentation patch explains the
prerequisites.
Furthermore, the security policy can also be delegated to an LSM, either
a MAC system or an integrity system. For instance, the new kernel
MAY_OPENEXEC flag closes a major IMA measurement/appraisal interpreter
integrity gap by bringing the ability to check the use of scripts [1].
Other uses are expected, such as for magic-links [2], SGX integration
[3], bpffs [4] or IPE [5].
# Prerequisite of its use
Userspace needs to adapt to take advantage of this new feature. For
example, the PEP 578 [6] (Runtime Audit Hooks) enables Python 3.8 to be
extended with policy enforcement points related to code interpretation,
which can be used to align with the PowerShell audit features.
Additional Python security improvements (e.g. a limited interpreter
withou -c, stdin piping of code) are on their way [7].
# Examples
The initial idea comes from CLIP OS 4 and the original implementation
has been used for more than 12 years:
https://github.com/clipos-archive/clipos4_doc
Chrome OS has a similar approach:
https://chromium.googlesource.com/chromiumos/docs/+/master/security/noexec_shell_scripts.md
Userland patches can be found here:
https://github.com/clipos-archive/clipos4_portage-overlay/search?q=O_MAYEXEC
Actually, there is more than the O_MAYEXEC changes (which matches this search)
e.g., to prevent Python interactive execution. There are patches for
Bash, Wine, Java (Icedtea), Busybox's ash, Perl and Python. There are
also some related patches which do not directly rely on O_MAYEXEC but
which restrict the use of browser plugins and extensions, which may be
seen as scripts too:
https://github.com/clipos-archive/clipos4_portage-overlay/tree/master/www-client
An introduction to O_MAYEXEC was given at the Linux Security Summit
Europe 2018 - Linux Kernel Security Contributions by ANSSI:
https://www.youtube.com/watch?v=chNjCRtPKQY&t=17m15s
The "write xor execute" principle was explained at Kernel Recipes 2018 -
CLIP OS: a defense-in-depth OS:
https://www.youtube.com/watch?v=PjRE0uBtkHU&t=11m14s
See also an overview article: https://lwn.net/Articles/820000/
This patch series can be applied on top of v5.8-rc5 . This can be tested
with CONFIG_SYSCTL. I would really appreciate constructive comments on
this patch series.
Previous version:
https://lore.kernel.org/lkml/20200505153156.925111-1-mic@digikod.net/
[1] https://lore.kernel.org/lkml/1544647356.4028.105.camel@linux.ibm.com/
[2] https://lore.kernel.org/lkml/20190904201933.10736-6-cyphar@cyphar.com/
[3] https://lore.kernel.org/lkml/CALCETrVovr8XNZSroey7pHF46O=kj_c5D9K8h=z2T_cNrpvMig@mail.gmail.com/
[4] https://lore.kernel.org/lkml/CALCETrVeZ0eufFXwfhtaG_j+AdvbzEWE0M3wjXMWVEO7pj+xkw@mail.gmail.com/
[5] https://lore.kernel.org/lkml/20200406221439.1469862-12-deven.desai@linux.microsoft.com/
[6] https://www.python.org/dev/peps/pep-0578/
[7] https://lore.kernel.org/lkml/0c70debd-e79e-d514-06c6-4cd1e021fa8b@python.org/
Regards,
Kees Cook (3):
exec: Change uselib(2) IS_SREG() failure to EACCES
exec: Move S_ISREG() check earlier
exec: Move path_noexec() check earlier
Mickaël Salaün (3):
fs: Introduce O_MAYEXEC flag for openat2(2)
fs,doc: Enable to enforce noexec mounts or file exec through O_MAYEXEC
selftest/openat2: Add tests for O_MAYEXEC enforcing
Mimi Zohar (1):
ima: add policy support for the new file open MAY_OPENEXEC flag
Documentation/ABI/testing/ima_policy | 2 +-
Documentation/admin-guide/sysctl/fs.rst | 49 +++
fs/exec.c | 23 +-
fs/fcntl.c | 2 +-
fs/namei.c | 36 +-
fs/open.c | 12 +-
include/linux/fcntl.h | 2 +-
include/linux/fs.h | 3 +
include/uapi/asm-generic/fcntl.h | 7 +
kernel/sysctl.c | 12 +-
security/integrity/ima/ima_main.c | 3 +-
security/integrity/ima/ima_policy.c | 15 +-
tools/testing/selftests/kselftest_harness.h | 3 +
tools/testing/selftests/openat2/Makefile | 3 +-
tools/testing/selftests/openat2/config | 1 +
tools/testing/selftests/openat2/helpers.h | 1 +
.../testing/selftests/openat2/omayexec_test.c | 325 ++++++++++++++++++
17 files changed, 470 insertions(+), 29 deletions(-)
create mode 100644 tools/testing/selftests/openat2/config
create mode 100644 tools/testing/selftests/openat2/omayexec_test.c
--
2.27.0
From: Al Viro <viro@zeniv.linux.org.uk> Date: 2020-08-10 20:22:12
On Mon, Aug 10, 2020 at 10:11:53PM +0200, Mickaël Salaün wrote:
It seems that there is no more complains nor questions. Do you want me
to send another series to fix the order of the S-o-b in patch 7?
There is a major question regarding the API design and the choice of
hooking that stuff on open(). And I have not heard anything resembling
a coherent answer.
From: David Laight <hidden> Date: 2020-08-10 22:09:20
On Mon, Aug 10, 2020 at 10:11:53PM +0200, Mickaël Salaün wrote:
quoted
It seems that there is no more complains nor questions. Do you want me
to send another series to fix the order of the S-o-b in patch 7?
There is a major question regarding the API design and the choice of
hooking that stuff on open(). And I have not heard anything resembling
a coherent answer.
To me O_MAYEXEC is just the wrong name.
The bit would be (something like) O_INTERPRET to indicate
what you want to do with the contents.
The kernel 'policy' then decides whether that needs 'r-x'
access or whether 'r--' access in enough.
I think that is what you 100 line comment in 0/n means.
David
-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)
From: Al Viro <viro@zeniv.linux.org.uk> Date: 2020-08-10 22:29:05
On Mon, Aug 10, 2020 at 10:09:09PM +0000, David Laight wrote:
quoted
On Mon, Aug 10, 2020 at 10:11:53PM +0200, Mickaël Salaün wrote:
quoted
It seems that there is no more complains nor questions. Do you want me
to send another series to fix the order of the S-o-b in patch 7?
There is a major question regarding the API design and the choice of
hooking that stuff on open(). And I have not heard anything resembling
a coherent answer.
To me O_MAYEXEC is just the wrong name.
The bit would be (something like) O_INTERPRET to indicate
what you want to do with the contents.
... which does not answer the question - name of constant is the least of
the worries here. Why the hell is "apply some unspecified checks to
file" combined with opening it, rather than being an independent primitive
you apply to an already opened file? Just in case - "'cuz that's how we'd
done it" does not make a good answer...
On Mon, Aug 10, 2020 at 10:11:53PM +0200, Mickaël Salaün wrote:
quoted
It seems that there is no more complains nor questions. Do you want me
to send another series to fix the order of the S-o-b in patch 7?
There is a major question regarding the API design and the choice of
hooking that stuff on open(). And I have not heard anything resembling
a coherent answer.
Hooking on open is a simple design that enables processes to check files
they intend to open, before they open them. From an API point of view,
this series extends openat2(2) with one simple flag: O_MAYEXEC. The
enforcement is then subject to the system policy (e.g. mount points,
file access rights, IMA, etc.).
Checking on open enables to not open a file if it does not meet some
requirements, the same way as if the path doesn't exist or (for whatever
reasons, including execution permission) if access is denied. It is a
good practice to check as soon as possible such properties, and it may
enables to avoid (user space) time-of-check to time-of-use (TOCTOU)
attacks (i.e. misuse of already open resources). It is important to keep
in mind that the use cases we are addressing consider that the (user
space) script interpreters (or linkers) are trusted and unaltered (i.e.
integrity/authenticity checked). These are similar sought defensive
properties as for SUID/SGID binaries: attackers can still launch them
with malicious inputs (e.g. file paths, file descriptors, environment
variables, etc.), but the binaries can then have a way to check if they
can extend their trust to some file paths.
Checking file descriptors may help in some use cases, but not the ones
motivating this series. Checking (already) opened resources could be a
*complementary* way to check execute permission, but it is not in the
scope of this series.
On Mon, Aug 10, 2020 at 10:09:09PM +0000, David Laight wrote:
quoted
quoted
On Mon, Aug 10, 2020 at 10:11:53PM +0200, Mickaël Salaün wrote:
quoted
It seems that there is no more complains nor questions. Do you want me
to send another series to fix the order of the S-o-b in patch 7?
There is a major question regarding the API design and the choice of
hooking that stuff on open(). And I have not heard anything resembling
a coherent answer.
To me O_MAYEXEC is just the wrong name.
The bit would be (something like) O_INTERPRET to indicate
what you want to do with the contents.
The properties is "execute permission". This can then be checked by
interpreters or other applications, then the generic O_MAYEXEC name.
... which does not answer the question - name of constant is the least of
the worries here. Why the hell is "apply some unspecified checks to
file" combined with opening it, rather than being an independent primitive
you apply to an already opened file? Just in case - "'cuz that's how we'd
done it" does not make a good answer...
On Tue, Aug 11, 2020 at 12:43 AM Mickaël Salaün [off-list ref] wrote:
On 10/08/2020 22:21, Al Viro wrote:
quoted
On Mon, Aug 10, 2020 at 10:11:53PM +0200, Mickaël Salaün wrote:
quoted
It seems that there is no more complains nor questions. Do you want me
to send another series to fix the order of the S-o-b in patch 7?
There is a major question regarding the API design and the choice of
hooking that stuff on open(). And I have not heard anything resembling
a coherent answer.
Hooking on open is a simple design that enables processes to check files
they intend to open, before they open them. From an API point of view,
this series extends openat2(2) with one simple flag: O_MAYEXEC. The
enforcement is then subject to the system policy (e.g. mount points,
file access rights, IMA, etc.).
Checking on open enables to not open a file if it does not meet some
requirements, the same way as if the path doesn't exist or (for whatever
reasons, including execution permission) if access is denied.
You can do exactly the same thing if you do the check in a separate
syscall though.
And it provides a greater degree of flexibility; for example, you can
use it in combination with fopen() without having to modify the
internals of fopen() or having to use fdopen().
It is a
good practice to check as soon as possible such properties, and it may
enables to avoid (user space) time-of-check to time-of-use (TOCTOU)
attacks (i.e. misuse of already open resources).
The assumption that security checks should happen as early as possible
can actually cause security problems. For example, because seccomp was
designed to do its checks as early as possible, including before
ptrace, we had an issue for a long time where the ptrace API could be
abused to bypass seccomp filters.
Please don't decide that a check must be ordered first _just_ because
it is a security check. While that can be good for limiting attack
surface, it can also create issues when the idea is applied too
broadly.
I don't see how TOCTOU issues are relevant in any way here. If someone
can turn a script that is considered a trusted file into an untrusted
file and then maliciously change its contents, you're going to have
issues either way because the modifications could still happen after
openat(); if this was possible, the whole thing would kind of fall
apart. And if that isn't possible, I don't see any TOCTOU.
It is important to keep
in mind that the use cases we are addressing consider that the (user
space) script interpreters (or linkers) are trusted and unaltered (i.e.
integrity/authenticity checked). These are similar sought defensive
properties as for SUID/SGID binaries: attackers can still launch them
with malicious inputs (e.g. file paths, file descriptors, environment
variables, etc.), but the binaries can then have a way to check if they
can extend their trust to some file paths.
Checking file descriptors may help in some use cases, but not the ones
motivating this series.
It actually provides a superset of the functionality that your
existing patches provide.
Checking (already) opened resources could be a
*complementary* way to check execute permission, but it is not in the
scope of this series.
From: Al Viro <viro@zeniv.linux.org.uk> Date: 2020-08-10 23:05:34
On Tue, Aug 11, 2020 at 12:43:52AM +0200, Mickaël Salaün wrote:
Hooking on open is a simple design that enables processes to check files
they intend to open, before they open them.
Which is a good thing, because...?
From an API point of view,
this series extends openat2(2) with one simple flag: O_MAYEXEC. The
enforcement is then subject to the system policy (e.g. mount points,
file access rights, IMA, etc.).
That's what "unspecified" means - as far as the kernel concerned, it's
"something completely opaque, will let these hooks to play, semantics is
entirely up to them".
Checking on open enables to not open a file if it does not meet some
requirements, the same way as if the path doesn't exist or (for whatever
reasons, including execution permission) if access is denied. It is a
good practice to check as soon as possible such properties, and it may
enables to avoid (user space) time-of-check to time-of-use (TOCTOU)
attacks (i.e. misuse of already open resources).
????? You explicitly assume a cooperating caller. If it can't be trusted
to issue the check between open and use, or can be manipulated (ptraced,
etc.) into not doing so, how can you rely upon the flag having been passed
in the first place? And TOCTOU window is definitely not wider that way.
If you want to have it done immediately after open(), bloody well do it
immediately after open. If attacker has subverted your control flow to the
extent that allows them to hit descriptor table in the interval between
these two syscalls, you have already lost - they'll simply prevent that
flag from being passed.
What's the point of burying it inside openat2()? A convenient multiplexor
to hook into? We already have one - it's called do_syscall_...
From: David Laight <hidden> Date: 2020-08-11 08:09:19
On 11/08/2020 00:28, Al Viro wrote:
quoted
On Mon, Aug 10, 2020 at 10:09:09PM +0000, David Laight wrote:
quoted
quoted
On Mon, Aug 10, 2020 at 10:11:53PM +0200, Mickaël Salaün wrote:
quoted
It seems that there is no more complains nor questions. Do you want me
to send another series to fix the order of the S-o-b in patch 7?
There is a major question regarding the API design and the choice of
hooking that stuff on open(). And I have not heard anything resembling
a coherent answer.
To me O_MAYEXEC is just the wrong name.
The bit would be (something like) O_INTERPRET to indicate
what you want to do with the contents.
The properties is "execute permission". This can then be checked by
interpreters or other applications, then the generic O_MAYEXEC name.
The english sense of MAYEXEC is just wrong for what you are trying
to check.
quoted
... which does not answer the question - name of constant is the least of
the worries here. Why the hell is "apply some unspecified checks to
file" combined with opening it, rather than being an independent primitive
you apply to an already opened file? Just in case - "'cuz that's how we'd
done it" does not make a good answer...
Maybe an access_ok() that acts on an open fd would be more
appropriate.
Which might end up being an fcntrl() action.
That would give you a full 32bit mask of options.
David
-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)
On Tue, Aug 11, 2020 at 12:43 AM Mickaël Salaün [off-list ref] wrote:
quoted
On 10/08/2020 22:21, Al Viro wrote:
quoted
On Mon, Aug 10, 2020 at 10:11:53PM +0200, Mickaël Salaün wrote:
quoted
It seems that there is no more complains nor questions. Do you want me
to send another series to fix the order of the S-o-b in patch 7?
There is a major question regarding the API design and the choice of
hooking that stuff on open(). And I have not heard anything resembling
a coherent answer.
Hooking on open is a simple design that enables processes to check files
they intend to open, before they open them. From an API point of view,
this series extends openat2(2) with one simple flag: O_MAYEXEC. The
enforcement is then subject to the system policy (e.g. mount points,
file access rights, IMA, etc.).
Checking on open enables to not open a file if it does not meet some
requirements, the same way as if the path doesn't exist or (for whatever
reasons, including execution permission) if access is denied.
You can do exactly the same thing if you do the check in a separate
syscall though.
And it provides a greater degree of flexibility; for example, you can
use it in combination with fopen() without having to modify the
internals of fopen() or having to use fdopen().
quoted
It is a
good practice to check as soon as possible such properties, and it may
enables to avoid (user space) time-of-check to time-of-use (TOCTOU)
attacks (i.e. misuse of already open resources).
The assumption that security checks should happen as early as possible
can actually cause security problems. For example, because seccomp was
designed to do its checks as early as possible, including before
ptrace, we had an issue for a long time where the ptrace API could be
abused to bypass seccomp filters.
Please don't decide that a check must be ordered first _just_ because
it is a security check. While that can be good for limiting attack
surface, it can also create issues when the idea is applied too
broadly.
I don't see how TOCTOU issues are relevant in any way here. If someone
can turn a script that is considered a trusted file into an untrusted
file and then maliciously change its contents, you're going to have
issues either way because the modifications could still happen after
openat(); if this was possible, the whole thing would kind of fall
apart. And if that isn't possible, I don't see any TOCTOU.
Sure, and if the scripts are not protected in some way there is no point
to check anything.
quoted
It is important to keep
in mind that the use cases we are addressing consider that the (user
space) script interpreters (or linkers) are trusted and unaltered (i.e.
integrity/authenticity checked). These are similar sought defensive
properties as for SUID/SGID binaries: attackers can still launch them
with malicious inputs (e.g. file paths, file descriptors, environment
variables, etc.), but the binaries can then have a way to check if they
can extend their trust to some file paths.
Checking file descriptors may help in some use cases, but not the ones
motivating this series.
It actually provides a superset of the functionality that your
existing patches provide.
It also brings new issues with multiple file descriptor origins (e.g.
memfd_create).
quoted
Checking (already) opened resources could be a
*complementary* way to check execute permission, but it is not in the
scope of this series.
On Tue, Aug 11, 2020 at 12:43:52AM +0200, Mickaël Salaün wrote:
quoted
Hooking on open is a simple design that enables processes to check files
they intend to open, before they open them.
Which is a good thing, because...?
quoted
From an API point of view,
this series extends openat2(2) with one simple flag: O_MAYEXEC. The
enforcement is then subject to the system policy (e.g. mount points,
file access rights, IMA, etc.).
That's what "unspecified" means - as far as the kernel concerned, it's
"something completely opaque, will let these hooks to play, semantics is
entirely up to them".
I see it as an access controls mechanism; access may be granted or
denied, as for O_RDONLY, O_WRONLY or (non-Linux) O_EXEC. Even for common
access controls, there are capabilities to bypass them (i.e.
CAP_DAC_OVERRIDE), but multiple layers may enforce different
complementary policies.
quoted
Checking on open enables to not open a file if it does not meet some
requirements, the same way as if the path doesn't exist or (for whatever
reasons, including execution permission) if access is denied. It is a
good practice to check as soon as possible such properties, and it may
enables to avoid (user space) time-of-check to time-of-use (TOCTOU)
attacks (i.e. misuse of already open resources).
????? You explicitly assume a cooperating caller.
As said in the below (removed) reply, no, quite the contrary.
If it can't be trusted
to issue the check between open and use, or can be manipulated (ptraced,
etc.) into not doing so, how can you rely upon the flag having been passed
in the first place? And TOCTOU window is definitely not wider that way.
OK, I guess it would be considered a bug in the application (e.g. buggy
resource management between threads).
If you want to have it done immediately after open(), bloody well do it
immediately after open. If attacker has subverted your control flow to the
extent that allows them to hit descriptor table in the interval between
these two syscalls, you have already lost - they'll simply prevent that
flag from being passed.
What's the point of burying it inside openat2()? A convenient multiplexor
to hook into? We already have one - it's called do_syscall_...
To check as soon as possible without opening something that should not
be opened in the first place.
Isn't a dedicated syscall a bit too much for this feature? What about
adding a new command/flag to fcntl(2)?
On Mon, Aug 10, 2020 at 10:09:09PM +0000, David Laight wrote:
quoted
quoted
On Mon, Aug 10, 2020 at 10:11:53PM +0200, Mickaël Salaün wrote:
quoted
It seems that there is no more complains nor questions. Do you want me
to send another series to fix the order of the S-o-b in patch 7?
There is a major question regarding the API design and the choice of
hooking that stuff on open(). And I have not heard anything resembling
a coherent answer.
To me O_MAYEXEC is just the wrong name.
The bit would be (something like) O_INTERPRET to indicate
what you want to do with the contents.
The properties is "execute permission". This can then be checked by
interpreters or other applications, then the generic O_MAYEXEC name.
The english sense of MAYEXEC is just wrong for what you are trying
to check.
We think it reflects exactly what it's purpose is.
quoted
quoted
... which does not answer the question - name of constant is the least of
the worries here. Why the hell is "apply some unspecified checks to
file" combined with opening it, rather than being an independent primitive
you apply to an already opened file? Just in case - "'cuz that's how we'd
done it" does not make a good answer...
Maybe an access_ok() that acts on an open fd would be more
appropriate.
Which might end up being an fcntrl() action.
That would give you a full 32bit mask of options.
On Tue, 2020-08-11 at 10:48 +0200, Mickaël Salaün wrote:
On 11/08/2020 01:03, Jann Horn wrote:
quoted
On Tue, Aug 11, 2020 at 12:43 AM Mickaël Salaün [off-list ref] wrote:
quoted
On 10/08/2020 22:21, Al Viro wrote:
quoted
On Mon, Aug 10, 2020 at 10:11:53PM +0200, Mickaël Salaün wrote:
quoted
It seems that there is no more complains nor questions. Do you want me
to send another series to fix the order of the S-o-b in patch 7?
There is a major question regarding the API design and the choice of
hooking that stuff on open(). And I have not heard anything resembling
a coherent answer.
Hooking on open is a simple design that enables processes to check files
they intend to open, before they open them. From an API point of view,
this series extends openat2(2) with one simple flag: O_MAYEXEC. The
enforcement is then subject to the system policy (e.g. mount points,
file access rights, IMA, etc.).
Checking on open enables to not open a file if it does not meet some
requirements, the same way as if the path doesn't exist or (for whatever
reasons, including execution permission) if access is denied.
You can do exactly the same thing if you do the check in a separate
syscall though.
And it provides a greater degree of flexibility; for example, you can
use it in combination with fopen() without having to modify the
internals of fopen() or having to use fdopen().
quoted
It is a
good practice to check as soon as possible such properties, and it may
enables to avoid (user space) time-of-check to time-of-use (TOCTOU)
attacks (i.e. misuse of already open resources).
The assumption that security checks should happen as early as possible
can actually cause security problems. For example, because seccomp was
designed to do its checks as early as possible, including before
ptrace, we had an issue for a long time where the ptrace API could be
abused to bypass seccomp filters.
Please don't decide that a check must be ordered first _just_ because
it is a security check. While that can be good for limiting attack
surface, it can also create issues when the idea is applied too
broadly.
One of the major gaps, defining a system wide policy requiring all code
being executed to be signed, is interpreters. The kernel has no
context for the interpreter's opening the file. From an IMA
perspective, this information needs to be conveyed to the kernel prior
to ima_file_check(), which would allow IMA policy rules to be defined
in terms of O_MAYEXEC.
quoted
I don't see how TOCTOU issues are relevant in any way here. If someone
can turn a script that is considered a trusted file into an untrusted
file and then maliciously change its contents, you're going to have
issues either way because the modifications could still happen after
openat(); if this was possible, the whole thing would kind of fall
apart. And if that isn't possible, I don't see any TOCTOU.
Sure, and if the scripts are not protected in some way there is no point
to check anything.
The interpreter itself would be signed.
Mimi
quoted
quoted
It is important to keep
in mind that the use cases we are addressing consider that the (user
space) script interpreters (or linkers) are trusted and unaltered (i.e.
integrity/authenticity checked). These are similar sought defensive
properties as for SUID/SGID binaries: attackers can still launch them
with malicious inputs (e.g. file paths, file descriptors, environment
variables, etc.), but the binaries can then have a way to check if they
can extend their trust to some file paths.
Checking file descriptors may help in some use cases, but not the ones
motivating this series.
It actually provides a superset of the functionality that your
existing patches provide.
It also brings new issues with multiple file descriptor origins (e.g.
memfd_create).
quoted
quoted
Checking (already) opened resources could be a
*complementary* way to check execute permission, but it is not in the
scope of this series.
From: Matthew Wilcox <willy@infradead.org> Date: 2020-08-11 14:02:49
On Tue, Aug 11, 2020 at 09:56:50AM -0400, Mimi Zohar wrote:
On Tue, 2020-08-11 at 10:48 +0200, Mickaël Salaün wrote:
quoted
On 11/08/2020 01:03, Jann Horn wrote:
quoted
On Tue, Aug 11, 2020 at 12:43 AM Mickaël Salaün [off-list ref] wrote:
quoted
On 10/08/2020 22:21, Al Viro wrote:
quoted
On Mon, Aug 10, 2020 at 10:11:53PM +0200, Mickaël Salaün wrote:
quoted
It seems that there is no more complains nor questions. Do you want me
to send another series to fix the order of the S-o-b in patch 7?
There is a major question regarding the API design and the choice of
hooking that stuff on open(). And I have not heard anything resembling
a coherent answer.
Hooking on open is a simple design that enables processes to check files
they intend to open, before they open them. From an API point of view,
this series extends openat2(2) with one simple flag: O_MAYEXEC. The
enforcement is then subject to the system policy (e.g. mount points,
file access rights, IMA, etc.).
Checking on open enables to not open a file if it does not meet some
requirements, the same way as if the path doesn't exist or (for whatever
reasons, including execution permission) if access is denied.
You can do exactly the same thing if you do the check in a separate
syscall though.
And it provides a greater degree of flexibility; for example, you can
use it in combination with fopen() without having to modify the
internals of fopen() or having to use fdopen().
quoted
It is a
good practice to check as soon as possible such properties, and it may
enables to avoid (user space) time-of-check to time-of-use (TOCTOU)
attacks (i.e. misuse of already open resources).
The assumption that security checks should happen as early as possible
can actually cause security problems. For example, because seccomp was
designed to do its checks as early as possible, including before
ptrace, we had an issue for a long time where the ptrace API could be
abused to bypass seccomp filters.
Please don't decide that a check must be ordered first _just_ because
it is a security check. While that can be good for limiting attack
surface, it can also create issues when the idea is applied too
broadly.
One of the major gaps, defining a system wide policy requiring all code
being executed to be signed, is interpreters. The kernel has no
context for the interpreter's opening the file. From an IMA
perspective, this information needs to be conveyed to the kernel prior
to ima_file_check(), which would allow IMA policy rules to be defined
in terms of O_MAYEXEC.
This is kind of evading the point -- Mickaël is proposing a new flag
to open() to tell IMA to measure the file being opened before the fd
is returned to userspace, and Al is suggesting a new syscall to allow
a previously-obtained fd to be measured.
I think what you're saying is that you don't see any reason to prefer
one over the other.
On Tue, 2020-08-11 at 15:02 +0100, Matthew Wilcox wrote:
On Tue, Aug 11, 2020 at 09:56:50AM -0400, Mimi Zohar wrote:
quoted
On Tue, 2020-08-11 at 10:48 +0200, Mickaël Salaün wrote:
quoted
On 11/08/2020 01:03, Jann Horn wrote:
quoted
On Tue, Aug 11, 2020 at 12:43 AM Mickaël Salaün [off-list ref] wrote:
quoted
On 10/08/2020 22:21, Al Viro wrote:
quoted
On Mon, Aug 10, 2020 at 10:11:53PM +0200, Mickaël Salaün wrote:
quoted
It seems that there is no more complains nor questions. Do you want me
to send another series to fix the order of the S-o-b in patch 7?
There is a major question regarding the API design and the choice of
hooking that stuff on open(). And I have not heard anything resembling
a coherent answer.
Hooking on open is a simple design that enables processes to check files
they intend to open, before they open them. From an API point of view,
this series extends openat2(2) with one simple flag: O_MAYEXEC. The
enforcement is then subject to the system policy (e.g. mount points,
file access rights, IMA, etc.).
Checking on open enables to not open a file if it does not meet some
requirements, the same way as if the path doesn't exist or (for whatever
reasons, including execution permission) if access is denied.
You can do exactly the same thing if you do the check in a separate
syscall though.
And it provides a greater degree of flexibility; for example, you can
use it in combination with fopen() without having to modify the
internals of fopen() or having to use fdopen().
quoted
It is a
good practice to check as soon as possible such properties, and it may
enables to avoid (user space) time-of-check to time-of-use (TOCTOU)
attacks (i.e. misuse of already open resources).
The assumption that security checks should happen as early as possible
can actually cause security problems. For example, because seccomp was
designed to do its checks as early as possible, including before
ptrace, we had an issue for a long time where the ptrace API could be
abused to bypass seccomp filters.
Please don't decide that a check must be ordered first _just_ because
it is a security check. While that can be good for limiting attack
surface, it can also create issues when the idea is applied too
broadly.
One of the major gaps, defining a system wide policy requiring all code
being executed to be signed, is interpreters. The kernel has no
context for the interpreter's opening the file. From an IMA
perspective, this information needs to be conveyed to the kernel prior
to ima_file_check(), which would allow IMA policy rules to be defined
in terms of O_MAYEXEC.
This is kind of evading the point -- Mickaël is proposing a new flag
to open() to tell IMA to measure the file being opened before the fd
is returned to userspace, and Al is suggesting a new syscall to allow
a previously-obtained fd to be measured.
I think what you're saying is that you don't see any reason to prefer
one over the other.
Being able to define IMA appraise and measure file open
(func=FILE_CHECK) policy rules to prevent the interpreter from
executing unsigned files would be really nice. Otherwise, the file
would be measured and appraised multiple times, once on file open and
again at the point of this new syscall.
Mimi
On 8/11/2020 1:48 AM, Mickaël Salaün wrote:
[...snip]
quoted
quoted
It is a
good practice to check as soon as possible such properties, and it may
enables to avoid (user space) time-of-check to time-of-use (TOCTOU)
attacks (i.e. misuse of already open resources).
The assumption that security checks should happen as early as possible
can actually cause security problems. For example, because seccomp was
designed to do its checks as early as possible, including before
ptrace, we had an issue for a long time where the ptrace API could be
abused to bypass seccomp filters.
Please don't decide that a check must be ordered first _just_ because
it is a security check. While that can be good for limiting attack
surface, it can also create issues when the idea is applied too
broadly.
I don't see an issue with IPE. As long as the hypothetical new syscall
and associated security hook have the file struct available in the
hook, it should integrate fairly easily.
[...snip]