* [RFC PATCH v8 0/3] Add support for AT_INTERPRETED (was O_MAYEXEC) @ 2020-09-08 7:59 Mickaël Salaün 2020-09-08 7:59 ` [RFC PATCH v8 1/3] fs: Introduce AT_INTERPRETED flag for faccessat2(2) Mickaël Salaün ` (3 more replies) 0 siblings, 4 replies; 23+ messages in thread From: Mickaël Salaün @ 2020-09-08 7:59 UTC (permalink / raw) To: linux-kernel Cc: Mickaël Salaün, Aleksa Sarai, Alexei Starovoitov, Al Viro, Andrew Morton, Andy Lutomirski, Christian Brauner, Christian Heimes, Daniel Borkmann, Deven Bowers, Dmitry Vyukov, Eric Biggers, Eric Chiang, Florian Weimer, James Morris, Jan Kara, Jann Horn, Jonathan Corbet, Kees Cook, Lakshmi Ramasubramanian, Matthew Garrett, Matthew Wilcox, Michael Kerrisk, Miklos Szeredi, Mimi Zohar, Philippe Trébuchet, Scott Shell, Sean Christopherson, Shuah Khan, Steve Dower, Steve Grubb, Tetsuo Handa, Thibaut Sautereau, Vincent Strubel, kernel-hardening, linux-api, linux-integrity, linux-security-module, linux-fsdevel Hi, This height patch series rework the previous O_MAYEXEC series by not adding a new flag to openat2(2) but to faccessat2(2) instead. As suggested, this enables to perform the access check on a file descriptor instead of on a file path (while opening it). This may require two checks (one on open and then with faccessat2) but it is a more generic approach [8]. The IMA patch is removed for now because the only LSM hook triggered by faccessat2(2) is inode_permission() which takes a struct inode as argument. However, struct path and then struct file are still available in this syscall, which enables to add a new hook to fit the needs of IMA and other path-based LSMs. We also removed the three patches from Kees Cook which are no longer required for this new implementation. Goal of AT_INTERPRETED ====================== The goal of this patch series is to enable to control script execution with interpreters help. A new AT_INTERPRETED flag, usable through faccessat2(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_INTERPRETED_EXEC flag is required to close 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]. Possible extended usage ======================= For now, only the X_OK mode is compatible with the AT_INTERPRETED flag. This enables to restrict the addition of new control flows in a process. Using R_OK or W_OK with AT_INTERPRETED returns -EINVAL. Possible future use-cases for R_OK with AT_INTERPRETED may be to check configuration files that may impact the behavior of applications (i.e. influence critical part of the current control flow). Those should then be trusted as well. The W_OK with AT_INTERPRETED could be used to check that a file descriptor is allowed to receive sensitive data such as debug logs. 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 without -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.9-rc4 . This can be tested with CONFIG_SYSCTL. I would really appreciate constructive comments on this patch series. Previous version: https://lore.kernel.org/lkml/20200723171227.446711-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/ [8] https://lore.kernel.org/lkml/e7c1f99d7cdf706ca0867e5fb76ae4cb38bc83f5.camel@linux.ibm.com/ Regards, Mickaël Salaün (3): fs: Introduce AT_INTERPRETED flag for faccessat2(2) fs,doc: Enable to configure exec checks for AT_INTERPRETED selftest/interpreter: Add tests for AT_INTERPRETED enforcing Documentation/admin-guide/sysctl/fs.rst | 54 +++ fs/open.c | 67 ++- include/linux/fs.h | 3 + include/uapi/linux/fcntl.h | 12 +- kernel/sysctl.c | 12 +- .../testing/selftests/interpreter/.gitignore | 2 + tools/testing/selftests/interpreter/Makefile | 18 + tools/testing/selftests/interpreter/config | 1 + .../interpreter/interpreted_access_test.c | 384 ++++++++++++++++++ 9 files changed, 548 insertions(+), 5 deletions(-) create mode 100644 tools/testing/selftests/interpreter/.gitignore create mode 100644 tools/testing/selftests/interpreter/Makefile create mode 100644 tools/testing/selftests/interpreter/config create mode 100644 tools/testing/selftests/interpreter/interpreted_access_test.c -- 2.28.0 ^ permalink raw reply [flat|nested] 23+ messages in thread
* [RFC PATCH v8 1/3] fs: Introduce AT_INTERPRETED flag for faccessat2(2) 2020-09-08 7:59 [RFC PATCH v8 0/3] Add support for AT_INTERPRETED (was O_MAYEXEC) Mickaël Salaün @ 2020-09-08 7:59 ` Mickaël Salaün 2020-09-08 12:28 ` Mimi Zohar 2020-09-08 7:59 ` [RFC PATCH v8 2/3] fs,doc: Enable to configure exec checks for AT_INTERPRETED Mickaël Salaün ` (2 subsequent siblings) 3 siblings, 1 reply; 23+ messages in thread From: Mickaël Salaün @ 2020-09-08 7:59 UTC (permalink / raw) To: linux-kernel Cc: Mickaël Salaün, Aleksa Sarai, Alexei Starovoitov, Al Viro, Andrew Morton, Andy Lutomirski, Christian Brauner, Christian Heimes, Daniel Borkmann, Deven Bowers, Dmitry Vyukov, Eric Biggers, Eric Chiang, Florian Weimer, James Morris, Jan Kara, Jann Horn, Jonathan Corbet, Kees Cook, Lakshmi Ramasubramanian, Matthew Garrett, Matthew Wilcox, Michael Kerrisk, Miklos Szeredi, Mimi Zohar, Philippe Trébuchet, Scott Shell, Sean Christopherson, Shuah Khan, Steve Dower, Steve Grubb, Tetsuo Handa, Thibaut Sautereau, Vincent Strubel, kernel-hardening, linux-api, linux-integrity, linux-security-module, linux-fsdevel, Thibaut Sautereau, Mickaël Salaün From: Mickaël Salaün <mic@linux.microsoft.com> The AT_INTERPRETED flag combined with the X_OK mode enable trusted user space tasks to check that files are allowed to be executed by user space. The security policy is consistently managed by the kernel through a sysctl or implemented by an LSM thanks to the inode_permission hook and a new kernel flag: MAY_INTERPRETED_EXEC. 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 faccessat2(2) with the AT_INTERPRETED flag and the X_OK mode. 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 AT_INTERPRETED with X_OK deliberately) to manage it. A simple security policy implementation, configured through a dedicated sysctl, is available in a following patch. AT_INTERPRETED with X_OK should not be confused with the O_EXEC flag (for open) 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/ This is a new implementation of a 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: Thibaut Sautereau <thibaut.sautereau@ssi.gouv.fr> Signed-off-by: Thibaut Sautereau <thibaut.sautereau@ssi.gouv.fr> Signed-off-by: Mickaël Salaün <mic@linux.microsoft.com> Cc: Al Viro <viro@zeniv.linux.org.uk> Cc: Andrew Morton <akpm@linux-foundation.org> Cc: Jann Horn <jannh@google.com> Cc: Kees Cook <keescook@chromium.org> Cc: Miklos Szeredi <mszeredi@redhat.com> --- Changes since v7: * Replaces openat2/O_MAYEXEC with faccessat2/X_OK/AT_INTERPRETED . Switching to an FD-based syscall was suggested by Al Viro and Jann Horn. 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/open.c | 31 +++++++++++++++++++++++++++++-- include/linux/fs.h | 2 ++ include/uapi/linux/fcntl.h | 12 +++++++++++- 3 files changed, 42 insertions(+), 3 deletions(-) diff --git a/fs/open.c b/fs/open.c index 9af548fb841b..879bdfbdc6fa 100644 --- a/fs/open.c +++ b/fs/open.c @@ -405,9 +405,13 @@ static long do_faccessat(int dfd, const char __user *filename, int mode, int fla if (mode & ~S_IRWXO) /* where's F_OK, X_OK, W_OK, R_OK? */ return -EINVAL; - if (flags & ~(AT_EACCESS | AT_SYMLINK_NOFOLLOW | AT_EMPTY_PATH)) + if (flags & ~(AT_EACCESS | AT_SYMLINK_NOFOLLOW | AT_EMPTY_PATH | + AT_INTERPRETED)) return -EINVAL; + /* Only allows X_OK with AT_INTERPRETED for now. */ + if ((flags & AT_INTERPRETED) && !(mode & S_IXOTH)) + return -EINVAL; if (flags & AT_SYMLINK_NOFOLLOW) lookup_flags &= ~LOOKUP_FOLLOW; if (flags & AT_EMPTY_PATH) @@ -426,7 +430,30 @@ static long do_faccessat(int dfd, const char __user *filename, int mode, int fla inode = d_backing_inode(path.dentry); - if ((mode & MAY_EXEC) && S_ISREG(inode->i_mode)) { + if ((flags & AT_INTERPRETED)) { + /* + * For compatibility reasons, without a defined security policy + * (via sysctl or LSM), using AT_INTERPRETED must map the + * execute permission to the read permission. Indeed, from + * user space point of view, being able to execute data (e.g. + * scripts) implies to be able to read this data. + * + * The MAY_INTERPRETED_EXEC bit is set to enable LSMs to add + * custom checks, while being compatible with current policies. + */ + if ((mode & MAY_EXEC)) { + mode |= MAY_INTERPRETED_EXEC; + /* + * For compatibility reasons, if the system-wide policy + * doesn't enforce file permission checks, then + * replaces the execute permission request with a read + * permission request. + */ + mode &= ~MAY_EXEC; + /* To be executed *by* user space, files must be readable. */ + mode |= MAY_READ; + } + } else if ((mode & MAY_EXEC) && S_ISREG(inode->i_mode)) { /* * MAY_EXEC on regular files is denied if the fs is mounted * with the "noexec" flag. diff --git a/include/linux/fs.h b/include/linux/fs.h index 7519ae003a08..03f1b2da6a87 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -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 +/* interpreted accesses checked with faccessat2 and AT_INTERPRETED */ +#define MAY_INTERPRETED_EXEC 0x00000100 /* * flags in file.f_mode. Note that FMODE_READ and FMODE_WRITE must correspond diff --git a/include/uapi/linux/fcntl.h b/include/uapi/linux/fcntl.h index 2f86b2ad6d7e..dca082b02634 100644 --- a/include/uapi/linux/fcntl.h +++ b/include/uapi/linux/fcntl.h @@ -90,7 +90,8 @@ * unlinkat. The two functions do completely different things and therefore, * the flags can be allowed to overlap. For example, passing AT_REMOVEDIR to * faccessat would be undefined behavior and thus treating it equivalent to - * AT_EACCESS is valid undefined behavior. + * AT_EACCESS is valid undefined behavior. The same goes for AT_SYMLINK_FOLLOW + * and AT_INTERPRETED. */ #define AT_FDCWD -100 /* Special value used to indicate openat should use the current @@ -100,6 +101,15 @@ effective IDs, not real IDs. */ #define AT_REMOVEDIR 0x200 /* Remove directory instead of unlinking file. */ +#define AT_INTERPRETED 0x400 /* Check if the current process should + grant access (e.g. execution) for a + specific file, i.e. enables RWX to + be enforced *by* user space. The + main usage is for script + interpreters to enforce a policy + consistent with the kernel's one + (through sysctl configuration or LSM + policy). */ #define AT_SYMLINK_FOLLOW 0x400 /* Follow symbolic links. */ #define AT_NO_AUTOMOUNT 0x800 /* Suppress terminal automount traversal */ #define AT_EMPTY_PATH 0x1000 /* Allow empty relative pathname */ -- 2.28.0 ^ permalink raw reply related [flat|nested] 23+ messages in thread
* Re: [RFC PATCH v8 1/3] fs: Introduce AT_INTERPRETED flag for faccessat2(2) 2020-09-08 7:59 ` [RFC PATCH v8 1/3] fs: Introduce AT_INTERPRETED flag for faccessat2(2) Mickaël Salaün @ 2020-09-08 12:28 ` Mimi Zohar 2020-09-08 12:43 ` Mickaël Salaün 0 siblings, 1 reply; 23+ messages in thread From: Mimi Zohar @ 2020-09-08 12:28 UTC (permalink / raw) To: Mickaël Salaün, linux-kernel Cc: Aleksa Sarai, Alexei Starovoitov, Al Viro, Andrew Morton, Andy Lutomirski, Christian Brauner, Christian Heimes, Daniel Borkmann, Deven Bowers, Dmitry Vyukov, Eric Biggers, Eric Chiang, Florian Weimer, James Morris, Jan Kara, Jann Horn, Jonathan Corbet, Kees Cook, Lakshmi Ramasubramanian, Matthew Garrett, Matthew Wilcox, Michael Kerrisk, Miklos Szeredi, Philippe Trébuchet, Scott Shell, Sean Christopherson, Shuah Khan, Steve Dower, Steve Grubb, Tetsuo Handa, Thibaut Sautereau, Vincent Strubel, kernel-hardening, linux-api, linux-integrity, linux-security-module, linux-fsdevel, Thibaut Sautereau, Mickaël Salaün, Stephen Smalley, John Johansen Hi Mickael, On Tue, 2020-09-08 at 09:59 +0200, Mickaël Salaün wrote: > diff --git a/fs/open.c b/fs/open.c > index 9af548fb841b..879bdfbdc6fa 100644 > --- a/fs/open.c > +++ b/fs/open.c > @@ -405,9 +405,13 @@ static long do_faccessat(int dfd, const char __user *filename, int mode, int fla > if (mode & ~S_IRWXO) /* where's F_OK, X_OK, W_OK, R_OK? */ > return -EINVAL; > > - if (flags & ~(AT_EACCESS | AT_SYMLINK_NOFOLLOW | AT_EMPTY_PATH)) > + if (flags & ~(AT_EACCESS | AT_SYMLINK_NOFOLLOW | AT_EMPTY_PATH | > + AT_INTERPRETED)) > return -EINVAL; > > + /* Only allows X_OK with AT_INTERPRETED for now. */ > + if ((flags & AT_INTERPRETED) && !(mode & S_IXOTH)) > + return -EINVAL; > if (flags & AT_SYMLINK_NOFOLLOW) > lookup_flags &= ~LOOKUP_FOLLOW; > if (flags & AT_EMPTY_PATH) > @@ -426,7 +430,30 @@ static long do_faccessat(int dfd, const char __user *filename, int mode, int fla > > inode = d_backing_inode(path.dentry); > > - if ((mode & MAY_EXEC) && S_ISREG(inode->i_mode)) { > + if ((flags & AT_INTERPRETED)) { > + /* > + * For compatibility reasons, without a defined security policy > + * (via sysctl or LSM), using AT_INTERPRETED must map the > + * execute permission to the read permission. Indeed, from > + * user space point of view, being able to execute data (e.g. > + * scripts) implies to be able to read this data. > + * > + * The MAY_INTERPRETED_EXEC bit is set to enable LSMs to add > + * custom checks, while being compatible with current policies. > + */ > + if ((mode & MAY_EXEC)) { Why is the ISREG() test being dropped? Without dropping it, there would be no reason for making the existing test an "else" clause. > + mode |= MAY_INTERPRETED_EXEC; > + /* > + * For compatibility reasons, if the system-wide policy > + * doesn't enforce file permission checks, then > + * replaces the execute permission request with a read > + * permission request. > + */ > + mode &= ~MAY_EXEC; > + /* To be executed *by* user space, files must be readable. */ > + mode |= MAY_READ; After this change, I'm wondering if it makes sense to add a call to security_file_permission(). IMA doesn't currently define it, but could. Mimi > + } > + } else if ((mode & MAY_EXEC) && S_ISREG(inode->i_mode)) { > /* > * MAY_EXEC on regular files is denied if the fs is mounted > * with the "noexec" flag. ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [RFC PATCH v8 1/3] fs: Introduce AT_INTERPRETED flag for faccessat2(2) 2020-09-08 12:28 ` Mimi Zohar @ 2020-09-08 12:43 ` Mickaël Salaün 2020-09-08 12:50 ` Stephen Smalley 2020-09-08 15:24 ` Mimi Zohar 0 siblings, 2 replies; 23+ messages in thread From: Mickaël Salaün @ 2020-09-08 12:43 UTC (permalink / raw) To: Mimi Zohar, linux-kernel Cc: Aleksa Sarai, Alexei Starovoitov, Al Viro, Andrew Morton, Andy Lutomirski, Christian Brauner, Christian Heimes, Daniel Borkmann, Deven Bowers, Dmitry Vyukov, Eric Biggers, Eric Chiang, Florian Weimer, James Morris, Jan Kara, Jann Horn, Jonathan Corbet, Kees Cook, Lakshmi Ramasubramanian, Matthew Garrett, Matthew Wilcox, Michael Kerrisk, Miklos Szeredi, Philippe Trébuchet, Scott Shell, Sean Christopherson, Shuah Khan, Steve Dower, Steve Grubb, Tetsuo Handa, Thibaut Sautereau, Vincent Strubel, kernel-hardening, linux-api, linux-integrity, linux-security-module, linux-fsdevel, Thibaut Sautereau, Mickaël Salaün, Stephen Smalley, John Johansen On 08/09/2020 14:28, Mimi Zohar wrote: > Hi Mickael, > > On Tue, 2020-09-08 at 09:59 +0200, Mickaël Salaün wrote: >> diff --git a/fs/open.c b/fs/open.c >> index 9af548fb841b..879bdfbdc6fa 100644 >> --- a/fs/open.c >> +++ b/fs/open.c >> @@ -405,9 +405,13 @@ static long do_faccessat(int dfd, const char __user *filename, int mode, int fla >> if (mode & ~S_IRWXO) /* where's F_OK, X_OK, W_OK, R_OK? */ >> return -EINVAL; >> >> - if (flags & ~(AT_EACCESS | AT_SYMLINK_NOFOLLOW | AT_EMPTY_PATH)) >> + if (flags & ~(AT_EACCESS | AT_SYMLINK_NOFOLLOW | AT_EMPTY_PATH | >> + AT_INTERPRETED)) >> return -EINVAL; >> >> + /* Only allows X_OK with AT_INTERPRETED for now. */ >> + if ((flags & AT_INTERPRETED) && !(mode & S_IXOTH)) >> + return -EINVAL; >> if (flags & AT_SYMLINK_NOFOLLOW) >> lookup_flags &= ~LOOKUP_FOLLOW; >> if (flags & AT_EMPTY_PATH) >> @@ -426,7 +430,30 @@ static long do_faccessat(int dfd, const char __user *filename, int mode, int fla >> >> inode = d_backing_inode(path.dentry); >> >> - if ((mode & MAY_EXEC) && S_ISREG(inode->i_mode)) { >> + if ((flags & AT_INTERPRETED)) { >> + /* >> + * For compatibility reasons, without a defined security policy >> + * (via sysctl or LSM), using AT_INTERPRETED must map the >> + * execute permission to the read permission. Indeed, from >> + * user space point of view, being able to execute data (e.g. >> + * scripts) implies to be able to read this data. >> + * >> + * The MAY_INTERPRETED_EXEC bit is set to enable LSMs to add >> + * custom checks, while being compatible with current policies. >> + */ >> + if ((mode & MAY_EXEC)) { > > Why is the ISREG() test being dropped? Without dropping it, there > would be no reason for making the existing test an "else" clause. The ISREG() is not dropped, it is just moved below with the rest of the original code. The corresponding code (with the path_noexec call) for AT_INTERPRETED is added with the next commit, and it relies on the sysctl configuration for compatibility reasons. > >> + mode |= MAY_INTERPRETED_EXEC; >> + /* >> + * For compatibility reasons, if the system-wide policy >> + * doesn't enforce file permission checks, then >> + * replaces the execute permission request with a read >> + * permission request. >> + */ >> + mode &= ~MAY_EXEC; >> + /* To be executed *by* user space, files must be readable. */ >> + mode |= MAY_READ; > > After this change, I'm wondering if it makes sense to add a call to > security_file_permission(). IMA doesn't currently define it, but > could. Yes, that's the idea. We could replace the following inode_permission() with file_permission(). I'm not sure how this will impact other LSMs though. > > Mimi > >> + } >> + } else if ((mode & MAY_EXEC) && S_ISREG(inode->i_mode)) { >> /* >> * MAY_EXEC on regular files is denied if the fs is mounted >> * with the "noexec" flag. > ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [RFC PATCH v8 1/3] fs: Introduce AT_INTERPRETED flag for faccessat2(2) 2020-09-08 12:43 ` Mickaël Salaün @ 2020-09-08 12:50 ` Stephen Smalley 2020-09-08 12:52 ` Stephen Smalley 2020-09-08 15:24 ` Mimi Zohar 1 sibling, 1 reply; 23+ messages in thread From: Stephen Smalley @ 2020-09-08 12:50 UTC (permalink / raw) To: Mickaël Salaün Cc: Mimi Zohar, linux-kernel, Aleksa Sarai, Alexei Starovoitov, Al Viro, Andrew Morton, Andy Lutomirski, Christian Brauner, Christian Heimes, Daniel Borkmann, Deven Bowers, Dmitry Vyukov, Eric Biggers, Eric Chiang, Florian Weimer, James Morris, Jan Kara, Jann Horn, Jonathan Corbet, Kees Cook, Lakshmi Ramasubramanian, Matthew Garrett, Matthew Wilcox, Michael Kerrisk, Miklos Szeredi, Philippe Trébuchet, Scott Shell, Sean Christopherson, Shuah Khan, Steve Dower, Steve Grubb, Tetsuo Handa, Thibaut Sautereau, Vincent Strubel, kernel-hardening, linux-api, linux-integrity, LSM List, Linux FS Devel, Thibaut Sautereau, Mickaël Salaün, John Johansen On Tue, Sep 8, 2020 at 8:43 AM Mickaël Salaün <mic@digikod.net> wrote: > > > On 08/09/2020 14:28, Mimi Zohar wrote: > > Hi Mickael, > > > > On Tue, 2020-09-08 at 09:59 +0200, Mickaël Salaün wrote: > >> + mode |= MAY_INTERPRETED_EXEC; > >> + /* > >> + * For compatibility reasons, if the system-wide policy > >> + * doesn't enforce file permission checks, then > >> + * replaces the execute permission request with a read > >> + * permission request. > >> + */ > >> + mode &= ~MAY_EXEC; > >> + /* To be executed *by* user space, files must be readable. */ > >> + mode |= MAY_READ; > > > > After this change, I'm wondering if it makes sense to add a call to > > security_file_permission(). IMA doesn't currently define it, but > > could. > > Yes, that's the idea. We could replace the following inode_permission() > with file_permission(). I'm not sure how this will impact other LSMs though. They are not equivalent at least as far as SELinux is concerned. security_file_permission() was only to be used to revalidate read/write permissions previously checked at file open to support policy changes and file or process label changes. We'd have to modify the SELinux hook if we wanted to have it check execute access even if nothing has changed since open time. ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [RFC PATCH v8 1/3] fs: Introduce AT_INTERPRETED flag for faccessat2(2) 2020-09-08 12:50 ` Stephen Smalley @ 2020-09-08 12:52 ` Stephen Smalley 2020-09-08 13:29 ` Mimi Zohar 0 siblings, 1 reply; 23+ messages in thread From: Stephen Smalley @ 2020-09-08 12:52 UTC (permalink / raw) To: Mickaël Salaün Cc: Mimi Zohar, linux-kernel, Aleksa Sarai, Alexei Starovoitov, Al Viro, Andrew Morton, Andy Lutomirski, Christian Brauner, Christian Heimes, Daniel Borkmann, Deven Bowers, Dmitry Vyukov, Eric Biggers, Eric Chiang, Florian Weimer, James Morris, Jan Kara, Jann Horn, Jonathan Corbet, Kees Cook, Lakshmi Ramasubramanian, Matthew Garrett, Matthew Wilcox, Michael Kerrisk, Miklos Szeredi, Philippe Trébuchet, Scott Shell, Sean Christopherson, Shuah Khan, Steve Dower, Steve Grubb, Tetsuo Handa, Thibaut Sautereau, Vincent Strubel, kernel-hardening, linux-api, linux-integrity, LSM List, Linux FS Devel, Thibaut Sautereau, Mickaël Salaün, John Johansen On Tue, Sep 8, 2020 at 8:50 AM Stephen Smalley <stephen.smalley.work@gmail.com> wrote: > > On Tue, Sep 8, 2020 at 8:43 AM Mickaël Salaün <mic@digikod.net> wrote: > > > > > > On 08/09/2020 14:28, Mimi Zohar wrote: > > > Hi Mickael, > > > > > > On Tue, 2020-09-08 at 09:59 +0200, Mickaël Salaün wrote: > > >> + mode |= MAY_INTERPRETED_EXEC; > > >> + /* > > >> + * For compatibility reasons, if the system-wide policy > > >> + * doesn't enforce file permission checks, then > > >> + * replaces the execute permission request with a read > > >> + * permission request. > > >> + */ > > >> + mode &= ~MAY_EXEC; > > >> + /* To be executed *by* user space, files must be readable. */ > > >> + mode |= MAY_READ; > > > > > > After this change, I'm wondering if it makes sense to add a call to > > > security_file_permission(). IMA doesn't currently define it, but > > > could. > > > > Yes, that's the idea. We could replace the following inode_permission() > > with file_permission(). I'm not sure how this will impact other LSMs though. > > They are not equivalent at least as far as SELinux is concerned. > security_file_permission() was only to be used to revalidate > read/write permissions previously checked at file open to support > policy changes and file or process label changes. We'd have to modify > the SELinux hook if we wanted to have it check execute access even if > nothing has changed since open time. Also Smack doesn't appear to implement file_permission at all, so it would skip Smack checking. ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [RFC PATCH v8 1/3] fs: Introduce AT_INTERPRETED flag for faccessat2(2) 2020-09-08 12:52 ` Stephen Smalley @ 2020-09-08 13:29 ` Mimi Zohar [not found] ` <CAEjxPJ5evWDSv-T-p=4OX29Pr584ZRAsnYoxSRd4qFDoryB+fQ@mail.gmail.com> 0 siblings, 1 reply; 23+ messages in thread From: Mimi Zohar @ 2020-09-08 13:29 UTC (permalink / raw) To: Stephen Smalley, Mickaël Salaün Cc: linux-kernel, Aleksa Sarai, Alexei Starovoitov, Al Viro, Andrew Morton, Andy Lutomirski, Christian Brauner, Christian Heimes, Daniel Borkmann, Deven Bowers, Dmitry Vyukov, Eric Biggers, Eric Chiang, Florian Weimer, James Morris, Jan Kara, Jann Horn, Jonathan Corbet, Kees Cook, Lakshmi Ramasubramanian, Matthew Garrett, Matthew Wilcox, Michael Kerrisk, Miklos Szeredi, Philippe Trébuchet, Scott Shell, Sean Christopherson, Shuah Khan, Steve Dower, Steve Grubb, Tetsuo Handa, Thibaut Sautereau, Vincent Strubel, kernel-hardening, linux-api, linux-integrity, LSM List, Linux FS Devel, Thibaut Sautereau, Mickaël Salaün, John Johansen On Tue, 2020-09-08 at 08:52 -0400, Stephen Smalley wrote: > On Tue, Sep 8, 2020 at 8:50 AM Stephen Smalley > <stephen.smalley.work@gmail.com> wrote: > > > > On Tue, Sep 8, 2020 at 8:43 AM Mickaël Salaün <mic@digikod.net> wrote: > > > > > > > > > On 08/09/2020 14:28, Mimi Zohar wrote: > > > > Hi Mickael, > > > > > > > > On Tue, 2020-09-08 at 09:59 +0200, Mickaël Salaün wrote: > > > >> + mode |= MAY_INTERPRETED_EXEC; > > > >> + /* > > > >> + * For compatibility reasons, if the system-wide policy > > > >> + * doesn't enforce file permission checks, then > > > >> + * replaces the execute permission request with a read > > > >> + * permission request. > > > >> + */ > > > >> + mode &= ~MAY_EXEC; > > > >> + /* To be executed *by* user space, files must be readable. */ > > > >> + mode |= MAY_READ; > > > > > > > > After this change, I'm wondering if it makes sense to add a call to > > > > security_file_permission(). IMA doesn't currently define it, but > > > > could. > > > > > > Yes, that's the idea. We could replace the following inode_permission() > > > with file_permission(). I'm not sure how this will impact other LSMs though. I wasn't suggesting replacing the existing security_inode_permission hook later, but adding a new security_file_permission hook here. > > > > They are not equivalent at least as far as SELinux is concerned. > > security_file_permission() was only to be used to revalidate > > read/write permissions previously checked at file open to support > > policy changes and file or process label changes. We'd have to modify > > the SELinux hook if we wanted to have it check execute access even if > > nothing has changed since open time. > > Also Smack doesn't appear to implement file_permission at all, so it > would skip Smack checking. My question is whether adding a new security_file_permission call here would break either SELinux or Apparmor? Mimi ^ permalink raw reply [flat|nested] 23+ messages in thread
[parent not found: <CAEjxPJ5evWDSv-T-p=4OX29Pr584ZRAsnYoxSRd4qFDoryB+fQ@mail.gmail.com>]
* Re: [RFC PATCH v8 1/3] fs: Introduce AT_INTERPRETED flag for faccessat2(2) [not found] ` <CAEjxPJ5evWDSv-T-p=4OX29Pr584ZRAsnYoxSRd4qFDoryB+fQ@mail.gmail.com> @ 2020-09-08 14:14 ` Mickaël Salaün 2020-09-08 15:38 ` Mimi Zohar 0 siblings, 1 reply; 23+ messages in thread From: Mickaël Salaün @ 2020-09-08 14:14 UTC (permalink / raw) To: Stephen Smalley, Mimi Zohar Cc: linux-kernel, Aleksa Sarai, Alexei Starovoitov, Al Viro, Andrew Morton, Andy Lutomirski, Christian Brauner, Christian Heimes, Daniel Borkmann, Deven Bowers, Dmitry Vyukov, Eric Biggers, Eric Chiang, Florian Weimer, James Morris, Jan Kara, Jann Horn, Jonathan Corbet, Kees Cook, Lakshmi Ramasubramanian, Matthew Garrett, Matthew Wilcox, Michael Kerrisk, Miklos Szeredi, Philippe Trébuchet, Scott Shell, Sean Christopherson, Shuah Khan, Steve Dower, Steve Grubb, Tetsuo Handa, Thibaut Sautereau, Vincent Strubel, kernel-hardening, linux-api, linux-integrity, LSM List, Linux FS Devel, Thibaut Sautereau, Mickaël Salaün, John Johansen On 08/09/2020 15:42, Stephen Smalley wrote: > On Tue, Sep 8, 2020 at 9:29 AM Mimi Zohar <zohar@linux.ibm.com> wrote: >> >> On Tue, 2020-09-08 at 08:52 -0400, Stephen Smalley wrote: >>> On Tue, Sep 8, 2020 at 8:50 AM Stephen Smalley >>> <stephen.smalley.work@gmail.com> wrote: >>>> >>>> On Tue, Sep 8, 2020 at 8:43 AM Mickaël Salaün <mic@digikod.net> wrote: >>>>> >>>>> >>>>> On 08/09/2020 14:28, Mimi Zohar wrote: >>>>>> Hi Mickael, >>>>>> >>>>>> On Tue, 2020-09-08 at 09:59 +0200, Mickaël Salaün wrote: >>>>>>> + mode |= MAY_INTERPRETED_EXEC; >>>>>>> + /* >>>>>>> + * For compatibility reasons, if the system-wide policy >>>>>>> + * doesn't enforce file permission checks, then >>>>>>> + * replaces the execute permission request with a read >>>>>>> + * permission request. >>>>>>> + */ >>>>>>> + mode &= ~MAY_EXEC; >>>>>>> + /* To be executed *by* user space, files must be readable. */ >>>>>>> + mode |= MAY_READ; >>>>>> >>>>>> After this change, I'm wondering if it makes sense to add a call to >>>>>> security_file_permission(). IMA doesn't currently define it, but >>>>>> could. >>>>> >>>>> Yes, that's the idea. We could replace the following inode_permission() >>>>> with file_permission(). I'm not sure how this will impact other LSMs though. >> >> I wasn't suggesting replacing the existing security_inode_permission >> hook later, but adding a new security_file_permission hook here. >> >>>> >>>> They are not equivalent at least as far as SELinux is concerned. >>>> security_file_permission() was only to be used to revalidate >>>> read/write permissions previously checked at file open to support >>>> policy changes and file or process label changes. We'd have to modify >>>> the SELinux hook if we wanted to have it check execute access even if >>>> nothing has changed since open time. >>> >>> Also Smack doesn't appear to implement file_permission at all, so it >>> would skip Smack checking. >> >> My question is whether adding a new security_file_permission call here >> would break either SELinux or Apparmor? > > selinux_inode_permission() has special handling for MAY_ACCESS so we'd > need to duplicate that into selinux_file_permission() -> > selinux_revalidate_file_permission(). Also likely need to adjust > selinux_file_permission() to explicitly check whether the mask > includes any permissions not checked at open time. So some changes > would be needed here. By default, it would be a no-op unless there > was a policy reload or the file was relabeled between the open(2) and > the faccessat(2) call. > We could create a new hook path_permission(struct path *path, int mask) as a superset of inode_permission(). To be more convenient, his new hook could then just call inode_permission() for every LSMs not implementing path_permission(). ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [RFC PATCH v8 1/3] fs: Introduce AT_INTERPRETED flag for faccessat2(2) 2020-09-08 14:14 ` Mickaël Salaün @ 2020-09-08 15:38 ` Mimi Zohar 0 siblings, 0 replies; 23+ messages in thread From: Mimi Zohar @ 2020-09-08 15:38 UTC (permalink / raw) To: Mickaël Salaün, Stephen Smalley, Casey Schaufler Cc: linux-kernel, Aleksa Sarai, Alexei Starovoitov, Al Viro, Andrew Morton, Andy Lutomirski, Christian Brauner, Christian Heimes, Daniel Borkmann, Deven Bowers, Dmitry Vyukov, Eric Biggers, Eric Chiang, Florian Weimer, James Morris, Jan Kara, Jann Horn, Jonathan Corbet, Kees Cook, Lakshmi Ramasubramanian, Matthew Garrett, Matthew Wilcox, Michael Kerrisk, Miklos Szeredi, Philippe Trébuchet, Scott Shell, Sean Christopherson, Shuah Khan, Steve Dower, Steve Grubb, Tetsuo Handa, Thibaut Sautereau, Vincent Strubel, kernel-hardening, linux-api, linux-integrity, LSM List, Linux FS Devel, Thibaut Sautereau, Mickaël Salaün, John Johansen [Cc'ing Casey] On Tue, 2020-09-08 at 16:14 +0200, Mickaël Salaün wrote: > On 08/09/2020 15:42, Stephen Smalley wrote: > > On Tue, Sep 8, 2020 at 9:29 AM Mimi Zohar <zohar@linux.ibm.com> wrote: > >> > >> On Tue, 2020-09-08 at 08:52 -0400, Stephen Smalley wrote: > >>> On Tue, Sep 8, 2020 at 8:50 AM Stephen Smalley > >>> <stephen.smalley.work@gmail.com> wrote: > >>>> > >>>> On Tue, Sep 8, 2020 at 8:43 AM Mickaël Salaün <mic@digikod.net> wrote: > >>>>> > >>>>> > >>>>> On 08/09/2020 14:28, Mimi Zohar wrote: > >>>>>> Hi Mickael, > >>>>>> > >>>>>> On Tue, 2020-09-08 at 09:59 +0200, Mickaël Salaün wrote: > >>>>>>> + mode |= MAY_INTERPRETED_EXEC; > >>>>>>> + /* > >>>>>>> + * For compatibility reasons, if the system-wide policy > >>>>>>> + * doesn't enforce file permission checks, then > >>>>>>> + * replaces the execute permission request with a read > >>>>>>> + * permission request. > >>>>>>> + */ > >>>>>>> + mode &= ~MAY_EXEC; > >>>>>>> + /* To be executed *by* user space, files must be readable. */ > >>>>>>> + mode |= MAY_READ; > >>>>>> > >>>>>> After this change, I'm wondering if it makes sense to add a call to > >>>>>> security_file_permission(). IMA doesn't currently define it, but > >>>>>> could. > >>>>> > >>>>> Yes, that's the idea. We could replace the following inode_permission() > >>>>> with file_permission(). I'm not sure how this will impact other LSMs though. > >> > >> I wasn't suggesting replacing the existing security_inode_permission > >> hook later, but adding a new security_file_permission hook here. > >> > >>>> > >>>> They are not equivalent at least as far as SELinux is concerned. > >>>> security_file_permission() was only to be used to revalidate > >>>> read/write permissions previously checked at file open to support > >>>> policy changes and file or process label changes. We'd have to modify > >>>> the SELinux hook if we wanted to have it check execute access even if > >>>> nothing has changed since open time. > >>> > >>> Also Smack doesn't appear to implement file_permission at all, so it > >>> would skip Smack checking. > >> > >> My question is whether adding a new security_file_permission call here > >> would break either SELinux or Apparmor? > > > > selinux_inode_permission() has special handling for MAY_ACCESS so we'd > > need to duplicate that into selinux_file_permission() -> > > selinux_revalidate_file_permission(). Also likely need to adjust > > selinux_file_permission() to explicitly check whether the mask > > includes any permissions not checked at open time. So some changes > > would be needed here. By default, it would be a no-op unless there > > was a policy reload or the file was relabeled between the open(2) and > > the faccessat(2) call. > > > > We could create a new hook path_permission(struct path *path, int mask) > as a superset of inode_permission(). To be more convenient, his new hook > could then just call inode_permission() for every LSMs not implementing > path_permission(). The LSM maintainers need to chime in here on this suggestion. In terms of the name, except for one hook, all the security_path_XXXX() hooks are dependent on CONFIG_SECURITY_PATH being configured. Mimi ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [RFC PATCH v8 1/3] fs: Introduce AT_INTERPRETED flag for faccessat2(2) 2020-09-08 12:43 ` Mickaël Salaün 2020-09-08 12:50 ` Stephen Smalley @ 2020-09-08 15:24 ` Mimi Zohar 2020-09-08 15:44 ` Mickaël Salaün 1 sibling, 1 reply; 23+ messages in thread From: Mimi Zohar @ 2020-09-08 15:24 UTC (permalink / raw) To: Mickaël Salaün, linux-kernel Cc: Aleksa Sarai, Alexei Starovoitov, Al Viro, Andrew Morton, Andy Lutomirski, Christian Brauner, Christian Heimes, Daniel Borkmann, Deven Bowers, Dmitry Vyukov, Eric Biggers, Eric Chiang, Florian Weimer, James Morris, Jan Kara, Jann Horn, Jonathan Corbet, Kees Cook, Lakshmi Ramasubramanian, Matthew Garrett, Matthew Wilcox, Michael Kerrisk, Miklos Szeredi, Philippe Trébuchet, Scott Shell, Sean Christopherson, Shuah Khan, Steve Dower, Steve Grubb, Tetsuo Handa, Thibaut Sautereau, Vincent Strubel, kernel-hardening, linux-api, linux-integrity, linux-security-module, linux-fsdevel, Thibaut Sautereau, Mickaël Salaün, Stephen Smalley, John Johansen On Tue, 2020-09-08 at 14:43 +0200, Mickaël Salaün wrote: > On 08/09/2020 14:28, Mimi Zohar wrote: > > Hi Mickael, > > > > On Tue, 2020-09-08 at 09:59 +0200, Mickaël Salaün wrote: > >> diff --git a/fs/open.c b/fs/open.c > >> index 9af548fb841b..879bdfbdc6fa 100644 > >> --- a/fs/open.c > >> +++ b/fs/open.c > >> @@ -405,9 +405,13 @@ static long do_faccessat(int dfd, const char __user *filename, int mode, int fla > >> if (mode & ~S_IRWXO) /* where's F_OK, X_OK, W_OK, R_OK? */ > >> return -EINVAL; > >> > >> - if (flags & ~(AT_EACCESS | AT_SYMLINK_NOFOLLOW | AT_EMPTY_PATH)) > >> + if (flags & ~(AT_EACCESS | AT_SYMLINK_NOFOLLOW | AT_EMPTY_PATH | > >> + AT_INTERPRETED)) > >> return -EINVAL; > >> > >> + /* Only allows X_OK with AT_INTERPRETED for now. */ > >> + if ((flags & AT_INTERPRETED) && !(mode & S_IXOTH)) > >> + return -EINVAL; > >> if (flags & AT_SYMLINK_NOFOLLOW) > >> lookup_flags &= ~LOOKUP_FOLLOW; > >> if (flags & AT_EMPTY_PATH) > >> @@ -426,7 +430,30 @@ static long do_faccessat(int dfd, const char __user *filename, int mode, int fla > >> > >> inode = d_backing_inode(path.dentry); > >> > >> - if ((mode & MAY_EXEC) && S_ISREG(inode->i_mode)) { > >> + if ((flags & AT_INTERPRETED)) { > >> + /* > >> + * For compatibility reasons, without a defined security policy > >> + * (via sysctl or LSM), using AT_INTERPRETED must map the > >> + * execute permission to the read permission. Indeed, from > >> + * user space point of view, being able to execute data (e.g. > >> + * scripts) implies to be able to read this data. > >> + * > >> + * The MAY_INTERPRETED_EXEC bit is set to enable LSMs to add > >> + * custom checks, while being compatible with current policies. > >> + */ > >> + if ((mode & MAY_EXEC)) { > > > > Why is the ISREG() test being dropped? Without dropping it, there > > would be no reason for making the existing test an "else" clause. > > The ISREG() is not dropped, it is just moved below with the rest of the > original code. The corresponding code (with the path_noexec call) for > AT_INTERPRETED is added with the next commit, and it relies on the > sysctl configuration for compatibility reasons. Dropping the S_ISREG() check here without an explanation is wrong and probably unsafe, as it is only re-added in the subsequent patch and only for the "sysctl_interpreted_access" case. Adding this new test after the existing test is probably safer. If the original test fails, it returns the same value as this test -EACCES. Mimi > > > > >> + mode |= MAY_INTERPRETED_EXEC; > >> + /* > >> + * For compatibility reasons, if the system-wide policy > >> + * doesn't enforce file permission checks, then > >> + * replaces the execute permission request with a read > >> + * permission request. > >> + */ > >> + mode &= ~MAY_EXEC; > >> + /* To be executed *by* user space, files must be readable. */ > >> + mode |= MAY_READ; ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [RFC PATCH v8 1/3] fs: Introduce AT_INTERPRETED flag for faccessat2(2) 2020-09-08 15:24 ` Mimi Zohar @ 2020-09-08 15:44 ` Mickaël Salaün 2020-09-08 16:44 ` Mimi Zohar 0 siblings, 1 reply; 23+ messages in thread From: Mickaël Salaün @ 2020-09-08 15:44 UTC (permalink / raw) To: Mimi Zohar, linux-kernel Cc: Aleksa Sarai, Alexei Starovoitov, Al Viro, Andrew Morton, Andy Lutomirski, Christian Brauner, Christian Heimes, Daniel Borkmann, Deven Bowers, Dmitry Vyukov, Eric Biggers, Eric Chiang, Florian Weimer, James Morris, Jan Kara, Jann Horn, Jonathan Corbet, Kees Cook, Lakshmi Ramasubramanian, Matthew Garrett, Matthew Wilcox, Michael Kerrisk, Miklos Szeredi, Philippe Trébuchet, Scott Shell, Sean Christopherson, Shuah Khan, Steve Dower, Steve Grubb, Tetsuo Handa, Thibaut Sautereau, Vincent Strubel, kernel-hardening, linux-api, linux-integrity, linux-security-module, linux-fsdevel, Thibaut Sautereau, Mickaël Salaün, Stephen Smalley, John Johansen On 08/09/2020 17:24, Mimi Zohar wrote: > On Tue, 2020-09-08 at 14:43 +0200, Mickaël Salaün wrote: >> On 08/09/2020 14:28, Mimi Zohar wrote: >>> Hi Mickael, >>> >>> On Tue, 2020-09-08 at 09:59 +0200, Mickaël Salaün wrote: >>>> diff --git a/fs/open.c b/fs/open.c >>>> index 9af548fb841b..879bdfbdc6fa 100644 >>>> --- a/fs/open.c >>>> +++ b/fs/open.c >>>> @@ -405,9 +405,13 @@ static long do_faccessat(int dfd, const char __user *filename, int mode, int fla >>>> if (mode & ~S_IRWXO) /* where's F_OK, X_OK, W_OK, R_OK? */ >>>> return -EINVAL; >>>> >>>> - if (flags & ~(AT_EACCESS | AT_SYMLINK_NOFOLLOW | AT_EMPTY_PATH)) >>>> + if (flags & ~(AT_EACCESS | AT_SYMLINK_NOFOLLOW | AT_EMPTY_PATH | >>>> + AT_INTERPRETED)) >>>> return -EINVAL; >>>> >>>> + /* Only allows X_OK with AT_INTERPRETED for now. */ >>>> + if ((flags & AT_INTERPRETED) && !(mode & S_IXOTH)) >>>> + return -EINVAL; >>>> if (flags & AT_SYMLINK_NOFOLLOW) >>>> lookup_flags &= ~LOOKUP_FOLLOW; >>>> if (flags & AT_EMPTY_PATH) >>>> @@ -426,7 +430,30 @@ static long do_faccessat(int dfd, const char __user *filename, int mode, int fla >>>> >>>> inode = d_backing_inode(path.dentry); >>>> >>>> - if ((mode & MAY_EXEC) && S_ISREG(inode->i_mode)) { >>>> + if ((flags & AT_INTERPRETED)) { >>>> + /* >>>> + * For compatibility reasons, without a defined security policy >>>> + * (via sysctl or LSM), using AT_INTERPRETED must map the >>>> + * execute permission to the read permission. Indeed, from >>>> + * user space point of view, being able to execute data (e.g. >>>> + * scripts) implies to be able to read this data. >>>> + * >>>> + * The MAY_INTERPRETED_EXEC bit is set to enable LSMs to add >>>> + * custom checks, while being compatible with current policies. >>>> + */ >>>> + if ((mode & MAY_EXEC)) { >>> >>> Why is the ISREG() test being dropped? Without dropping it, there >>> would be no reason for making the existing test an "else" clause. >> >> The ISREG() is not dropped, it is just moved below with the rest of the >> original code. The corresponding code (with the path_noexec call) for >> AT_INTERPRETED is added with the next commit, and it relies on the >> sysctl configuration for compatibility reasons. > > Dropping the S_ISREG() check here without an explanation is wrong and > probably unsafe, as it is only re-added in the subsequent patch and > only for the "sysctl_interpreted_access" case. Adding this new test > after the existing test is probably safer. If the original test fails, > it returns the same value as this test -EACCES. The original S_ISREG() is ANDed with a MAY_EXEC check and with path_noexec(). The goal of this patch is indeed to have a different behavior than the original faccessat2(2) thanks to the AT_INTERPRETED flag. This can't work if we add the sysctl check after the current path_noexec() check. Moreover, in this patch an exec check is translated to a read check. This new behavior is harmless because using AT_INTERPRETED with the current faccessat2(2) would return -EINVAL. The current vanilla behavior is then unchanged. The whole point of this patch series is to have a policy which do not break current systems and is easy to configure by the sysadmin through sysctl. This patch series also enable LSMs to take advantage of it without the current faccess* limitations. For instance, it is then possible for an LSM to implement more complex policies which may allow execution of data from pipes or sockets, while verifying the source of this data. Enforcing S_ISREG() in this patch would forbid such policies to be implemented. In the case of IMA, you may want to add the same S_ISREG() check. > > Mimi > >> >>> >>>> + mode |= MAY_INTERPRETED_EXEC; >>>> + /* >>>> + * For compatibility reasons, if the system-wide policy >>>> + * doesn't enforce file permission checks, then >>>> + * replaces the execute permission request with a read >>>> + * permission request. >>>> + */ >>>> + mode &= ~MAY_EXEC; >>>> + /* To be executed *by* user space, files must be readable. */ >>>> + mode |= MAY_READ; > > ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [RFC PATCH v8 1/3] fs: Introduce AT_INTERPRETED flag for faccessat2(2) 2020-09-08 15:44 ` Mickaël Salaün @ 2020-09-08 16:44 ` Mimi Zohar 2020-09-08 17:21 ` Mickaël Salaün 0 siblings, 1 reply; 23+ messages in thread From: Mimi Zohar @ 2020-09-08 16:44 UTC (permalink / raw) To: Mickaël Salaün, linux-kernel Cc: Aleksa Sarai, Alexei Starovoitov, Al Viro, Andrew Morton, Andy Lutomirski, Christian Brauner, Christian Heimes, Daniel Borkmann, Deven Bowers, Dmitry Vyukov, Eric Biggers, Eric Chiang, Florian Weimer, James Morris, Jan Kara, Jann Horn, Jonathan Corbet, Kees Cook, Lakshmi Ramasubramanian, Matthew Garrett, Matthew Wilcox, Michael Kerrisk, Miklos Szeredi, Philippe Trébuchet, Scott Shell, Sean Christopherson, Shuah Khan, Steve Dower, Steve Grubb, Tetsuo Handa, Thibaut Sautereau, Vincent Strubel, kernel-hardening, linux-api, linux-integrity, linux-security-module, linux-fsdevel, Thibaut Sautereau, Mickaël Salaün, Stephen Smalley, John Johansen On Tue, 2020-09-08 at 17:44 +0200, Mickaël Salaün wrote: > On 08/09/2020 17:24, Mimi Zohar wrote: > > On Tue, 2020-09-08 at 14:43 +0200, Mickaël Salaün wrote: > >> On 08/09/2020 14:28, Mimi Zohar wrote: > >>> Hi Mickael, > >>> > >>> On Tue, 2020-09-08 at 09:59 +0200, Mickaël Salaün wrote: > >>>> diff --git a/fs/open.c b/fs/open.c > >>>> index 9af548fb841b..879bdfbdc6fa 100644 > >>>> --- a/fs/open.c > >>>> +++ b/fs/open.c > >>>> @@ -405,9 +405,13 @@ static long do_faccessat(int dfd, const char __user *filename, int mode, int fla > >>>> if (mode & ~S_IRWXO) /* where's F_OK, X_OK, W_OK, R_OK? */ > >>>> return -EINVAL; > >>>> > >>>> - if (flags & ~(AT_EACCESS | AT_SYMLINK_NOFOLLOW | AT_EMPTY_PATH)) > >>>> + if (flags & ~(AT_EACCESS | AT_SYMLINK_NOFOLLOW | AT_EMPTY_PATH | > >>>> + AT_INTERPRETED)) > >>>> return -EINVAL; > >>>> > >>>> + /* Only allows X_OK with AT_INTERPRETED for now. */ > >>>> + if ((flags & AT_INTERPRETED) && !(mode & S_IXOTH)) > >>>> + return -EINVAL; > >>>> if (flags & AT_SYMLINK_NOFOLLOW) > >>>> lookup_flags &= ~LOOKUP_FOLLOW; > >>>> if (flags & AT_EMPTY_PATH) > >>>> @@ -426,7 +430,30 @@ static long do_faccessat(int dfd, const char __user *filename, int mode, int fla > >>>> > >>>> inode = d_backing_inode(path.dentry); > >>>> > >>>> - if ((mode & MAY_EXEC) && S_ISREG(inode->i_mode)) { > >>>> + if ((flags & AT_INTERPRETED)) { > >>>> + /* > >>>> + * For compatibility reasons, without a defined security policy > >>>> + * (via sysctl or LSM), using AT_INTERPRETED must map the > >>>> + * execute permission to the read permission. Indeed, from > >>>> + * user space point of view, being able to execute data (e.g. > >>>> + * scripts) implies to be able to read this data. > >>>> + * > >>>> + * The MAY_INTERPRETED_EXEC bit is set to enable LSMs to add > >>>> + * custom checks, while being compatible with current policies. > >>>> + */ > >>>> + if ((mode & MAY_EXEC)) { > >>> > >>> Why is the ISREG() test being dropped? Without dropping it, there > >>> would be no reason for making the existing test an "else" clause. > >> > >> The ISREG() is not dropped, it is just moved below with the rest of the > >> original code. The corresponding code (with the path_noexec call) for > >> AT_INTERPRETED is added with the next commit, and it relies on the > >> sysctl configuration for compatibility reasons. > > > > Dropping the S_ISREG() check here without an explanation is wrong and > > probably unsafe, as it is only re-added in the subsequent patch and > > only for the "sysctl_interpreted_access" case. Adding this new test > > after the existing test is probably safer. If the original test fails, > > it returns the same value as this test -EACCES. > > The original S_ISREG() is ANDed with a MAY_EXEC check and with > path_noexec(). The goal of this patch is indeed to have a different > behavior than the original faccessat2(2) thanks to the AT_INTERPRETED > flag. This can't work if we add the sysctl check after the current > path_noexec() check. Moreover, in this patch an exec check is translated > to a read check. This new behavior is harmless because using > AT_INTERPRETED with the current faccessat2(2) would return -EINVAL. The > current vanilla behavior is then unchanged. Don't get me wrong. I'm very interested in having this support and appreciate all the work you're doing on getting it upstreamed. With the change in this patch, I see the MAY_EXEC being changed to MAY_READ, but I don't see -EINVAL being returned. It sounds like this change is dependent on the faccessat2 version for -EINVAL to be returned. > > The whole point of this patch series is to have a policy which do not > break current systems and is easy to configure by the sysadmin through > sysctl. This patch series also enable LSMs to take advantage of it > without the current faccess* limitations. For instance, it is then > possible for an LSM to implement more complex policies which may allow > execution of data from pipes or sockets, while verifying the source of > this data. Enforcing S_ISREG() in this patch would forbid such policies > to be implemented. In the case of IMA, you may want to add the same > S_ISREG() check. > > > >> > >>> > >>>> + mode |= MAY_INTERPRETED_EXEC; > >>>> + /* > >>>> + * For compatibility reasons, if the system-wide policy > >>>> + * doesn't enforce file permission checks, then > >>>> + * replaces the execute permission request with a read > >>>> + * permission request. > >>>> + */ > >>>> + mode &= ~MAY_EXEC; > >>>> + /* To be executed *by* user space, files must be readable. */ > >>>> + mode |= MAY_READ; > > > > ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [RFC PATCH v8 1/3] fs: Introduce AT_INTERPRETED flag for faccessat2(2) 2020-09-08 16:44 ` Mimi Zohar @ 2020-09-08 17:21 ` Mickaël Salaün 0 siblings, 0 replies; 23+ messages in thread From: Mickaël Salaün @ 2020-09-08 17:21 UTC (permalink / raw) To: Mimi Zohar, linux-kernel Cc: Aleksa Sarai, Alexei Starovoitov, Al Viro, Andrew Morton, Andy Lutomirski, Christian Brauner, Christian Heimes, Daniel Borkmann, Deven Bowers, Dmitry Vyukov, Eric Biggers, Eric Chiang, Florian Weimer, James Morris, Jan Kara, Jann Horn, Jonathan Corbet, Kees Cook, Lakshmi Ramasubramanian, Matthew Garrett, Matthew Wilcox, Michael Kerrisk, Miklos Szeredi, Philippe Trébuchet, Scott Shell, Sean Christopherson, Shuah Khan, Steve Dower, Steve Grubb, Tetsuo Handa, Thibaut Sautereau, Vincent Strubel, kernel-hardening, linux-api, linux-integrity, linux-security-module, linux-fsdevel, Thibaut Sautereau, Mickaël Salaün, Stephen Smalley, John Johansen On 08/09/2020 18:44, Mimi Zohar wrote: > On Tue, 2020-09-08 at 17:44 +0200, Mickaël Salaün wrote: >> On 08/09/2020 17:24, Mimi Zohar wrote: >>> On Tue, 2020-09-08 at 14:43 +0200, Mickaël Salaün wrote: >>>> On 08/09/2020 14:28, Mimi Zohar wrote: >>>>> Hi Mickael, >>>>> >>>>> On Tue, 2020-09-08 at 09:59 +0200, Mickaël Salaün wrote: >>>>>> diff --git a/fs/open.c b/fs/open.c >>>>>> index 9af548fb841b..879bdfbdc6fa 100644 >>>>>> --- a/fs/open.c >>>>>> +++ b/fs/open.c >>>>>> @@ -405,9 +405,13 @@ static long do_faccessat(int dfd, const char __user *filename, int mode, int fla >>>>>> if (mode & ~S_IRWXO) /* where's F_OK, X_OK, W_OK, R_OK? */ >>>>>> return -EINVAL; >>>>>> >>>>>> - if (flags & ~(AT_EACCESS | AT_SYMLINK_NOFOLLOW | AT_EMPTY_PATH)) >>>>>> + if (flags & ~(AT_EACCESS | AT_SYMLINK_NOFOLLOW | AT_EMPTY_PATH | >>>>>> + AT_INTERPRETED)) >>>>>> return -EINVAL; >>>>>> >>>>>> + /* Only allows X_OK with AT_INTERPRETED for now. */ >>>>>> + if ((flags & AT_INTERPRETED) && !(mode & S_IXOTH)) >>>>>> + return -EINVAL; >>>>>> if (flags & AT_SYMLINK_NOFOLLOW) >>>>>> lookup_flags &= ~LOOKUP_FOLLOW; >>>>>> if (flags & AT_EMPTY_PATH) >>>>>> @@ -426,7 +430,30 @@ static long do_faccessat(int dfd, const char __user *filename, int mode, int fla >>>>>> >>>>>> inode = d_backing_inode(path.dentry); >>>>>> >>>>>> - if ((mode & MAY_EXEC) && S_ISREG(inode->i_mode)) { >>>>>> + if ((flags & AT_INTERPRETED)) { >>>>>> + /* >>>>>> + * For compatibility reasons, without a defined security policy >>>>>> + * (via sysctl or LSM), using AT_INTERPRETED must map the >>>>>> + * execute permission to the read permission. Indeed, from >>>>>> + * user space point of view, being able to execute data (e.g. >>>>>> + * scripts) implies to be able to read this data. >>>>>> + * >>>>>> + * The MAY_INTERPRETED_EXEC bit is set to enable LSMs to add >>>>>> + * custom checks, while being compatible with current policies. >>>>>> + */ >>>>>> + if ((mode & MAY_EXEC)) { >>>>> >>>>> Why is the ISREG() test being dropped? Without dropping it, there >>>>> would be no reason for making the existing test an "else" clause. >>>> >>>> The ISREG() is not dropped, it is just moved below with the rest of the >>>> original code. The corresponding code (with the path_noexec call) for >>>> AT_INTERPRETED is added with the next commit, and it relies on the >>>> sysctl configuration for compatibility reasons. >>> >>> Dropping the S_ISREG() check here without an explanation is wrong and >>> probably unsafe, as it is only re-added in the subsequent patch and >>> only for the "sysctl_interpreted_access" case. Adding this new test >>> after the existing test is probably safer. If the original test fails, >>> it returns the same value as this test -EACCES. >> >> The original S_ISREG() is ANDed with a MAY_EXEC check and with >> path_noexec(). The goal of this patch is indeed to have a different >> behavior than the original faccessat2(2) thanks to the AT_INTERPRETED >> flag. This can't work if we add the sysctl check after the current >> path_noexec() check. Moreover, in this patch an exec check is translated >> to a read check. This new behavior is harmless because using >> AT_INTERPRETED with the current faccessat2(2) would return -EINVAL. The >> current vanilla behavior is then unchanged. > > Don't get me wrong. I'm very interested in having this support and > appreciate all the work you're doing on getting it upstreamed. With > the change in this patch, I see the MAY_EXEC being changed to MAY_READ, > but I don't see -EINVAL being returned. It sounds like this change is > dependent on the faccessat2 version for -EINVAL to be returned. No worries, unfortunately the patch format doesn't ease this review. :) access(2) and faccessat(2) have a flag value of 0. Only faccessat2(2) takes a flag from userspace. The -EINVAL is currently returned (by faccessat2) if there is an unknown flag provided by userspace. With this patch, only a mode equal to X_OK is allowed for the AT_INTERPRETED flag (cf. second hunk in this patch). As described in the cover letter, we could handle the other modes in the future though. > >> >> The whole point of this patch series is to have a policy which do not >> break current systems and is easy to configure by the sysadmin through >> sysctl. This patch series also enable LSMs to take advantage of it >> without the current faccess* limitations. For instance, it is then >> possible for an LSM to implement more complex policies which may allow >> execution of data from pipes or sockets, while verifying the source of >> this data. Enforcing S_ISREG() in this patch would forbid such policies >> to be implemented. In the case of IMA, you may want to add the same >> S_ISREG() check. > >>> >>>> >>>>> >>>>>> + mode |= MAY_INTERPRETED_EXEC; >>>>>> + /* >>>>>> + * For compatibility reasons, if the system-wide policy >>>>>> + * doesn't enforce file permission checks, then >>>>>> + * replaces the execute permission request with a read >>>>>> + * permission request. >>>>>> + */ >>>>>> + mode &= ~MAY_EXEC; >>>>>> + /* To be executed *by* user space, files must be readable. */ >>>>>> + mode |= MAY_READ; >>> >>> > > ^ permalink raw reply [flat|nested] 23+ messages in thread
* [RFC PATCH v8 2/3] fs,doc: Enable to configure exec checks for AT_INTERPRETED 2020-09-08 7:59 [RFC PATCH v8 0/3] Add support for AT_INTERPRETED (was O_MAYEXEC) Mickaël Salaün 2020-09-08 7:59 ` [RFC PATCH v8 1/3] fs: Introduce AT_INTERPRETED flag for faccessat2(2) Mickaël Salaün @ 2020-09-08 7:59 ` Mickaël Salaün 2020-09-08 7:59 ` [RFC PATCH v8 3/3] selftest/interpreter: Add tests for AT_INTERPRETED enforcing Mickaël Salaün 2020-09-08 18:50 ` [RFC PATCH v8 0/3] Add support for AT_INTERPRETED (was O_MAYEXEC) Al Viro 3 siblings, 0 replies; 23+ messages in thread From: Mickaël Salaün @ 2020-09-08 7:59 UTC (permalink / raw) To: linux-kernel Cc: Mickaël Salaün, Aleksa Sarai, Alexei Starovoitov, Al Viro, Andrew Morton, Andy Lutomirski, Christian Brauner, Christian Heimes, Daniel Borkmann, Deven Bowers, Dmitry Vyukov, Eric Biggers, Eric Chiang, Florian Weimer, James Morris, Jan Kara, Jann Horn, Jonathan Corbet, Kees Cook, Lakshmi Ramasubramanian, Matthew Garrett, Matthew Wilcox, Michael Kerrisk, Miklos Szeredi, Mimi Zohar, Philippe Trébuchet, Scott Shell, Sean Christopherson, Shuah Khan, Steve Dower, Steve Grubb, Tetsuo Handa, Thibaut Sautereau, Vincent Strubel, kernel-hardening, linux-api, linux-integrity, linux-security-module, linux-fsdevel, Mickaël Salaün, Thibaut Sautereau From: Mickaël Salaün <mic@linux.microsoft.com> This enables to configure a policy for executable scripts which can be queried with faccessat2(2) and the AT_INTERPRETED flag. This may allow script interpreters to check execution permission before reading commands from a file, or dynamic linkers to allow shared object loading. This may be seen as a way for a trusted task (e.g. interpreter) to check the trustworthiness of files (e.g. scripts) before extending its control flow graph with new ones originating from these files. Add a new sysctl fs.interpreted_access 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. 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 AT_INTERPRETED flag combined with X_OK mode is a mean to enforce a system-wide security policy (but not application-centric policies), it does not make sense for user space to check the sysctl value. Indeed, this new flag only enables to extend the system ability to enforce a policy thanks to (some trusted) user space 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@linux.microsoft.com> Reviewed-by: Thibaut Sautereau <thibaut.sautereau@ssi.gouv.fr> Cc: Al Viro <viro@zeniv.linux.org.uk> Cc: Andrew Morton <akpm@linux-foundation.org> Cc: Jann Horn <jannh@google.com> Cc: Jonathan Corbet <corbet@lwn.net> Cc: Kees Cook <keescook@chromium.org> Cc: Miklos Szeredi <mszeredi@redhat.com> --- Changes since v7: * Handle special file descriptors. * Add a compatibility mode for execute/read check. * Move the sysctl policy from fs/namei.c to fs/open.c for the new faccessat2/AT_INTERPRETED. * Rename the sysctl from fs.open_mayexec_enforce to fs.interpreted_access . * Update documentation accordingly. 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 | 54 +++++++++++++++++++++++++ fs/open.c | 38 ++++++++++++++++- include/linux/fs.h | 1 + kernel/sysctl.c | 12 +++++- 4 files changed, 102 insertions(+), 3 deletions(-) diff --git a/Documentation/admin-guide/sysctl/fs.rst b/Documentation/admin-guide/sysctl/fs.rst index f48277a0a850..66d1c1bd67a5 100644 --- a/Documentation/admin-guide/sysctl/fs.rst +++ b/Documentation/admin-guide/sysctl/fs.rst @@ -36,6 +36,7 @@ Currently, these files are in /proc/sys/fs: - inode-max - inode-nr - inode-state +- interpreted_access - nr_open - overflowuid - overflowgid @@ -165,6 +166,59 @@ system needs to prune the inode list instead of allocating more. +interpreted_access +------------------ + +The ``AT_INTERPRETED`` flag with an ``X_OK`` mode can be passed to +:manpage:`faccessat2(2)` by an interpreter to check that regular files 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. + +To avoid race-conditions, it is highly recommended to first open the file and +then do the check on the new file descriptor thanks to the ``AT_EMPTY_PATH`` +flag. + +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 :manpage:`faccessat2(2)` and ``AT_INTERPRETED``, 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.interpreted_access`` 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 file is marked as + executable for the current process (e.g., POSIX permissions, ACLs). + +Note that as long as a policy is enforced, checking any non-regular file with +``AT_INTERPRETED`` returns -EINVAL (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/interpreter/interpreted_access_test.c and interpreter +patches (for the original O_MAYEXEC) are available 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 ------------------------- diff --git a/fs/open.c b/fs/open.c index 879bdfbdc6fa..ef01ab35449d 100644 --- a/fs/open.c +++ b/fs/open.c @@ -32,6 +32,7 @@ #include <linux/ima.h> #include <linux/dnotify.h> #include <linux/compat.h> +#include <linux/sysctl.h> #include "internal.h" @@ -394,6 +395,11 @@ static const struct cred *access_override_creds(void) return old_cred; } +#define INTERPRETED_EXEC_MOUNT BIT(0) +#define INTERPRETED_EXEC_FILE BIT(1) + +int sysctl_interpreted_access __read_mostly; + static long do_faccessat(int dfd, const char __user *filename, int mode, int flags) { struct path path; @@ -443,13 +449,43 @@ static long do_faccessat(int dfd, const char __user *filename, int mode, int fla */ if ((mode & MAY_EXEC)) { mode |= MAY_INTERPRETED_EXEC; + res = -EACCES; + /* + * If there is a system-wide execute policy enforced, + * then forbids access to non-regular files and special + * superblocks. + */ + if ((sysctl_interpreted_access & (INTERPRETED_EXEC_MOUNT | + INTERPRETED_EXEC_FILE))) { + if (!S_ISREG(inode->i_mode)) + goto out_path_release; + /* + * Denies access to pseudo filesystems that + * will never be mountable (e.g. sockfs, + * pipefs) but can still be reachable through + * /proc/self/fd, or memfd-like file + * descriptors, or nsfs-like files. + * + * According to the tests, SB_NOEXEC seems to + * be only used by proc and nsfs filesystems. + * Is it correct? + */ + if ((path.dentry->d_sb->s_flags & + (SB_NOUSER | SB_KERNMOUNT | SB_NOEXEC))) + goto out_path_release; + } + + if ((sysctl_interpreted_access & INTERPRETED_EXEC_MOUNT) && + path_noexec(&path)) + goto out_path_release; /* * For compatibility reasons, if the system-wide policy * doesn't enforce file permission checks, then * replaces the execute permission request with a read * permission request. */ - mode &= ~MAY_EXEC; + if (!(sysctl_interpreted_access & INTERPRETED_EXEC_FILE)) + mode &= ~MAY_EXEC; /* To be executed *by* user space, files must be readable. */ mode |= MAY_READ; } diff --git a/include/linux/fs.h b/include/linux/fs.h index 03f1b2da6a87..ef39550f2464 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -83,6 +83,7 @@ extern int sysctl_protected_symlinks; extern int sysctl_protected_hardlinks; extern int sysctl_protected_fifos; extern int sysctl_protected_regular; +extern int sysctl_interpreted_access; typedef __kernel_rwf_t rwf_t; diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 09e70ee2332e..899fa52b4ee8 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -113,6 +113,7 @@ static int sixty = 60; static int __maybe_unused neg_one = -1; static int __maybe_unused two = 2; +static int __maybe_unused three = 3; static int __maybe_unused four = 4; static unsigned long zero_ul; static unsigned long one_ul = 1; @@ -887,7 +888,6 @@ static int proc_taint(struct ctl_table *table, int write, return err; } -#ifdef CONFIG_PRINTK static int proc_dointvec_minmax_sysadmin(struct ctl_table *table, int write, void *buffer, size_t *lenp, loff_t *ppos) { @@ -896,7 +896,6 @@ static int proc_dointvec_minmax_sysadmin(struct ctl_table *table, int write, return proc_dointvec_minmax(table, write, buffer, lenp, ppos); } -#endif /** * struct do_proc_dointvec_minmax_conv_param - proc_dointvec_minmax() range checking structure @@ -3293,6 +3292,15 @@ static struct ctl_table fs_table[] = { .extra1 = SYSCTL_ZERO, .extra2 = &two, }, + { + .procname = "interpreted_access", + .data = &sysctl_interpreted_access, + .maxlen = sizeof(int), + .mode = 0600, + .proc_handler = proc_dointvec_minmax_sysadmin, + .extra1 = SYSCTL_ZERO, + .extra2 = &three, + }, #if defined(CONFIG_BINFMT_MISC) || defined(CONFIG_BINFMT_MISC_MODULE) { .procname = "binfmt_misc", -- 2.28.0 ^ permalink raw reply related [flat|nested] 23+ messages in thread
* [RFC PATCH v8 3/3] selftest/interpreter: Add tests for AT_INTERPRETED enforcing 2020-09-08 7:59 [RFC PATCH v8 0/3] Add support for AT_INTERPRETED (was O_MAYEXEC) Mickaël Salaün 2020-09-08 7:59 ` [RFC PATCH v8 1/3] fs: Introduce AT_INTERPRETED flag for faccessat2(2) Mickaël Salaün 2020-09-08 7:59 ` [RFC PATCH v8 2/3] fs,doc: Enable to configure exec checks for AT_INTERPRETED Mickaël Salaün @ 2020-09-08 7:59 ` Mickaël Salaün 2020-09-08 18:50 ` [RFC PATCH v8 0/3] Add support for AT_INTERPRETED (was O_MAYEXEC) Al Viro 3 siblings, 0 replies; 23+ messages in thread From: Mickaël Salaün @ 2020-09-08 7:59 UTC (permalink / raw) To: linux-kernel Cc: Mickaël Salaün, Aleksa Sarai, Alexei Starovoitov, Al Viro, Andrew Morton, Andy Lutomirski, Christian Brauner, Christian Heimes, Daniel Borkmann, Deven Bowers, Dmitry Vyukov, Eric Biggers, Eric Chiang, Florian Weimer, James Morris, Jan Kara, Jann Horn, Jonathan Corbet, Kees Cook, Lakshmi Ramasubramanian, Matthew Garrett, Matthew Wilcox, Michael Kerrisk, Miklos Szeredi, Mimi Zohar, Philippe Trébuchet, Scott Shell, Sean Christopherson, Shuah Khan, Steve Dower, Steve Grubb, Tetsuo Handa, Thibaut Sautereau, Vincent Strubel, kernel-hardening, linux-api, linux-integrity, linux-security-module, linux-fsdevel, Mickaël Salaün, Thibaut Sautereau From: Mickaël Salaün <mic@linux.microsoft.com> Test that checks performed by faccessat2(2) with AT_INTERPRETED on file path and file descriptors are consistent with noexec mount points and file execute permissions, according to the policy configured with the fs.interpreted_access sysctl. Signed-off-by: Mickaël Salaün <mic@linux.microsoft.com> Reviewed-by: Thibaut Sautereau <thibaut.sautereau@ssi.gouv.fr> Cc: Al Viro <viro@zeniv.linux.org.uk> Cc: Andrew Morton <akpm@linux-foundation.org> Cc: Jann Horn <jannh@google.com> Cc: Kees Cook <keescook@chromium.org> Cc: Miklos Szeredi <mszeredi@redhat.com> Cc: Shuah Khan <shuah@kernel.org> --- Changes since v7: * Update tests with faccessat2/AT_INTERPRETED, including new ones to check that setting R_OK or W_OK returns EINVAL. * Add tests for memfd, pipefs and nsfs. * Rename and move back tests to a standalone directory. 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. --- .../testing/selftests/interpreter/.gitignore | 2 + tools/testing/selftests/interpreter/Makefile | 18 + tools/testing/selftests/interpreter/config | 1 + .../interpreter/interpreted_access_test.c | 384 ++++++++++++++++++ 4 files changed, 405 insertions(+) create mode 100644 tools/testing/selftests/interpreter/.gitignore create mode 100644 tools/testing/selftests/interpreter/Makefile create mode 100644 tools/testing/selftests/interpreter/config create mode 100644 tools/testing/selftests/interpreter/interpreted_access_test.c diff --git a/tools/testing/selftests/interpreter/.gitignore b/tools/testing/selftests/interpreter/.gitignore new file mode 100644 index 000000000000..82a4846cbc4b --- /dev/null +++ b/tools/testing/selftests/interpreter/.gitignore @@ -0,0 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0-only +/*_test diff --git a/tools/testing/selftests/interpreter/Makefile b/tools/testing/selftests/interpreter/Makefile new file mode 100644 index 000000000000..6b3e8c3e533b --- /dev/null +++ b/tools/testing/selftests/interpreter/Makefile @@ -0,0 +1,18 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + +CFLAGS += -Wall -O2 +LDLIBS += -lcap + +src_test := $(wildcard *_test.c) +TEST_GEN_PROGS := $(src_test:.c=) + +KSFT_KHDR_INSTALL := 1 +include ../lib.mk + +khdr_dir = $(top_srcdir)/usr/include + +$(khdr_dir)/asm-generic/unistd.h: khdr + @: + +$(OUTPUT)/%_test: %_test.c $(khdr_dir)/asm-generic/unistd.h ../kselftest_harness.h + $(LINK.c) $< $(LDLIBS) -o $@ -I$(khdr_dir) diff --git a/tools/testing/selftests/interpreter/config b/tools/testing/selftests/interpreter/config new file mode 100644 index 000000000000..dd53c266bf52 --- /dev/null +++ b/tools/testing/selftests/interpreter/config @@ -0,0 +1 @@ +CONFIG_SYSCTL=y diff --git a/tools/testing/selftests/interpreter/interpreted_access_test.c b/tools/testing/selftests/interpreter/interpreted_access_test.c new file mode 100644 index 000000000000..6458dccabe51 --- /dev/null +++ b/tools/testing/selftests/interpreter/interpreted_access_test.c @@ -0,0 +1,384 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Test AT_INTERPRETED + * + * Copyright © 2018-2020 ANSSI + * + * Author: Mickaël Salaün <mic@digikod.net> + */ + +#define _GNU_SOURCE +#include <asm-generic/unistd.h> +#include <errno.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <sys/capability.h> +#include <sys/mman.h> +#include <sys/mount.h> +#include <sys/stat.h> +#include <sys/syscall.h> +#include <sys/sysmacros.h> +#include <unistd.h> + +#include "../kselftest_harness.h" + +#ifndef AT_INTERPRETED +#define AT_INTERPRETED 0x400 +#endif + +#ifndef faccessat2 +static int faccessat2(int dirfd, const char *pathname, int mode, int flags) +{ + errno = 0; + return syscall(__NR_faccessat2, dirfd, pathname, mode, flags); +} +#endif + +static const char sysctl_path[] = "/proc/sys/fs/interpreted_access"; + +static const char workdir_path[] = "./test-mount"; +static const char reg_file_path[] = "./test-mount/regular_file"; +static const char dir_path[] = "./test-mount/directory"; +static const char symlink_path[] = "./test-mount/symlink"; +static const char block_dev_path[] = "./test-mount/block_device"; +static const char char_dev_path[] = "./test-mount/character_device"; +static const char fifo_path[] = "./test-mount/fifo"; +static const char sock_path[] = "./test-mount/socket"; + +static void ignore_dac(struct __test_metadata *_metadata, int override) +{ + cap_t caps; + const cap_value_t cap_val[2] = { + CAP_DAC_OVERRIDE, + CAP_DAC_READ_SEARCH, + }; + + caps = cap_get_proc(); + ASSERT_NE(NULL, caps); + ASSERT_EQ(0, cap_set_flag(caps, CAP_EFFECTIVE, 2, cap_val, + override ? CAP_SET : CAP_CLEAR)); + ASSERT_EQ(0, cap_set_proc(caps)); + EXPECT_EQ(0, cap_free(caps)); +} + +static void ignore_sys_admin(struct __test_metadata *_metadata, int override) +{ + cap_t caps; + const cap_value_t cap_val[1] = { + CAP_SYS_ADMIN, + }; + + caps = cap_get_proc(); + ASSERT_NE(NULL, caps); + ASSERT_EQ(0, cap_set_flag(caps, CAP_EFFECTIVE, 1, cap_val, + override ? CAP_SET : CAP_CLEAR)); + ASSERT_EQ(0, cap_set_proc(caps)); + EXPECT_EQ(0, cap_free(caps)); +} + +static void test_omx(struct __test_metadata *_metadata, + const char *const path, const int err_open, + const int err_access) +{ + int flags = O_RDONLY | O_NOFOLLOW | O_CLOEXEC; + int fd, access_ret, access_errno; + + /* Do not block on pipes. */ + if (path == fifo_path) + flags |= O_NONBLOCK; + + fd = open(path, flags); + if (err_open) { + ASSERT_EQ(err_open, errno) { + TH_LOG("Wrong error for open %s: %s", path, strerror(errno)); + } + ASSERT_EQ(-1, fd); + } else { + ASSERT_LE(0, fd) { + TH_LOG("Failed to open %s: %s", path, strerror(errno)); + } + access_ret = faccessat2(fd, "", X_OK, AT_EMPTY_PATH | AT_INTERPRETED); + access_errno = errno; + EXPECT_EQ(0, close(fd)); + if (err_access) { + ASSERT_EQ(err_access, access_errno) { + TH_LOG("Wrong error for faccessat2 w/o path %s: %s", + path, strerror(access_errno)); + } + ASSERT_EQ(-1, access_ret); + } else { + ASSERT_EQ(0, access_ret) { + TH_LOG("Access denied for %s: %s", path, strerror(access_errno)); + } + } + } + + access_ret = faccessat2(AT_FDCWD, path, X_OK, AT_SYMLINK_NOFOLLOW | AT_INTERPRETED); + if (err_access) { + ASSERT_EQ(err_access, errno) { + TH_LOG("Wrong error for faccessat2 w/ path %s: %s", path, strerror(errno)); + } + ASSERT_EQ(-1, access_ret); + } else { + ASSERT_EQ(0, access_ret) { + TH_LOG("Access denied for %s: %s", path, strerror(errno)); + } + } + + /* Tests read access. */ + access_ret = faccessat2(AT_FDCWD, path, R_OK, AT_SYMLINK_NOFOLLOW | AT_INTERPRETED); + ASSERT_EQ(-1, access_ret); + ASSERT_EQ(EINVAL, errno); + + /* Tests write access. */ + access_ret = faccessat2(AT_FDCWD, path, W_OK, AT_SYMLINK_NOFOLLOW | AT_INTERPRETED); + ASSERT_EQ(-1, access_ret); + ASSERT_EQ(EINVAL, errno); +} + +static void test_policy_fd(struct __test_metadata *_metadata, const int fd, + const bool has_policy) +{ + const int ret = faccessat2(fd, "", X_OK, AT_EMPTY_PATH | AT_INTERPRETED); + + if (has_policy) { + ASSERT_EQ(-1, ret); + ASSERT_EQ(EACCES, errno) { + TH_LOG("Wrong error for faccessat2 with an FD: %s", strerror(errno)); + } + } else { + ASSERT_EQ(0, ret) { + TH_LOG("Access denied for an FD: %s", strerror(errno)); + } + } +} + +FIXTURE(access) { + char initial_sysctl_value; + int memfd, pipefd; + int pipe_fds[2]; +}; + +static void test_file_types(struct __test_metadata *_metadata, FIXTURE_DATA(access) *self, + const int err_code, const bool has_policy) +{ + /* Tests are performed on a tmpfs mount point. */ + test_omx(_metadata, reg_file_path, 0, err_code); + test_omx(_metadata, dir_path, 0, has_policy ? EACCES : 0); + test_omx(_metadata, symlink_path, ELOOP, has_policy ? EACCES : 0); + test_omx(_metadata, block_dev_path, 0, has_policy ? EACCES : 0); + test_omx(_metadata, char_dev_path, 0, has_policy ? EACCES : 0); + test_omx(_metadata, fifo_path, 0, has_policy ? EACCES : 0); + test_omx(_metadata, sock_path, ENXIO, has_policy ? EACCES : 0); + + test_omx(_metadata, "/proc/self/ns/mnt", ELOOP, has_policy ? EACCES : 0); + + /* Checks that exec is denied for any memfd. */ + test_policy_fd(_metadata, self->memfd, has_policy); + + /* Checks that exec is denied for any pipefs fd. */ + test_policy_fd(_metadata, self->pipefd, has_policy); +} + +static void test_files(struct __test_metadata *_metadata, FIXTURE_DATA(access) *self, + const int err_code, const bool has_policy) +{ + /* Tests as root. */ + ignore_dac(_metadata, 1); + test_file_types(_metadata, self, err_code, has_policy); + + /* Tests without bypass. */ + ignore_dac(_metadata, 0); + test_file_types(_metadata, self, err_code, has_policy); +} + +static void sysctl_write_char(struct __test_metadata *_metadata, const char value) +{ + int fd; + + fd = open(sysctl_path, O_WRONLY | O_CLOEXEC); + ASSERT_LE(0, fd); + ASSERT_EQ(1, write(fd, &value, 1)); + EXPECT_EQ(0, close(fd)); +} + +static char sysctl_read_char(struct __test_metadata *_metadata) +{ + int fd; + char sysctl_value; + + fd = open(sysctl_path, O_RDONLY | O_CLOEXEC); + ASSERT_LE(0, fd); + ASSERT_EQ(1, read(fd, &sysctl_value, 1)); + EXPECT_EQ(0, close(fd)); + return sysctl_value; +} + +FIXTURE_VARIANT(access) { + const bool mount_exec; + const bool file_exec; + const int sysctl_err_code[3]; +}; + +FIXTURE_VARIANT_ADD(access, mount_exec_file_exec) { + .mount_exec = true, + .file_exec = true, + .sysctl_err_code = {0, 0, 0}, +}; + +FIXTURE_VARIANT_ADD(access, mount_exec_file_noexec) +{ + .mount_exec = true, + .file_exec = false, + .sysctl_err_code = {0, EACCES, EACCES}, +}; + +FIXTURE_VARIANT_ADD(access, mount_noexec_file_exec) +{ + .mount_exec = false, + .file_exec = true, + .sysctl_err_code = {EACCES, 0, EACCES}, +}; + +FIXTURE_VARIANT_ADD(access, mount_noexec_file_noexec) +{ + .mount_exec = false, + .file_exec = false, + .sysctl_err_code = {EACCES, EACCES, EACCES}, +}; + +FIXTURE_SETUP(access) +{ + int procfd_path_size; + static const char path_template[] = "/proc/self/fd/%d"; + char procfd_path[sizeof(path_template) + 10]; + + /* + * Cleans previous workspace if any error previously happened (don't + * check errors). + */ + umount(workdir_path); + rmdir(workdir_path); + + /* Creates a clean mount point. */ + ASSERT_EQ(0, mkdir(workdir_path, 00700)); + ASSERT_EQ(0, mount("test", workdir_path, "tmpfs", MS_MGC_VAL | + (variant->mount_exec ? 0 : MS_NOEXEC), + "mode=0700,size=4k")); + + /* Creates a regular file. */ + ASSERT_EQ(0, mknod(reg_file_path, S_IFREG | (variant->file_exec ? 0500 : 0400), 0)); + /* Creates a directory. */ + ASSERT_EQ(0, mkdir(dir_path, variant->file_exec ? 0500 : 0400)); + /* Creates a symlink pointing to the regular file. */ + ASSERT_EQ(0, symlink("regular_file", symlink_path)); + /* Creates a character device: /dev/null. */ + ASSERT_EQ(0, mknod(char_dev_path, S_IFCHR | 0400, makedev(1, 3))); + /* Creates a block device: /dev/loop0 */ + ASSERT_EQ(0, mknod(block_dev_path, S_IFBLK | 0400, makedev(7, 0))); + /* Creates a fifo. */ + ASSERT_EQ(0, mknod(fifo_path, S_IFIFO | 0400, 0)); + /* Creates a socket. */ + ASSERT_EQ(0, mknod(sock_path, S_IFSOCK | 0400, 0)); + + /* Creates a regular file without user mount point. */ + self->memfd = memfd_create("test-interpreted", MFD_CLOEXEC); + ASSERT_LE(0, self->memfd); + /* Sets mode, which must be ignored by the exec check. */ + ASSERT_EQ(0, fchmod(self->memfd, variant->file_exec ? 0500 : 0400)); + + /* Creates a pipefs file descriptor. */ + ASSERT_EQ(0, pipe(self->pipe_fds)); + procfd_path_size = snprintf(procfd_path, sizeof(procfd_path), + path_template, self->pipe_fds[0]); + ASSERT_LT(procfd_path_size, sizeof(procfd_path)); + self->pipefd = open(procfd_path, O_RDONLY | O_CLOEXEC); + ASSERT_LE(0, self->pipefd); + ASSERT_EQ(0, fchmod(self->pipefd, variant->file_exec ? 0500 : 0400)); + + /* Saves initial sysctl value. */ + self->initial_sysctl_value = sysctl_read_char(_metadata); + + /* Prepares for sysctl writes. */ + ignore_sys_admin(_metadata, 1); +} + +FIXTURE_TEARDOWN(access) +{ + EXPECT_EQ(0, close(self->memfd)); + EXPECT_EQ(0, close(self->pipefd)); + EXPECT_EQ(0, close(self->pipe_fds[0])); + EXPECT_EQ(0, close(self->pipe_fds[1])); + + /* Restores initial sysctl value. */ + sysctl_write_char(_metadata, self->initial_sysctl_value); + + /* There is no need to unlink the test files. */ + ASSERT_EQ(0, umount(workdir_path)); + ASSERT_EQ(0, rmdir(workdir_path)); +} + +TEST_F(access, sysctl_0) +{ + /* Do not enforce anything. */ + sysctl_write_char(_metadata, '0'); + test_files(_metadata, self, 0, false); +} + +TEST_F(access, sysctl_1) +{ + /* Enforces mount exec check. */ + sysctl_write_char(_metadata, '1'); + test_files(_metadata, self, variant->sysctl_err_code[0], true); +} + +TEST_F(access, sysctl_2) +{ + /* Enforces file exec check. */ + sysctl_write_char(_metadata, '2'); + test_files(_metadata, self, variant->sysctl_err_code[1], true); +} + +TEST_F(access, sysctl_3) +{ + /* Enforces mount and file exec check. */ + sysctl_write_char(_metadata, '3'); + test_files(_metadata, self, variant->sysctl_err_code[2], true); +} + +FIXTURE(cleanup) { + char initial_sysctl_value; +}; + +FIXTURE_SETUP(cleanup) +{ + /* Saves initial sysctl value. */ + self->initial_sysctl_value = sysctl_read_char(_metadata); +} + +FIXTURE_TEARDOWN(cleanup) +{ + /* Restores initial sysctl value. */ + ignore_sys_admin(_metadata, 1); + sysctl_write_char(_metadata, self->initial_sysctl_value); +} + +TEST_F(cleanup, sysctl_access_write) +{ + int fd; + ssize_t ret; + + ignore_sys_admin(_metadata, 1); + sysctl_write_char(_metadata, '0'); + + ignore_sys_admin(_metadata, 0); + fd = open(sysctl_path, O_WRONLY | O_CLOEXEC); + ASSERT_LE(0, fd); + ret = write(fd, "0", 1); + ASSERT_EQ(-1, ret); + ASSERT_EQ(EPERM, errno); + EXPECT_EQ(0, close(fd)); +} + +TEST_HARNESS_MAIN -- 2.28.0 ^ permalink raw reply related [flat|nested] 23+ messages in thread
* Re: [RFC PATCH v8 0/3] Add support for AT_INTERPRETED (was O_MAYEXEC) 2020-09-08 7:59 [RFC PATCH v8 0/3] Add support for AT_INTERPRETED (was O_MAYEXEC) Mickaël Salaün ` (2 preceding siblings ...) 2020-09-08 7:59 ` [RFC PATCH v8 3/3] selftest/interpreter: Add tests for AT_INTERPRETED enforcing Mickaël Salaün @ 2020-09-08 18:50 ` Al Viro 2020-09-09 7:19 ` Mickaël Salaün 3 siblings, 1 reply; 23+ messages in thread From: Al Viro @ 2020-09-08 18:50 UTC (permalink / raw) To: Mickaël Salaün Cc: linux-kernel, Aleksa Sarai, Alexei Starovoitov, Andrew Morton, Andy Lutomirski, Christian Brauner, Christian Heimes, Daniel Borkmann, Deven Bowers, Dmitry Vyukov, Eric Biggers, Eric Chiang, Florian Weimer, James Morris, Jan Kara, Jann Horn, Jonathan Corbet, Kees Cook, Lakshmi Ramasubramanian, Matthew Garrett, Matthew Wilcox, Michael Kerrisk, Miklos Szeredi, Mimi Zohar, Philippe Trébuchet, Scott Shell, Sean Christopherson, Shuah Khan, Steve Dower, Steve Grubb, Tetsuo Handa, Thibaut Sautereau, Vincent Strubel, kernel-hardening, linux-api, linux-integrity, linux-security-module, linux-fsdevel On Tue, Sep 08, 2020 at 09:59:53AM +0200, Mickaël Salaün wrote: > Hi, > > This height patch series rework the previous O_MAYEXEC series by not > adding a new flag to openat2(2) but to faccessat2(2) instead. As > suggested, this enables to perform the access check on a file descriptor > instead of on a file path (while opening it). This may require two > checks (one on open and then with faccessat2) but it is a more generic > approach [8]. Again, why is that folded into lookup/open/whatnot, rather than being an operation applied to a file (e.g. O_PATH one)? ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [RFC PATCH v8 0/3] Add support for AT_INTERPRETED (was O_MAYEXEC) 2020-09-08 18:50 ` [RFC PATCH v8 0/3] Add support for AT_INTERPRETED (was O_MAYEXEC) Al Viro @ 2020-09-09 7:19 ` Mickaël Salaün 2020-09-09 17:08 ` Matthew Wilcox 2020-09-09 17:13 ` Al Viro 0 siblings, 2 replies; 23+ messages in thread From: Mickaël Salaün @ 2020-09-09 7:19 UTC (permalink / raw) To: Al Viro Cc: linux-kernel, Aleksa Sarai, Alexei Starovoitov, Andrew Morton, Andy Lutomirski, Christian Brauner, Christian Heimes, Daniel Borkmann, Deven Bowers, Dmitry Vyukov, Eric Biggers, Eric Chiang, Florian Weimer, James Morris, Jan Kara, Jann Horn, Jonathan Corbet, Kees Cook, Lakshmi Ramasubramanian, Matthew Garrett, Matthew Wilcox, Michael Kerrisk, Miklos Szeredi, Mimi Zohar, Philippe Trébuchet, Scott Shell, Sean Christopherson, Shuah Khan, Steve Dower, Steve Grubb, Tetsuo Handa, Thibaut Sautereau, Vincent Strubel, kernel-hardening, linux-api, linux-integrity, linux-security-module, linux-fsdevel On 08/09/2020 20:50, Al Viro wrote: > On Tue, Sep 08, 2020 at 09:59:53AM +0200, Mickaël Salaün wrote: >> Hi, >> >> This height patch series rework the previous O_MAYEXEC series by not >> adding a new flag to openat2(2) but to faccessat2(2) instead. As >> suggested, this enables to perform the access check on a file descriptor >> instead of on a file path (while opening it). This may require two >> checks (one on open and then with faccessat2) but it is a more generic >> approach [8]. > > Again, why is that folded into lookup/open/whatnot, rather than being > an operation applied to a file (e.g. O_PATH one)? > I don't understand your question. AT_INTERPRETED can and should be used with AT_EMPTY_PATH. The two checks I wrote about was for IMA. ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [RFC PATCH v8 0/3] Add support for AT_INTERPRETED (was O_MAYEXEC) 2020-09-09 7:19 ` Mickaël Salaün @ 2020-09-09 17:08 ` Matthew Wilcox 2020-09-09 17:55 ` Mickaël Salaün 2020-09-10 9:26 ` Thibaut Sautereau 2020-09-09 17:13 ` Al Viro 1 sibling, 2 replies; 23+ messages in thread From: Matthew Wilcox @ 2020-09-09 17:08 UTC (permalink / raw) To: Mickaël Salaün Cc: Al Viro, linux-kernel, Aleksa Sarai, Alexei Starovoitov, Andrew Morton, Andy Lutomirski, Christian Brauner, Christian Heimes, Daniel Borkmann, Deven Bowers, Dmitry Vyukov, Eric Biggers, Eric Chiang, Florian Weimer, James Morris, Jan Kara, Jann Horn, Jonathan Corbet, Kees Cook, Lakshmi Ramasubramanian, Matthew Garrett, Michael Kerrisk, Miklos Szeredi, Mimi Zohar, Philippe Trébuchet, Scott Shell, Sean Christopherson, Shuah Khan, Steve Dower, Steve Grubb, Tetsuo Handa, Thibaut Sautereau, Vincent Strubel, kernel-hardening, linux-api, linux-integrity, linux-security-module, linux-fsdevel On Wed, Sep 09, 2020 at 09:19:11AM +0200, Mickaël Salaün wrote: > > On 08/09/2020 20:50, Al Viro wrote: > > On Tue, Sep 08, 2020 at 09:59:53AM +0200, Mickaël Salaün wrote: > >> Hi, > >> > >> This height patch series rework the previous O_MAYEXEC series by not > >> adding a new flag to openat2(2) but to faccessat2(2) instead. As > >> suggested, this enables to perform the access check on a file descriptor > >> instead of on a file path (while opening it). This may require two > >> checks (one on open and then with faccessat2) but it is a more generic > >> approach [8]. > > > > Again, why is that folded into lookup/open/whatnot, rather than being > > an operation applied to a file (e.g. O_PATH one)? > > I don't understand your question. AT_INTERPRETED can and should be used > with AT_EMPTY_PATH. The two checks I wrote about was for IMA. Al is saying you should add a new syscall, not try to fold it into some existing syscall. I agree with him. Add a new syscall, just like you were told to do it last time. ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [RFC PATCH v8 0/3] Add support for AT_INTERPRETED (was O_MAYEXEC) 2020-09-09 17:08 ` Matthew Wilcox @ 2020-09-09 17:55 ` Mickaël Salaün 2020-09-10 9:26 ` Thibaut Sautereau 1 sibling, 0 replies; 23+ messages in thread From: Mickaël Salaün @ 2020-09-09 17:55 UTC (permalink / raw) To: Matthew Wilcox Cc: Al Viro, linux-kernel, Aleksa Sarai, Alexei Starovoitov, Andrew Morton, Andy Lutomirski, Christian Brauner, Christian Heimes, Daniel Borkmann, Deven Bowers, Dmitry Vyukov, Eric Biggers, Eric Chiang, Florian Weimer, James Morris, Jan Kara, Jann Horn, Jonathan Corbet, Kees Cook, Lakshmi Ramasubramanian, Matthew Garrett, Michael Kerrisk, Miklos Szeredi, Mimi Zohar, Philippe Trébuchet, Scott Shell, Sean Christopherson, Shuah Khan, Steve Dower, Steve Grubb, Tetsuo Handa, Thibaut Sautereau, Vincent Strubel, kernel-hardening, linux-api, linux-integrity, linux-security-module, linux-fsdevel On 09/09/2020 19:08, Matthew Wilcox wrote: > On Wed, Sep 09, 2020 at 09:19:11AM +0200, Mickaël Salaün wrote: >> >> On 08/09/2020 20:50, Al Viro wrote: >>> On Tue, Sep 08, 2020 at 09:59:53AM +0200, Mickaël Salaün wrote: >>>> Hi, >>>> >>>> This height patch series rework the previous O_MAYEXEC series by not >>>> adding a new flag to openat2(2) but to faccessat2(2) instead. As >>>> suggested, this enables to perform the access check on a file descriptor >>>> instead of on a file path (while opening it). This may require two >>>> checks (one on open and then with faccessat2) but it is a more generic >>>> approach [8]. >>> >>> Again, why is that folded into lookup/open/whatnot, rather than being >>> an operation applied to a file (e.g. O_PATH one)? >> >> I don't understand your question. AT_INTERPRETED can and should be used >> with AT_EMPTY_PATH. The two checks I wrote about was for IMA. > > Al is saying you should add a new syscall, not try to fold it into > some existing syscall. > > I agree with him. Add a new syscall, just like you were told to do it > last time. > OK, but I didn't receive a response for my proposition to extend faccessat2(2). ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [RFC PATCH v8 0/3] Add support for AT_INTERPRETED (was O_MAYEXEC) 2020-09-09 17:08 ` Matthew Wilcox 2020-09-09 17:55 ` Mickaël Salaün @ 2020-09-10 9:26 ` Thibaut Sautereau 1 sibling, 0 replies; 23+ messages in thread From: Thibaut Sautereau @ 2020-09-10 9:26 UTC (permalink / raw) To: Matthew Wilcox, Al Viro Cc: Mickaël Salaün, linux-kernel, Aleksa Sarai, Alexei Starovoitov, Andrew Morton, Andy Lutomirski, Christian Brauner, Christian Heimes, Daniel Borkmann, Deven Bowers, Dmitry Vyukov, Eric Biggers, Eric Chiang, Florian Weimer, James Morris, Jan Kara, Jann Horn, Jonathan Corbet, Kees Cook, Lakshmi Ramasubramanian, Matthew Garrett, Michael Kerrisk, Miklos Szeredi, Mimi Zohar, Philippe Trébuchet, Scott Shell, Sean Christopherson, Shuah Khan, Steve Dower, Steve Grubb, Tetsuo Handa, Vincent Strubel, kernel-hardening, linux-api, linux-integrity, linux-security-module, linux-fsdevel, Arnd Bergmann On Wed, Sep 09, 2020 at 06:08:51PM +0100, Matthew Wilcox wrote: > On Wed, Sep 09, 2020 at 09:19:11AM +0200, Mickaël Salaün wrote: > > > > On 08/09/2020 20:50, Al Viro wrote: > > > On Tue, Sep 08, 2020 at 09:59:53AM +0200, Mickaël Salaün wrote: > > >> Hi, > > >> > > >> This height patch series rework the previous O_MAYEXEC series by not > > >> adding a new flag to openat2(2) but to faccessat2(2) instead. As > > >> suggested, this enables to perform the access check on a file descriptor > > >> instead of on a file path (while opening it). This may require two > > >> checks (one on open and then with faccessat2) but it is a more generic > > >> approach [8]. > > > > > > Again, why is that folded into lookup/open/whatnot, rather than being > > > an operation applied to a file (e.g. O_PATH one)? > > > > I don't understand your question. AT_INTERPRETED can and should be used > > with AT_EMPTY_PATH. The two checks I wrote about was for IMA. > > Al is saying you should add a new syscall, not try to fold it into > some existing syscall. > > I agree with him. Add a new syscall, just like you were told to do it > last time. Sure, we'll do it. In the meantime, could we at least get an explanation about why using faccessat2() instead of a new syscall is wrong? I could see the reasons for separating the exec checks from the file opening, but this time I don't understand. Is it because it brings too much complexity to do_faccessat()? -- Thibaut Sautereau CLIP OS developer ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [RFC PATCH v8 0/3] Add support for AT_INTERPRETED (was O_MAYEXEC) 2020-09-09 7:19 ` Mickaël Salaün 2020-09-09 17:08 ` Matthew Wilcox @ 2020-09-09 17:13 ` Al Viro 2020-09-09 17:56 ` Mickaël Salaün 2020-09-12 0:16 ` James Morris 1 sibling, 2 replies; 23+ messages in thread From: Al Viro @ 2020-09-09 17:13 UTC (permalink / raw) To: Mickaël Salaün Cc: linux-kernel, Aleksa Sarai, Alexei Starovoitov, Andrew Morton, Andy Lutomirski, Christian Brauner, Christian Heimes, Daniel Borkmann, Deven Bowers, Dmitry Vyukov, Eric Biggers, Eric Chiang, Florian Weimer, James Morris, Jan Kara, Jann Horn, Jonathan Corbet, Kees Cook, Lakshmi Ramasubramanian, Matthew Garrett, Matthew Wilcox, Michael Kerrisk, Miklos Szeredi, Mimi Zohar, Philippe Trébuchet, Scott Shell, Sean Christopherson, Shuah Khan, Steve Dower, Steve Grubb, Tetsuo Handa, Thibaut Sautereau, Vincent Strubel, kernel-hardening, linux-api, linux-integrity, linux-security-module, linux-fsdevel On Wed, Sep 09, 2020 at 09:19:11AM +0200, Mickaël Salaün wrote: > > On 08/09/2020 20:50, Al Viro wrote: > > On Tue, Sep 08, 2020 at 09:59:53AM +0200, Mickaël Salaün wrote: > >> Hi, > >> > >> This height patch series rework the previous O_MAYEXEC series by not > >> adding a new flag to openat2(2) but to faccessat2(2) instead. As > >> suggested, this enables to perform the access check on a file descriptor > >> instead of on a file path (while opening it). This may require two > >> checks (one on open and then with faccessat2) but it is a more generic > >> approach [8]. > > > > Again, why is that folded into lookup/open/whatnot, rather than being > > an operation applied to a file (e.g. O_PATH one)? > > > > I don't understand your question. AT_INTERPRETED can and should be used > with AT_EMPTY_PATH. The two checks I wrote about was for IMA. Once more, with feeling: don't hide that behind existing syscalls. If you want to tell LSM have a look at given fs object in a special way, *add* *a* *new* *system* *call* *for* *doing* *just* *that*. ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [RFC PATCH v8 0/3] Add support for AT_INTERPRETED (was O_MAYEXEC) 2020-09-09 17:13 ` Al Viro @ 2020-09-09 17:56 ` Mickaël Salaün 2020-09-12 0:16 ` James Morris 1 sibling, 0 replies; 23+ messages in thread From: Mickaël Salaün @ 2020-09-09 17:56 UTC (permalink / raw) To: Al Viro Cc: linux-kernel, Aleksa Sarai, Alexei Starovoitov, Andrew Morton, Andy Lutomirski, Christian Brauner, Christian Heimes, Daniel Borkmann, Deven Bowers, Dmitry Vyukov, Eric Biggers, Eric Chiang, Florian Weimer, James Morris, Jan Kara, Jann Horn, Jonathan Corbet, Kees Cook, Lakshmi Ramasubramanian, Matthew Garrett, Matthew Wilcox, Michael Kerrisk, Miklos Szeredi, Mimi Zohar, Philippe Trébuchet, Scott Shell, Sean Christopherson, Shuah Khan, Steve Dower, Steve Grubb, Tetsuo Handa, Thibaut Sautereau, Vincent Strubel, kernel-hardening, linux-api, linux-integrity, linux-security-module, linux-fsdevel On 09/09/2020 19:13, Al Viro wrote: > On Wed, Sep 09, 2020 at 09:19:11AM +0200, Mickaël Salaün wrote: >> >> On 08/09/2020 20:50, Al Viro wrote: >>> On Tue, Sep 08, 2020 at 09:59:53AM +0200, Mickaël Salaün wrote: >>>> Hi, >>>> >>>> This height patch series rework the previous O_MAYEXEC series by not >>>> adding a new flag to openat2(2) but to faccessat2(2) instead. As >>>> suggested, this enables to perform the access check on a file descriptor >>>> instead of on a file path (while opening it). This may require two >>>> checks (one on open and then with faccessat2) but it is a more generic >>>> approach [8]. >>> >>> Again, why is that folded into lookup/open/whatnot, rather than being >>> an operation applied to a file (e.g. O_PATH one)? >>> >> >> I don't understand your question. AT_INTERPRETED can and should be used >> with AT_EMPTY_PATH. The two checks I wrote about was for IMA. > > Once more, with feeling: don't hide that behind existing syscalls. > If you want to tell LSM have a look at given fs object in a special > way, *add* *a* *new* *system* *call* *for* *doing* *just* *that*. > Fine, I'll do it. It will look a lot like this one though. ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [RFC PATCH v8 0/3] Add support for AT_INTERPRETED (was O_MAYEXEC) 2020-09-09 17:13 ` Al Viro 2020-09-09 17:56 ` Mickaël Salaün @ 2020-09-12 0:16 ` James Morris 1 sibling, 0 replies; 23+ messages in thread From: James Morris @ 2020-09-12 0:16 UTC (permalink / raw) To: Al Viro Cc: Mickaël Salaün, linux-kernel, Aleksa Sarai, Alexei Starovoitov, Andrew Morton, Andy Lutomirski, Christian Brauner, Christian Heimes, Daniel Borkmann, Deven Bowers, Dmitry Vyukov, Eric Biggers, Eric Chiang, Florian Weimer, Jan Kara, Jann Horn, Jonathan Corbet, Kees Cook, Lakshmi Ramasubramanian, Matthew Garrett, Matthew Wilcox, Michael Kerrisk, Miklos Szeredi, Mimi Zohar, Philippe Trébuchet, Scott Shell, Sean Christopherson, Shuah Khan, Steve Dower, Steve Grubb, Tetsuo Handa, Thibaut Sautereau, Vincent Strubel, kernel-hardening, linux-api, linux-integrity, linux-security-module, linux-fsdevel [-- Attachment #1: Type: text/plain, Size: 1283 bytes --] On Wed, 9 Sep 2020, Al Viro wrote: > On Wed, Sep 09, 2020 at 09:19:11AM +0200, Mickaël Salaün wrote: > > > > On 08/09/2020 20:50, Al Viro wrote: > > > On Tue, Sep 08, 2020 at 09:59:53AM +0200, Mickaël Salaün wrote: > > >> Hi, > > >> > > >> This height patch series rework the previous O_MAYEXEC series by not > > >> adding a new flag to openat2(2) but to faccessat2(2) instead. As > > >> suggested, this enables to perform the access check on a file descriptor > > >> instead of on a file path (while opening it). This may require two > > >> checks (one on open and then with faccessat2) but it is a more generic > > >> approach [8]. > > > > > > Again, why is that folded into lookup/open/whatnot, rather than being > > > an operation applied to a file (e.g. O_PATH one)? > > > > > > > I don't understand your question. AT_INTERPRETED can and should be used > > with AT_EMPTY_PATH. The two checks I wrote about was for IMA. > > Once more, with feeling: don't hide that behind existing syscalls. > If you want to tell LSM have a look at given fs object in a special > way, *add* *a* *new* *system* *call* *for* *doing* *just* *that*. It's not just for LSM, though, and it has identical semantics from the caller's POV as faccessat(). -- James Morris <jmorris@namei.org> ^ permalink raw reply [flat|nested] 23+ messages in thread
end of thread, other threads:[~2020-09-12 0:18 UTC | newest] Thread overview: 23+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2020-09-08 7:59 [RFC PATCH v8 0/3] Add support for AT_INTERPRETED (was O_MAYEXEC) Mickaël Salaün 2020-09-08 7:59 ` [RFC PATCH v8 1/3] fs: Introduce AT_INTERPRETED flag for faccessat2(2) Mickaël Salaün 2020-09-08 12:28 ` Mimi Zohar 2020-09-08 12:43 ` Mickaël Salaün 2020-09-08 12:50 ` Stephen Smalley 2020-09-08 12:52 ` Stephen Smalley 2020-09-08 13:29 ` Mimi Zohar [not found] ` <CAEjxPJ5evWDSv-T-p=4OX29Pr584ZRAsnYoxSRd4qFDoryB+fQ@mail.gmail.com> 2020-09-08 14:14 ` Mickaël Salaün 2020-09-08 15:38 ` Mimi Zohar 2020-09-08 15:24 ` Mimi Zohar 2020-09-08 15:44 ` Mickaël Salaün 2020-09-08 16:44 ` Mimi Zohar 2020-09-08 17:21 ` Mickaël Salaün 2020-09-08 7:59 ` [RFC PATCH v8 2/3] fs,doc: Enable to configure exec checks for AT_INTERPRETED Mickaël Salaün 2020-09-08 7:59 ` [RFC PATCH v8 3/3] selftest/interpreter: Add tests for AT_INTERPRETED enforcing Mickaël Salaün 2020-09-08 18:50 ` [RFC PATCH v8 0/3] Add support for AT_INTERPRETED (was O_MAYEXEC) Al Viro 2020-09-09 7:19 ` Mickaël Salaün 2020-09-09 17:08 ` Matthew Wilcox 2020-09-09 17:55 ` Mickaël Salaün 2020-09-10 9:26 ` Thibaut Sautereau 2020-09-09 17:13 ` Al Viro 2020-09-09 17:56 ` Mickaël Salaün 2020-09-12 0:16 ` James Morris
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).