Kernel-hardening archive on lore.kernel.org
 help / color / Atom feed
* [PATCH v6 0/7] Add support for O_MAYEXEC
@ 2020-07-14 18:16 Mickaël Salaün
  2020-07-14 18:16 ` [PATCH v6 1/7] exec: Change uselib(2) IS_SREG() failure to EACCES Mickaël Salaün
                   ` (6 more replies)
  0 siblings, 7 replies; 25+ messages in thread
From: Mickaël Salaün @ 2020-07-14 18:16 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, Mickaël Salaün, 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 sixth patch series mainly adds Kees Cook's file permission check
relocations which help to simplify and generalize the previous series.
I removed the MAY_EXECMOUNT flag patch which is not useful anymore with
this refactoring.  I also removed the static enforcement configuration
through Kconfig to make this series simpler and because it works in pair
with mount configurations (i.e. requires the same capability:
CAP_SYS_ADMIN).

As requested by Mimi Zohar, I completed the series with one of her
patches for IMA.  I also picked Kees Cook's patches to consolidate exec
permission checking into do_filp_open()'s flow:
https://lore.kernel.org/lkml/20200605160013.3954297-1-keescook@chromium.org/


# Goal of O_MAYEXEC

The goal of this patch series is to enable to control script execution
with interpreters help.  A new O_MAYEXEC flag, usable through
openat2(2), is added to enable userspace script interpreters to delegate
to the kernel (and thus the system security policy) the permission to
interpret/execute scripts or other files containing what can be seen as
commands.

A simple system-wide security policy can be enforced by the system
administrator through a sysctl configuration consistent with the mount
points or the file access rights.  The documentation patch explains the
prerequisites.

Furthermore, the security policy can also be delegated to an LSM, either
a MAC system or an integrity system.  For instance, the new kernel
MAY_OPENEXEC flag closes a major IMA measurement/appraisal interpreter
integrity gap by bringing the ability to check the use of scripts [1].
Other uses are expected, such as for magic-links [2], SGX integration
[3], bpffs [4] or IPE [5].


# Prerequisite of its use

Userspace needs to adapt to take advantage of this new feature.  For
example, the PEP 578 [6] (Runtime Audit Hooks) enables Python 3.8 to be
extended with policy enforcement points related to code interpretation,
which can be used to align with the PowerShell audit features.
Additional Python security improvements (e.g. a limited interpreter
withou -c, stdin piping of code) are on their way [7].


# Examples

The initial idea comes from CLIP OS 4 and the original implementation
has been used for more than 12 years:
https://github.com/clipos-archive/clipos4_doc
Chrome OS has a similar approach:
https://chromium.googlesource.com/chromiumos/docs/+/master/security/noexec_shell_scripts.md

Userland patches can be found here:
https://github.com/clipos-archive/clipos4_portage-overlay/search?q=O_MAYEXEC
Actually, there is more than the O_MAYEXEC changes (which matches this search)
e.g., to prevent Python interactive execution. There are patches for
Bash, Wine, Java (Icedtea), Busybox's ash, Perl and Python. There are
also some related patches which do not directly rely on O_MAYEXEC but
which restrict the use of browser plugins and extensions, which may be
seen as scripts too:
https://github.com/clipos-archive/clipos4_portage-overlay/tree/master/www-client

An introduction to O_MAYEXEC was given at the Linux Security Summit
Europe 2018 - Linux Kernel Security Contributions by ANSSI:
https://www.youtube.com/watch?v=chNjCRtPKQY&t=17m15s
The "write xor execute" principle was explained at Kernel Recipes 2018 -
CLIP OS: a defense-in-depth OS:
https://www.youtube.com/watch?v=PjRE0uBtkHU&t=11m14s
See also an overview article: https://lwn.net/Articles/820000/


This patch series can be applied on top of v5.8-rc5 .  This can be tested
with CONFIG_SYSCTL.  I would really appreciate constructive comments on
this patch series.

Previous version:
https://lore.kernel.org/lkml/20200505153156.925111-1-mic@digikod.net/


[1] https://lore.kernel.org/lkml/1544647356.4028.105.camel@linux.ibm.com/
[2] https://lore.kernel.org/lkml/20190904201933.10736-6-cyphar@cyphar.com/
[3] https://lore.kernel.org/lkml/CALCETrVovr8XNZSroey7pHF46O=kj_c5D9K8h=z2T_cNrpvMig@mail.gmail.com/
[4] https://lore.kernel.org/lkml/CALCETrVeZ0eufFXwfhtaG_j+AdvbzEWE0M3wjXMWVEO7pj+xkw@mail.gmail.com/
[5] https://lore.kernel.org/lkml/20200406221439.1469862-12-deven.desai@linux.microsoft.com/
[6] https://www.python.org/dev/peps/pep-0578/
[7] https://lore.kernel.org/lkml/0c70debd-e79e-d514-06c6-4cd1e021fa8b@python.org/

Regards,

Kees Cook (3):
  exec: Change uselib(2) IS_SREG() failure to EACCES
  exec: Move S_ISREG() check earlier
  exec: Move path_noexec() check earlier

Mickaël Salaün (3):
  fs: Introduce O_MAYEXEC flag for openat2(2)
  fs,doc: Enable to enforce noexec mounts or file exec through O_MAYEXEC
  selftest/openat2: Add tests for O_MAYEXEC enforcing

Mimi Zohar (1):
  ima: add policy support for the new file open MAY_OPENEXEC flag

 Documentation/ABI/testing/ima_policy          |   2 +-
 Documentation/admin-guide/sysctl/fs.rst       |  45 +++
 fs/exec.c                                     |  23 +-
 fs/fcntl.c                                    |   2 +-
 fs/namei.c                                    |  31 ++-
 fs/open.c                                     |  14 +-
 include/linux/fcntl.h                         |   2 +-
 include/linux/fs.h                            |   3 +
 include/uapi/asm-generic/fcntl.h              |   7 +
 kernel/sysctl.c                               |  12 +-
 security/integrity/ima/ima_main.c             |   3 +-
 security/integrity/ima/ima_policy.c           |  15 +-
 tools/testing/selftests/kselftest_harness.h   |   3 +
 tools/testing/selftests/openat2/Makefile      |   3 +-
 tools/testing/selftests/openat2/config        |   1 +
 tools/testing/selftests/openat2/helpers.h     |   1 +
 .../testing/selftests/openat2/omayexec_test.c | 262 ++++++++++++++++++
 17 files changed, 400 insertions(+), 29 deletions(-)
 create mode 100644 tools/testing/selftests/openat2/config
 create mode 100644 tools/testing/selftests/openat2/omayexec_test.c

-- 
2.27.0


^ permalink raw reply	[flat|nested] 25+ messages in thread

* [PATCH v6 1/7] exec: Change uselib(2) IS_SREG() failure to EACCES
  2020-07-14 18:16 [PATCH v6 0/7] Add support for O_MAYEXEC Mickaël Salaün
@ 2020-07-14 18:16 ` Mickaël Salaün
  2020-07-14 18:16 ` [PATCH v6 2/7] exec: Move S_ISREG() check earlier Mickaël Salaün
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 25+ messages in thread
From: Mickaël Salaün @ 2020-07-14 18:16 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, Mickaël Salaün, 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

From: Kees Cook <keescook@chromium.org>

Change uselib(2)' S_ISREG() error return to EACCES instead of EINVAL so
the behavior matches execve(2), and the seemingly documented value.
The "not a regular file" failure mode of execve(2) is explicitly
documented[1], but it is not mentioned in uselib(2)[2] which does,
however, say that open(2) and mmap(2) errors may apply. The documentation
for open(2) does not include a "not a regular file" error[3], but mmap(2)
does[4], and it is EACCES.

[1] http://man7.org/linux/man-pages/man2/execve.2.html#ERRORS
[2] http://man7.org/linux/man-pages/man2/uselib.2.html#ERRORS
[3] http://man7.org/linux/man-pages/man2/open.2.html#ERRORS
[4] http://man7.org/linux/man-pages/man2/mmap.2.html#ERRORS

Signed-off-by: Kees Cook <keescook@chromium.org>
Acked-by: Christian Brauner <christian.brauner@ubuntu.com>
Acked-by: Mickaël Salaün <mic@digikod.net>
Link: https://lore.kernel.org/r/20200605160013.3954297-2-keescook@chromium.org
---
 fs/exec.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/fs/exec.c b/fs/exec.c
index e6e8a9a70327..d7c937044d10 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -141,11 +141,10 @@ SYSCALL_DEFINE1(uselib, const char __user *, library)
 	if (IS_ERR(file))
 		goto out;
 
-	error = -EINVAL;
+	error = -EACCES;
 	if (!S_ISREG(file_inode(file)->i_mode))
 		goto exit;
 
-	error = -EACCES;
 	if (path_noexec(&file->f_path))
 		goto exit;
 
-- 
2.27.0


^ permalink raw reply	[flat|nested] 25+ messages in thread

* [PATCH v6 2/7] exec: Move S_ISREG() check earlier
  2020-07-14 18:16 [PATCH v6 0/7] Add support for O_MAYEXEC Mickaël Salaün
  2020-07-14 18:16 ` [PATCH v6 1/7] exec: Change uselib(2) IS_SREG() failure to EACCES Mickaël Salaün
@ 2020-07-14 18:16 ` Mickaël Salaün
  2020-07-14 18:16 ` [PATCH v6 3/7] exec: Move path_noexec() " Mickaël Salaün
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 25+ messages in thread
From: Mickaël Salaün @ 2020-07-14 18:16 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, Mickaël Salaün, 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

From: Kees Cook <keescook@chromium.org>

The execve(2)/uselib(2) syscalls have always rejected non-regular
files. Recently, it was noticed that a deadlock was introduced when trying
to execute pipes, as the S_ISREG() test was happening too late. This was
fixed in commit 73601ea5b7b1 ("fs/open.c: allow opening only regular files
during execve()"), but it was added after inode_permission() had already
run, which meant LSMs could see bogus attempts to execute non-regular
files.

Move the test into the other inode type checks (which already look
for other pathological conditions[1]). Since there is no need to use
FMODE_EXEC while we still have access to "acc_mode", also switch the
test to MAY_EXEC.

Also include a comment with the redundant S_ISREG() checks at the end of
execve(2)/uselib(2) to note that they are present to avoid any mistakes.

My notes on the call path, and related arguments, checks, etc:

do_open_execat()
    struct open_flags open_exec_flags = {
        .open_flag = O_LARGEFILE | O_RDONLY | __FMODE_EXEC,
        .acc_mode = MAY_EXEC,
        ...
    do_filp_open(dfd, filename, open_flags)
        path_openat(nameidata, open_flags, flags)
            file = alloc_empty_file(open_flags, current_cred());
            do_open(nameidata, file, open_flags)
                may_open(path, acc_mode, open_flag)
		    /* new location of MAY_EXEC vs S_ISREG() test */
                    inode_permission(inode, MAY_OPEN | acc_mode)
                        security_inode_permission(inode, acc_mode)
                vfs_open(path, file)
                    do_dentry_open(file, path->dentry->d_inode, open)
                        /* old location of FMODE_EXEC vs S_ISREG() test */
                        security_file_open(f)
                        open()

[1] https://lore.kernel.org/lkml/202006041910.9EF0C602@keescook/

Signed-off-by: Kees Cook <keescook@chromium.org>
Acked-by: Mickaël Salaün <mic@digikod.net>
Link: https://lore.kernel.org/r/20200605160013.3954297-3-keescook@chromium.org
---
 fs/exec.c  | 14 ++++++++++++--
 fs/namei.c |  6 ++++--
 fs/open.c  |  6 ------
 3 files changed, 16 insertions(+), 10 deletions(-)

diff --git a/fs/exec.c b/fs/exec.c
index d7c937044d10..bdc6a6eb5dce 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -141,8 +141,13 @@ SYSCALL_DEFINE1(uselib, const char __user *, library)
 	if (IS_ERR(file))
 		goto out;
 
+	/*
+	 * may_open() has already checked for this, so it should be
+	 * impossible to trip now. But we need to be extra cautious
+	 * and check again at the very end too.
+	 */
 	error = -EACCES;
-	if (!S_ISREG(file_inode(file)->i_mode))
+	if (WARN_ON_ONCE(!S_ISREG(file_inode(file)->i_mode)))
 		goto exit;
 
 	if (path_noexec(&file->f_path))
@@ -886,8 +891,13 @@ static struct file *do_open_execat(int fd, struct filename *name, int flags)
 	if (IS_ERR(file))
 		goto out;
 
+	/*
+	 * may_open() has already checked for this, so it should be
+	 * impossible to trip now. But we need to be extra cautious
+	 * and check again at the very end too.
+	 */
 	err = -EACCES;
-	if (!S_ISREG(file_inode(file)->i_mode))
+	if (WARN_ON_ONCE(!S_ISREG(file_inode(file)->i_mode)))
 		goto exit;
 
 	if (path_noexec(&file->f_path))
diff --git a/fs/namei.c b/fs/namei.c
index 72d4219c93ac..a559ad943970 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -2849,16 +2849,18 @@ static int may_open(const struct path *path, int acc_mode, int flag)
 	case S_IFLNK:
 		return -ELOOP;
 	case S_IFDIR:
-		if (acc_mode & MAY_WRITE)
+		if (acc_mode & (MAY_WRITE | MAY_EXEC))
 			return -EISDIR;
 		break;
 	case S_IFBLK:
 	case S_IFCHR:
 		if (!may_open_dev(path))
 			return -EACCES;
-		/*FALLTHRU*/
+		fallthrough;
 	case S_IFIFO:
 	case S_IFSOCK:
+		if (acc_mode & MAY_EXEC)
+			return -EACCES;
 		flag &= ~O_TRUNC;
 		break;
 	}
diff --git a/fs/open.c b/fs/open.c
index 6cd48a61cda3..623b7506a6db 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -784,12 +784,6 @@ static int do_dentry_open(struct file *f,
 		return 0;
 	}
 
-	/* Any file opened for execve()/uselib() has to be a regular file. */
-	if (unlikely(f->f_flags & FMODE_EXEC && !S_ISREG(inode->i_mode))) {
-		error = -EACCES;
-		goto cleanup_file;
-	}
-
 	if (f->f_mode & FMODE_WRITE && !special_file(inode->i_mode)) {
 		error = get_write_access(inode);
 		if (unlikely(error))
-- 
2.27.0


^ permalink raw reply	[flat|nested] 25+ messages in thread

* [PATCH v6 3/7] exec: Move path_noexec() check earlier
  2020-07-14 18:16 [PATCH v6 0/7] Add support for O_MAYEXEC Mickaël Salaün
  2020-07-14 18:16 ` [PATCH v6 1/7] exec: Change uselib(2) IS_SREG() failure to EACCES Mickaël Salaün
  2020-07-14 18:16 ` [PATCH v6 2/7] exec: Move S_ISREG() check earlier Mickaël Salaün
@ 2020-07-14 18:16 ` Mickaël Salaün
  2020-07-14 18:16 ` [PATCH v6 4/7] fs: Introduce O_MAYEXEC flag for openat2(2) Mickaël Salaün
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 25+ messages in thread
From: Mickaël Salaün @ 2020-07-14 18:16 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, Mickaël Salaün, 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

From: Kees Cook <keescook@chromium.org>

The path_noexec() check, like the regular file check, was happening too
late, letting LSMs see impossible execve()s. Check it earlier as well
in may_open() and collect the redundant fs/exec.c path_noexec() test
under the same robustness comment as the S_ISREG() check.

My notes on the call path, and related arguments, checks, etc:

do_open_execat()
    struct open_flags open_exec_flags = {
        .open_flag = O_LARGEFILE | O_RDONLY | __FMODE_EXEC,
        .acc_mode = MAY_EXEC,
        ...
    do_filp_open(dfd, filename, open_flags)
        path_openat(nameidata, open_flags, flags)
            file = alloc_empty_file(open_flags, current_cred());
            do_open(nameidata, file, open_flags)
                may_open(path, acc_mode, open_flag)
                    /* new location of MAY_EXEC vs path_noexec() test */
                    inode_permission(inode, MAY_OPEN | acc_mode)
                        security_inode_permission(inode, acc_mode)
                vfs_open(path, file)
                    do_dentry_open(file, path->dentry->d_inode, open)
                        security_file_open(f)
                        open()
    /* old location of path_noexec() test */

Signed-off-by: Kees Cook <keescook@chromium.org>
Acked-by: Mickaël Salaün <mic@digikod.net>
Link: https://lore.kernel.org/r/20200605160013.3954297-4-keescook@chromium.org
---
 fs/exec.c  | 12 ++++--------
 fs/namei.c |  4 ++++
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/fs/exec.c b/fs/exec.c
index bdc6a6eb5dce..4eea20c27b01 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -147,10 +147,8 @@ SYSCALL_DEFINE1(uselib, const char __user *, library)
 	 * and check again at the very end too.
 	 */
 	error = -EACCES;
-	if (WARN_ON_ONCE(!S_ISREG(file_inode(file)->i_mode)))
-		goto exit;
-
-	if (path_noexec(&file->f_path))
+	if (WARN_ON_ONCE(!S_ISREG(file_inode(file)->i_mode) ||
+			 path_noexec(&file->f_path)))
 		goto exit;
 
 	fsnotify_open(file);
@@ -897,10 +895,8 @@ static struct file *do_open_execat(int fd, struct filename *name, int flags)
 	 * and check again at the very end too.
 	 */
 	err = -EACCES;
-	if (WARN_ON_ONCE(!S_ISREG(file_inode(file)->i_mode)))
-		goto exit;
-
-	if (path_noexec(&file->f_path))
+	if (WARN_ON_ONCE(!S_ISREG(file_inode(file)->i_mode) ||
+			 path_noexec(&file->f_path)))
 		goto exit;
 
 	err = deny_write_access(file);
diff --git a/fs/namei.c b/fs/namei.c
index a559ad943970..ddc9b25540fe 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -2863,6 +2863,10 @@ static int may_open(const struct path *path, int acc_mode, int flag)
 			return -EACCES;
 		flag &= ~O_TRUNC;
 		break;
+	case S_IFREG:
+		if ((acc_mode & MAY_EXEC) && path_noexec(path))
+			return -EACCES;
+		break;
 	}
 
 	error = inode_permission(inode, MAY_OPEN | acc_mode);
-- 
2.27.0


^ permalink raw reply	[flat|nested] 25+ messages in thread

* [PATCH v6 4/7] fs: Introduce O_MAYEXEC flag for openat2(2)
  2020-07-14 18:16 [PATCH v6 0/7] Add support for O_MAYEXEC Mickaël Salaün
                   ` (2 preceding siblings ...)
  2020-07-14 18:16 ` [PATCH v6 3/7] exec: Move path_noexec() " Mickaël Salaün
@ 2020-07-14 18:16 ` Mickaël Salaün
  2020-07-15 20:06   ` Kees Cook
  2020-07-14 18:16 ` [PATCH v6 5/7] fs,doc: Enable to enforce noexec mounts or file exec through O_MAYEXEC Mickaël Salaün
                   ` (2 subsequent siblings)
  6 siblings, 1 reply; 25+ messages in thread
From: Mickaël Salaün @ 2020-07-14 18:16 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, Mickaël Salaün, 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

When the O_MAYEXEC flag is passed, openat2(2) may be subject to
additional restrictions depending on a security policy managed by the
kernel through a sysctl or implemented by an LSM thanks to the
inode_permission hook.  This new flag is ignored by open(2) and
openat(2) because of their unspecified flags handling.

The underlying idea is to be able to restrict scripts interpretation
according to a policy defined by the system administrator.  For this to
be possible, script interpreters must use the O_MAYEXEC flag
appropriately.  To be fully effective, these interpreters also need to
handle the other ways to execute code: command line parameters (e.g.,
option -e for Perl), module loading (e.g., option -m for Python), stdin,
file sourcing, environment variables, configuration files, etc.
According to the threat model, it may be acceptable to allow some script
interpreters (e.g. Bash) to interpret commands from stdin, may it be a
TTY or a pipe, because it may not be enough to (directly) perform
syscalls.  Further documentation can be found in a following patch.

Even without enforced security policy, userland interpreters can set it
to enforce the system policy at their level, knowing that it will not
break anything on running systems which do not care about this feature.
However, on systems which want this feature enforced, there will be
knowledgeable people (i.e. sysadmins who enforced O_MAYEXEC
deliberately) to manage it.  A simple security policy implementation,
configured through a dedicated sysctl, is available in a following
patch.

O_MAYEXEC should not be confused with the O_EXEC flag which is intended
for execute-only, which obviously doesn't work for scripts.  However, a
similar behavior could be implemented in userland with O_PATH:
https://lore.kernel.org/lkml/1e2f6913-42f2-3578-28ed-567f6a4bdda1@digikod.net/

The implementation of O_MAYEXEC almost duplicates what execve(2) and
uselib(2) are already doing: setting MAY_OPENEXEC in acc_mode (which can
then be checked as MAY_EXEC, if enforced), and propagating FMODE_EXEC to
_fmode via __FMODE_EXEC flag (which can then trigger a
fanotify/FAN_OPEN_EXEC event).

This is an updated subset of the patch initially written by Vincent
Strubel for CLIP OS 4:
https://github.com/clipos-archive/src_platform_clip-patches/blob/f5cb330d6b684752e403b4e41b39f7004d88e561/1901_open_mayexec.patch
This patch has been used for more than 12 years with customized script
interpreters.  Some examples (with the original name O_MAYEXEC) can be
found here:
https://github.com/clipos-archive/clipos4_portage-overlay/search?q=O_MAYEXEC

Co-developed-by: Vincent Strubel <vincent.strubel@ssi.gouv.fr>
Signed-off-by: Vincent Strubel <vincent.strubel@ssi.gouv.fr>
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@digikod.net>
Reviewed-by: Deven Bowers <deven.desai@linux.microsoft.com>
Reviewed-by: Kees Cook <keescook@chromium.org>
Cc: Aleksa Sarai <cyphar@cyphar.com>
Cc: Al Viro <viro@zeniv.linux.org.uk>
---

Changes since v5:
* Update commit message.

Changes since v3:
* Switch back to O_MAYEXEC, but only handle it with openat2(2) which
  checks unknown flags (suggested by Aleksa Sarai). Cf.
  https://lore.kernel.org/lkml/20200430015429.wuob7m5ofdewubui@yavin.dot.cyphar.com/

Changes since v2:
* Replace O_MAYEXEC with RESOLVE_MAYEXEC from openat2(2).  This change
  enables to not break existing application using bogus O_* flags that
  may be ignored by current kernels by using a new dedicated flag, only
  usable through openat2(2) (suggested by Jeff Layton).  Using this flag
  will results in an error if the running kernel does not support it.
  User space needs to manage this case, as with other RESOLVE_* flags.
  The best effort approach to security (for most common distros) will
  simply consists of ignoring such an error and retry without
  RESOLVE_MAYEXEC.  However, a fully controlled system may which to
  error out if such an inconsistency is detected.

Changes since v1:
* Set __FMODE_EXEC when using O_MAYEXEC to make this information
  available through the new fanotify/FAN_OPEN_EXEC event (suggested by
  Jan Kara and Matthew Bobrowski):
  https://lore.kernel.org/lkml/20181213094658.GA996@lithium.mbobrowski.org/
---
 fs/fcntl.c                       | 2 +-
 fs/open.c                        | 8 ++++++++
 include/linux/fcntl.h            | 2 +-
 include/linux/fs.h               | 2 ++
 include/uapi/asm-generic/fcntl.h | 7 +++++++
 5 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/fs/fcntl.c b/fs/fcntl.c
index 2e4c0fa2074b..0357ad667563 100644
--- a/fs/fcntl.c
+++ b/fs/fcntl.c
@@ -1033,7 +1033,7 @@ static int __init fcntl_init(void)
 	 * Exceptions: O_NONBLOCK is a two bit define on parisc; O_NDELAY
 	 * is defined as O_NONBLOCK on some platforms and not on others.
 	 */
-	BUILD_BUG_ON(21 - 1 /* for O_RDONLY being 0 */ !=
+	BUILD_BUG_ON(22 - 1 /* for O_RDONLY being 0 */ !=
 		HWEIGHT32(
 			(VALID_OPEN_FLAGS & ~(O_NONBLOCK | O_NDELAY)) |
 			__FMODE_EXEC | __FMODE_NONOTIFY));
diff --git a/fs/open.c b/fs/open.c
index 623b7506a6db..38e434bdbbb6 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -987,6 +987,8 @@ inline struct open_how build_open_how(int flags, umode_t mode)
 		.mode = mode & S_IALLUGO,
 	};
 
+	/* O_MAYEXEC is ignored by syscalls relying on build_open_how(). */
+	how.flags &= ~O_MAYEXEC;
 	/* O_PATH beats everything else. */
 	if (how.flags & O_PATH)
 		how.flags &= O_PATH_FLAGS;
@@ -1054,6 +1056,12 @@ inline int build_open_flags(const struct open_how *how, struct open_flags *op)
 	if (flags & __O_SYNC)
 		flags |= O_DSYNC;
 
+	/* Checks execution permissions on open. */
+	if (flags & O_MAYEXEC) {
+		acc_mode |= MAY_OPENEXEC;
+		flags |= __FMODE_EXEC;
+	}
+
 	op->open_flag = flags;
 
 	/* O_TRUNC implies we need access checks for write permissions */
diff --git a/include/linux/fcntl.h b/include/linux/fcntl.h
index 7bcdcf4f6ab2..e188a360fa5f 100644
--- a/include/linux/fcntl.h
+++ b/include/linux/fcntl.h
@@ -10,7 +10,7 @@
 	(O_RDONLY | O_WRONLY | O_RDWR | O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC | \
 	 O_APPEND | O_NDELAY | O_NONBLOCK | O_NDELAY | __O_SYNC | O_DSYNC | \
 	 FASYNC	| O_DIRECT | O_LARGEFILE | O_DIRECTORY | O_NOFOLLOW | \
-	 O_NOATIME | O_CLOEXEC | O_PATH | __O_TMPFILE)
+	 O_NOATIME | O_CLOEXEC | O_PATH | __O_TMPFILE | O_MAYEXEC)
 
 /* List of all valid flags for the how->upgrade_mask argument: */
 #define VALID_UPGRADE_FLAGS \
diff --git a/include/linux/fs.h b/include/linux/fs.h
index f5abba86107d..56f835c9a87a 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
+/* the inode is opened with O_MAYEXEC */
+#define MAY_OPENEXEC		0x00000100
 
 /*
  * flags in file.f_mode.  Note that FMODE_READ and FMODE_WRITE must correspond
diff --git a/include/uapi/asm-generic/fcntl.h b/include/uapi/asm-generic/fcntl.h
index 9dc0bf0c5a6e..bca90620119f 100644
--- a/include/uapi/asm-generic/fcntl.h
+++ b/include/uapi/asm-generic/fcntl.h
@@ -97,6 +97,13 @@
 #define O_NDELAY	O_NONBLOCK
 #endif
 
+/*
+ * Code execution from file is intended, checks such permission.  A simple
+ * policy can be enforced system-wide as explained in
+ * Documentation/admin-guide/sysctl/fs.rst .
+ */
+#define O_MAYEXEC	040000000
+
 #define F_DUPFD		0	/* dup */
 #define F_GETFD		1	/* get close_on_exec */
 #define F_SETFD		2	/* set/clear close_on_exec */
-- 
2.27.0


^ permalink raw reply	[flat|nested] 25+ messages in thread

* [PATCH v6 5/7] fs,doc: Enable to enforce noexec mounts or file exec through O_MAYEXEC
  2020-07-14 18:16 [PATCH v6 0/7] Add support for O_MAYEXEC Mickaël Salaün
                   ` (3 preceding siblings ...)
  2020-07-14 18:16 ` [PATCH v6 4/7] fs: Introduce O_MAYEXEC flag for openat2(2) Mickaël Salaün
@ 2020-07-14 18:16 ` Mickaël Salaün
  2020-07-14 18:40   ` Randy Dunlap
  2020-07-15 20:37   ` Kees Cook
  2020-07-14 18:16 ` [PATCH v6 6/7] selftest/openat2: Add tests for O_MAYEXEC enforcing Mickaël Salaün
  2020-07-14 18:16 ` [PATCH v6 7/7] ima: add policy support for the new file open MAY_OPENEXEC flag Mickaël Salaün
  6 siblings, 2 replies; 25+ messages in thread
From: Mickaël Salaün @ 2020-07-14 18:16 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, Mickaël Salaün, 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

Allow for the enforcement of the O_MAYEXEC openat2(2) flag.  Thanks to
the noexec option from the underlying VFS mount, or to the file execute
permission, userspace can enforce these execution policies.  This may
allow script interpreters to check execution permission before reading
commands from a file, or dynamic linkers to allow shared object loading.

Add a new sysctl fs.open_mayexec_enforce to enable system administrators
to enforce two complementary security policies according to the
installed system: enforce the noexec mount option, and enforce
executable file permission.  Indeed, because of compatibility with
installed systems, only system administrators are able to check that
this new enforcement is in line with the system mount points and file
permissions.  A following patch adds documentation.

Being able to restrict execution also enables to protect the kernel by
restricting arbitrary syscalls that an attacker could perform with a
crafted binary or certain script languages.  It also improves multilevel
isolation by reducing the ability of an attacker to use side channels
with specific code.  These restrictions can natively be enforced for ELF
binaries (with the noexec mount option) but require this kernel
extension to properly handle scripts (e.g., Python, Perl).  To get a
consistent execution policy, additional memory restrictions should also
be enforced (e.g. thanks to SELinux).

Because the O_MAYEXEC flag is a meant to enforce a system-wide security
policy (but not application-centric policies), it does not make sense
for userland to check the sysctl value.  Indeed, this new flag only
enables to extend the system ability to enforce a policy thanks to (some
trusted) userland collaboration.  Moreover, additional security policies
could be managed by LSMs.  This is a best-effort approach from the
application developer point of view:
https://lore.kernel.org/lkml/1477d3d7-4b36-afad-7077-a38f42322238@digikod.net/

Signed-off-by: Mickaël Salaün <mic@digikod.net>
Reviewed-by: Thibaut Sautereau <thibaut.sautereau@ssi.gouv.fr>
Cc: Aleksa Sarai <cyphar@cyphar.com>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: Jonathan Corbet <corbet@lwn.net>
Cc: Kees Cook <keescook@chromium.org>
---

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 | 45 +++++++++++++++++++++++++
 fs/namei.c                              | 29 +++++++++++++---
 include/linux/fs.h                      |  1 +
 kernel/sysctl.c                         | 12 +++++--
 4 files changed, 80 insertions(+), 7 deletions(-)

diff --git a/Documentation/admin-guide/sysctl/fs.rst b/Documentation/admin-guide/sysctl/fs.rst
index 2a45119e3331..02ec384b8bbf 100644
--- a/Documentation/admin-guide/sysctl/fs.rst
+++ b/Documentation/admin-guide/sysctl/fs.rst
@@ -37,6 +37,7 @@ Currently, these files are in /proc/sys/fs:
 - inode-nr
 - inode-state
 - nr_open
+- open_mayexec_enforce
 - overflowuid
 - overflowgid
 - pipe-user-pages-hard
@@ -165,6 +166,50 @@ system needs to prune the inode list instead of allocating
 more.
 
 
+open_mayexec_enforce
+--------------------
+
+While being ignored by :manpage:`open(2)` and :manpage:`openat(2)`, the
+``O_MAYEXEC`` flag can be passed to :manpage:`openat2(2)` to only open regular
+files that are expected to be executable.  If the file is not identified as
+executable, then the syscall returns -EACCES.  This may allow a script
+interpreter to check executable permission before reading commands from a file,
+or a dynamic linker to only load executable shared objects.  One interesting
+use case is to enforce a "write xor execute" policy through interpreters.
+
+The ability to restrict code execution must be thought as a system-wide policy,
+which first starts by restricting mount points with the ``noexec`` option.
+This option is also automatically applied to special filesystems such as /proc
+.  This prevents files on such mount points to be directly executed by the
+kernel or mapped as executable memory (e.g. libraries).  With script
+interpreters using the ``O_MAYEXEC`` flag, the executable permission can then
+be checked before reading commands from files. This makes it possible to
+enforce the ``noexec`` at the interpreter level, and thus propagates this
+security policy to scripts.  To be fully effective, these interpreters also
+need to handle the other ways to execute code: command line parameters (e.g.,
+option ``-e`` for Perl), module loading (e.g., option ``-m`` for Python),
+stdin, file sourcing, environment variables, configuration files, etc.
+According to the threat model, it may be acceptable to allow some script
+interpreters (e.g. Bash) to interpret commands from stdin, may it be a TTY or a
+pipe, because it may not be enough to (directly) perform syscalls.
+
+There are two complementary security policies: enforce the ``noexec`` mount
+option, and enforce executable file permission.  These policies are handled by
+the ``fs.open_mayexec_enforce`` sysctl (writable only with ``CAP_SYS_ADMIN``)
+as a bitmask:
+
+1 - Mount restriction: checks that the mount options for the underlying VFS
+    mount do not prevent execution.
+
+2 - File permission restriction: checks that the to-be-opened file is marked as
+    executable for the current process (e.g., POSIX permissions).
+
+Code samples can be found in tools/testing/selftests/openat2/omayexec_test.c
+and interpreter patches (for the original O_MAYEXEC version) may be found at
+https://github.com/clipos-archive/clipos4_portage-overlay/search?q=O_MAYEXEC .
+See also an overview article: https://lwn.net/Articles/820000/ .
+
+
 overflowgid & overflowuid
 -------------------------
 
diff --git a/fs/namei.c b/fs/namei.c
index ddc9b25540fe..9a9166e5ddd3 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -39,6 +39,7 @@
 #include <linux/bitops.h>
 #include <linux/init_task.h>
 #include <linux/uaccess.h>
+#include <linux/sysctl.h>
 
 #include "internal.h"
 #include "mount.h"
@@ -425,10 +426,15 @@ static int sb_permission(struct super_block *sb, struct inode *inode, int mask)
 	return 0;
 }
 
+#define OPEN_MAYEXEC_ENFORCE_MOUNT	BIT(0)
+#define OPEN_MAYEXEC_ENFORCE_FILE	BIT(1)
+
+int sysctl_open_mayexec_enforce __read_mostly;
+
 /**
  * inode_permission - Check for access rights to a given inode
  * @inode: Inode to check permission on
- * @mask: Right to check for (%MAY_READ, %MAY_WRITE, %MAY_EXEC)
+ * @mask: Right to check for (%MAY_READ, %MAY_WRITE, %MAY_EXEC, %MAY_OPENEXEC)
  *
  * Check for read/write/execute permissions on an inode.  We use fs[ug]id for
  * this, letting us set arbitrary permissions for filesystem access without
@@ -2849,7 +2855,7 @@ static int may_open(const struct path *path, int acc_mode, int flag)
 	case S_IFLNK:
 		return -ELOOP;
 	case S_IFDIR:
-		if (acc_mode & (MAY_WRITE | MAY_EXEC))
+		if (acc_mode & (MAY_WRITE | MAY_EXEC | MAY_OPENEXEC))
 			return -EISDIR;
 		break;
 	case S_IFBLK:
@@ -2859,13 +2865,26 @@ static int may_open(const struct path *path, int acc_mode, int flag)
 		fallthrough;
 	case S_IFIFO:
 	case S_IFSOCK:
-		if (acc_mode & MAY_EXEC)
+		if (acc_mode & (MAY_EXEC | MAY_OPENEXEC))
 			return -EACCES;
 		flag &= ~O_TRUNC;
 		break;
 	case S_IFREG:
-		if ((acc_mode & MAY_EXEC) && path_noexec(path))
-			return -EACCES;
+		if (path_noexec(path)) {
+			if (acc_mode & MAY_EXEC)
+				return -EACCES;
+			if ((acc_mode & MAY_OPENEXEC) &&
+					(sysctl_open_mayexec_enforce & OPEN_MAYEXEC_ENFORCE_MOUNT))
+				return -EACCES;
+		}
+		if ((acc_mode & MAY_OPENEXEC) &&
+				(sysctl_open_mayexec_enforce & OPEN_MAYEXEC_ENFORCE_FILE))
+			/*
+			 * Because acc_mode may change here, the next and only
+			 * use of acc_mode should then be by the following call
+			 * to inode_permission().
+			 */
+			acc_mode |= MAY_EXEC;
 		break;
 	}
 
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 56f835c9a87a..071f37707ccc 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_open_mayexec_enforce;
 
 typedef __kernel_rwf_t rwf_t;
 
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index db1ce7af2563..5008a2566e79 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;
@@ -888,7 +889,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)
 {
@@ -897,7 +897,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
@@ -3264,6 +3263,15 @@ static struct ctl_table fs_table[] = {
 		.extra1		= SYSCTL_ZERO,
 		.extra2		= &two,
 	},
+	{
+		.procname       = "open_mayexec_enforce",
+		.data           = &sysctl_open_mayexec_enforce,
+		.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.27.0


^ permalink raw reply	[flat|nested] 25+ messages in thread

* [PATCH v6 6/7] selftest/openat2: Add tests for O_MAYEXEC enforcing
  2020-07-14 18:16 [PATCH v6 0/7] Add support for O_MAYEXEC Mickaël Salaün
                   ` (4 preceding siblings ...)
  2020-07-14 18:16 ` [PATCH v6 5/7] fs,doc: Enable to enforce noexec mounts or file exec through O_MAYEXEC Mickaël Salaün
@ 2020-07-14 18:16 ` Mickaël Salaün
  2020-07-15 20:38   ` Kees Cook
  2020-07-14 18:16 ` [PATCH v6 7/7] ima: add policy support for the new file open MAY_OPENEXEC flag Mickaël Salaün
  6 siblings, 1 reply; 25+ messages in thread
From: Mickaël Salaün @ 2020-07-14 18:16 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, Mickaël Salaün, 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

Test propagation of noexec mount points or file executability through
files open with or without O_MAYEXEC, thanks to the
fs.open_mayexec_enforce sysctl.

Signed-off-by: Mickaël Salaün <mic@digikod.net>
Reviewed-by: Thibaut Sautereau <thibaut.sautereau@ssi.gouv.fr>
Cc: Aleksa Sarai <cyphar@cyphar.com>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: Kees Cook <keescook@chromium.org>
Cc: Shuah Khan <shuah@kernel.org>
---

Changes since v5:
* Refactor with FIXTURE_VARIANT, which make the tests much more easy to
  read and maintain.
* Save and restore initial sysctl value (suggested by Kees Cook).
* Test with a sysctl value of 0.
* Check errno in sysctl_access_write test.
* Update tests for the CAP_SYS_ADMIN switch.
* Update tests to check -EISDIR (replacing -EACCES).
* Replace FIXTURE_DATA() with FIXTURE() (spotted by Kees Cook).
* Use global const strings.

Changes since v3:
* Replace RESOLVE_MAYEXEC with O_MAYEXEC.
* Add tests to check that O_MAYEXEC is ignored by open(2) and openat(2).

Changes since v2:
* Move tests from exec/ to openat2/ .
* Replace O_MAYEXEC with RESOLVE_MAYEXEC from openat2(2).
* Cleanup tests.

Changes since v1:
* Move tests from yama/ to exec/ .
* Fix _GNU_SOURCE in kselftest_harness.h .
* Add a new test sysctl_access_write to check if CAP_MAC_ADMIN is taken
  into account.
* Test directory execution which is always forbidden since commit
  73601ea5b7b1 ("fs/open.c: allow opening only regular files during
  execve()"), and also check that even the root user can not bypass file
  execution checks.
* Make sure delete_workspace() always as enough right to succeed.
* Cosmetic cleanup.
---
 tools/testing/selftests/kselftest_harness.h   |   3 +
 tools/testing/selftests/openat2/Makefile      |   3 +-
 tools/testing/selftests/openat2/config        |   1 +
 tools/testing/selftests/openat2/helpers.h     |   1 +
 .../testing/selftests/openat2/omayexec_test.c | 262 ++++++++++++++++++
 5 files changed, 269 insertions(+), 1 deletion(-)
 create mode 100644 tools/testing/selftests/openat2/config
 create mode 100644 tools/testing/selftests/openat2/omayexec_test.c

diff --git a/tools/testing/selftests/kselftest_harness.h b/tools/testing/selftests/kselftest_harness.h
index c9f03ef93338..68a0acd9ea1e 100644
--- a/tools/testing/selftests/kselftest_harness.h
+++ b/tools/testing/selftests/kselftest_harness.h
@@ -50,7 +50,10 @@
 #ifndef __KSELFTEST_HARNESS_H
 #define __KSELFTEST_HARNESS_H
 
+#ifndef _GNU_SOURCE
 #define _GNU_SOURCE
+#endif
+
 #include <asm/types.h>
 #include <errno.h>
 #include <stdbool.h>
diff --git a/tools/testing/selftests/openat2/Makefile b/tools/testing/selftests/openat2/Makefile
index 4b93b1417b86..cb98bdb4d5b1 100644
--- a/tools/testing/selftests/openat2/Makefile
+++ b/tools/testing/selftests/openat2/Makefile
@@ -1,7 +1,8 @@
 # SPDX-License-Identifier: GPL-2.0-or-later
 
 CFLAGS += -Wall -O2 -g -fsanitize=address -fsanitize=undefined
-TEST_GEN_PROGS := openat2_test resolve_test rename_attack_test
+LDLIBS += -lcap
+TEST_GEN_PROGS := openat2_test resolve_test rename_attack_test omayexec_test
 
 include ../lib.mk
 
diff --git a/tools/testing/selftests/openat2/config b/tools/testing/selftests/openat2/config
new file mode 100644
index 000000000000..dd53c266bf52
--- /dev/null
+++ b/tools/testing/selftests/openat2/config
@@ -0,0 +1 @@
+CONFIG_SYSCTL=y
diff --git a/tools/testing/selftests/openat2/helpers.h b/tools/testing/selftests/openat2/helpers.h
index a6ea27344db2..1dcd3e1e2f38 100644
--- a/tools/testing/selftests/openat2/helpers.h
+++ b/tools/testing/selftests/openat2/helpers.h
@@ -9,6 +9,7 @@
 
 #define _GNU_SOURCE
 #include <stdint.h>
+#include <stdbool.h>
 #include <errno.h>
 #include <linux/types.h>
 #include "../kselftest.h"
diff --git a/tools/testing/selftests/openat2/omayexec_test.c b/tools/testing/selftests/openat2/omayexec_test.c
new file mode 100644
index 000000000000..a33f31e59045
--- /dev/null
+++ b/tools/testing/selftests/openat2/omayexec_test.c
@@ -0,0 +1,262 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Test O_MAYEXEC
+ *
+ * Copyright © 2018-2020 ANSSI
+ *
+ * Author: Mickaël Salaün <mic@digikod.net>
+ */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/capability.h>
+#include <sys/mount.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include "helpers.h"
+#include "../kselftest_harness.h"
+
+#ifndef O_MAYEXEC
+#define O_MAYEXEC		040000000
+#endif
+
+static const char sysctl_path[] = "/proc/sys/fs/open_mayexec_enforce";
+
+static const char workdir_path[] = "./test-mount";
+static const char file_path[] = "./test-mount/file";
+static const char dir_path[] = "./test-mount/directory";
+
+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_code)
+{
+	struct open_how how = {
+		.flags = O_RDONLY | O_CLOEXEC,
+	};
+	int fd;
+
+	/* Opens without O_MAYEXEC. */
+	fd = sys_openat2(AT_FDCWD, path, &how);
+	ASSERT_LE(0, fd);
+	EXPECT_EQ(0, close(fd));
+
+	how.flags |= O_MAYEXEC;
+
+	/* Checks that O_MAYEXEC is ignored with open(2). */
+	fd = open(path, how.flags);
+	ASSERT_LE(0, fd);
+	EXPECT_EQ(0, close(fd));
+
+	/* Checks that O_MAYEXEC is ignored with openat(2). */
+	fd = openat(AT_FDCWD, path, how.flags);
+	ASSERT_LE(0, fd);
+	EXPECT_EQ(0, close(fd));
+
+	/* Opens with O_MAYEXEC. */
+	fd = sys_openat2(AT_FDCWD, path, &how);
+	if (!err_code) {
+		ASSERT_LE(0, fd);
+		EXPECT_EQ(0, close(fd));
+	} else {
+		ASSERT_EQ(err_code, fd);
+	}
+}
+
+static void test_omx_dir_file(struct __test_metadata *_metadata, const int err_code)
+{
+	test_omx(_metadata, dir_path, -EISDIR);
+	test_omx(_metadata, file_path, err_code);
+}
+
+static void test_dir_file(struct __test_metadata *_metadata, const int err_code)
+{
+	/* Tests as root. */
+	ignore_dac(_metadata, 1);
+	test_omx_dir_file(_metadata, err_code);
+
+	/* Tests without bypass. */
+	ignore_dac(_metadata, 0);
+	test_omx_dir_file(_metadata, err_code);
+}
+
+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(omayexec) {
+	char initial_sysctl_value;
+};
+
+FIXTURE_VARIANT(omayexec) {
+	const bool mount_exec;
+	const bool file_exec;
+	const int sysctl_err_code[3];
+};
+
+FIXTURE_VARIANT_ADD(omayexec, mount_exec_file_exec) {
+	.mount_exec = true,
+	.file_exec = true,
+	.sysctl_err_code = {0, 0, 0},
+};
+
+FIXTURE_VARIANT_ADD(omayexec, mount_exec_file_noexec)
+{
+	.mount_exec = true,
+	.file_exec = false,
+	.sysctl_err_code = {0, -EACCES, -EACCES},
+};
+
+FIXTURE_VARIANT_ADD(omayexec, mount_noexec_file_exec)
+{
+	.mount_exec = false,
+	.file_exec = true,
+	.sysctl_err_code = {-EACCES, 0, -EACCES},
+};
+
+FIXTURE_VARIANT_ADD(omayexec, mount_noexec_file_noexec)
+{
+	.mount_exec = false,
+	.file_exec = false,
+	.sysctl_err_code = {-EACCES, -EACCES, -EACCES},
+};
+
+FIXTURE_SETUP(omayexec)
+{
+	int fd;
+
+	/*
+	 * 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 test file. */
+	fd = open(file_path, O_CREAT | O_RDONLY | O_CLOEXEC,
+			variant->file_exec ? 00500 : 00400);
+	ASSERT_LE(0, fd);
+	EXPECT_EQ(0, close(fd));
+
+	/* Creates a test directory. */
+	ASSERT_EQ(0, mkdir(dir_path, variant->file_exec ? 00500 : 00400));
+
+	/* Saves initial sysctl value. */
+	self->initial_sysctl_value = sysctl_read_char(_metadata);
+
+	/* Prepares for sysctl writes. */
+	ignore_sys_admin(_metadata, 1);
+}
+
+FIXTURE_TEARDOWN(omayexec)
+{
+	/* Restores initial sysctl value. */
+	sysctl_write_char(_metadata, self->initial_sysctl_value);
+
+	/* There is no need to unlink file_path nor dir_path. */
+	ASSERT_EQ(0, umount(workdir_path));
+	ASSERT_EQ(0, rmdir(workdir_path));
+}
+
+TEST_F(omayexec, sysctl_0)
+{
+	/* Do not enforce anything. */
+	sysctl_write_char(_metadata, '0');
+	test_dir_file(_metadata, 0);
+}
+
+TEST_F(omayexec, sysctl_1)
+{
+	/* Enforces mount exec check. */
+	sysctl_write_char(_metadata, '1');
+	test_dir_file(_metadata, variant->sysctl_err_code[0]);
+}
+
+TEST_F(omayexec, sysctl_2)
+{
+	/* Enforces file exec check. */
+	sysctl_write_char(_metadata, '2');
+	test_dir_file(_metadata, variant->sysctl_err_code[1]);
+}
+
+TEST_F(omayexec, sysctl_3)
+{
+	/* Enforces mount and file exec check. */
+	sysctl_write_char(_metadata, '3');
+	test_dir_file(_metadata, variant->sysctl_err_code[2]);
+}
+
+TEST(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.27.0


^ permalink raw reply	[flat|nested] 25+ messages in thread

* [PATCH v6 7/7] ima: add policy support for the new file open MAY_OPENEXEC flag
  2020-07-14 18:16 [PATCH v6 0/7] Add support for O_MAYEXEC Mickaël Salaün
                   ` (5 preceding siblings ...)
  2020-07-14 18:16 ` [PATCH v6 6/7] selftest/openat2: Add tests for O_MAYEXEC enforcing Mickaël Salaün
@ 2020-07-14 18:16 ` Mickaël Salaün
  2020-07-15 20:40   ` Kees Cook
  6 siblings, 1 reply; 25+ messages in thread
From: Mickaël Salaün @ 2020-07-14 18:16 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, Mickaël Salaün, 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

From: Mimi Zohar <zohar@linux.ibm.com>

The kernel has no way of differentiating between a file containing data
or code being opened by an interpreter.  The proposed O_MAYEXEC
openat2(2) flag bridges this gap by defining and enabling the
MAY_OPENEXEC flag.

This patch adds IMA policy support for the new MAY_OPENEXEC flag.

Example:
measure func=FILE_CHECK mask=^MAY_OPENEXEC
appraise func=FILE_CHECK appraise_type=imasig mask=^MAY_OPENEXEC

Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
Reviewed-by: Lakshmi Ramasubramanian <nramas@linux.microsoft.com>
Acked-by: Mickaël Salaün <mic@digikod.net>
Link: https://lore.kernel.org/r/1588167523-7866-3-git-send-email-zohar@linux.ibm.com
---
 Documentation/ABI/testing/ima_policy |  2 +-
 security/integrity/ima/ima_main.c    |  3 ++-
 security/integrity/ima/ima_policy.c  | 15 +++++++++++----
 3 files changed, 14 insertions(+), 6 deletions(-)

diff --git a/Documentation/ABI/testing/ima_policy b/Documentation/ABI/testing/ima_policy
index cd572912c593..caca46125fe0 100644
--- a/Documentation/ABI/testing/ima_policy
+++ b/Documentation/ABI/testing/ima_policy
@@ -31,7 +31,7 @@ Description:
 				[KEXEC_KERNEL_CHECK] [KEXEC_INITRAMFS_CHECK]
 				[KEXEC_CMDLINE] [KEY_CHECK]
 			mask:= [[^]MAY_READ] [[^]MAY_WRITE] [[^]MAY_APPEND]
-			       [[^]MAY_EXEC]
+			       [[^]MAY_EXEC] [[^]MAY_OPENEXEC]
 			fsmagic:= hex value
 			fsuuid:= file system UUID (e.g 8bcbe394-4f13-4144-be8e-5aa9ea2ce2f6)
 			uid:= decimal value
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index c1583d98c5e5..59fd1658a203 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -490,7 +490,8 @@ int ima_file_check(struct file *file, int mask)
 
 	security_task_getsecid(current, &secid);
 	return process_measurement(file, current_cred(), secid, NULL, 0,
-				   mask & (MAY_READ | MAY_WRITE | MAY_EXEC |
+				   mask & (MAY_READ | MAY_WRITE |
+					   MAY_EXEC | MAY_OPENEXEC |
 					   MAY_APPEND), FILE_CHECK);
 }
 EXPORT_SYMBOL_GPL(ima_file_check);
diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
index e493063a3c34..6487f0b2afdd 100644
--- a/security/integrity/ima/ima_policy.c
+++ b/security/integrity/ima/ima_policy.c
@@ -406,7 +406,8 @@ static bool ima_match_keyring(struct ima_rule_entry *rule,
  * @cred: a pointer to a credentials structure for user validation
  * @secid: the secid of the task to be validated
  * @func: LIM hook identifier
- * @mask: requested action (MAY_READ | MAY_WRITE | MAY_APPEND | MAY_EXEC)
+ * @mask: requested action (MAY_READ | MAY_WRITE | MAY_APPEND | MAY_EXEC |
+ *			    MAY_OPENEXEC)
  * @keyring: keyring name to check in policy for KEY_CHECK func
  *
  * Returns true on rule match, false on failure.
@@ -527,7 +528,8 @@ static int get_subaction(struct ima_rule_entry *rule, enum ima_hooks func)
  *        being made
  * @secid: LSM secid of the task to be validated
  * @func: IMA hook identifier
- * @mask: requested action (MAY_READ | MAY_WRITE | MAY_APPEND | MAY_EXEC)
+ * @mask: requested action (MAY_READ | MAY_WRITE | MAY_APPEND | MAY_EXEC |
+ *			    MAY_OPENEXEC)
  * @pcr: set the pcr to extend
  * @template_desc: the template that should be used for this rule
  * @keyring: the keyring name, if given, to be used to check in the policy.
@@ -1091,6 +1093,8 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)
 				entry->mask = MAY_READ;
 			else if (strcmp(from, "MAY_APPEND") == 0)
 				entry->mask = MAY_APPEND;
+			else if (strcmp(from, "MAY_OPENEXEC") == 0)
+				entry->mask = MAY_OPENEXEC;
 			else
 				result = -EINVAL;
 			if (!result)
@@ -1422,14 +1426,15 @@ const char *const func_tokens[] = {
 
 #ifdef	CONFIG_IMA_READ_POLICY
 enum {
-	mask_exec = 0, mask_write, mask_read, mask_append
+	mask_exec = 0, mask_write, mask_read, mask_append, mask_openexec
 };
 
 static const char *const mask_tokens[] = {
 	"^MAY_EXEC",
 	"^MAY_WRITE",
 	"^MAY_READ",
-	"^MAY_APPEND"
+	"^MAY_APPEND",
+	"^MAY_OPENEXEC"
 };
 
 void *ima_policy_start(struct seq_file *m, loff_t *pos)
@@ -1518,6 +1523,8 @@ int ima_policy_show(struct seq_file *m, void *v)
 			seq_printf(m, pt(Opt_mask), mt(mask_read) + offset);
 		if (entry->mask & MAY_APPEND)
 			seq_printf(m, pt(Opt_mask), mt(mask_append) + offset);
+		if (entry->mask & MAY_OPENEXEC)
+			seq_printf(m, pt(Opt_mask), mt(mask_openexec) + offset);
 		seq_puts(m, " ");
 	}
 
-- 
2.27.0


^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH v6 5/7] fs,doc: Enable to enforce noexec mounts or file exec through O_MAYEXEC
  2020-07-14 18:16 ` [PATCH v6 5/7] fs,doc: Enable to enforce noexec mounts or file exec through O_MAYEXEC Mickaël Salaün
@ 2020-07-14 18:40   ` Randy Dunlap
  2020-07-16 14:40     ` Mickaël Salaün
  2020-07-15 20:37   ` Kees Cook
  1 sibling, 1 reply; 25+ messages in thread
From: Randy Dunlap @ 2020-07-14 18:40 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,
	Mickaël Salaün, 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,

On 7/14/20 11:16 AM, Mickaël Salaün wrote:

> ---
>  Documentation/admin-guide/sysctl/fs.rst | 45 +++++++++++++++++++++++++
>  fs/namei.c                              | 29 +++++++++++++---
>  include/linux/fs.h                      |  1 +
>  kernel/sysctl.c                         | 12 +++++--
>  4 files changed, 80 insertions(+), 7 deletions(-)
> 
> diff --git a/Documentation/admin-guide/sysctl/fs.rst b/Documentation/admin-guide/sysctl/fs.rst
> index 2a45119e3331..02ec384b8bbf 100644
> --- a/Documentation/admin-guide/sysctl/fs.rst
> +++ b/Documentation/admin-guide/sysctl/fs.rst

Reviewed-by: Randy Dunlap <rdunlap@infradead.org>

with one tiny nit:

> @@ -165,6 +166,50 @@ system needs to prune the inode list instead of allocating
> +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

Can you move that period from the beginning of the line to the end of the
previous line?

> +kernel or mapped as executable memory (e.g. libraries).  With script
> +interpreters using the ``O_MAYEXEC`` flag, the executable permission can then
> +be checked before reading commands from files. This makes it possible to
> +enforce the ``noexec`` at the interpreter level, and thus propagates this
> +security policy to scripts.  To be fully effective, these interpreters also
> +need to handle the other ways to execute code: command line parameters (e.g.,
> +option ``-e`` for Perl), module loading (e.g., option ``-m`` for Python),
> +stdin, file sourcing, environment variables, configuration files, etc.
> +According to the threat model, it may be acceptable to allow some script
> +interpreters (e.g. Bash) to interpret commands from stdin, may it be a TTY or a
> +pipe, because it may not be enough to (directly) perform syscalls.

thanks.
-- 
~Randy


^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH v6 4/7] fs: Introduce O_MAYEXEC flag for openat2(2)
  2020-07-14 18:16 ` [PATCH v6 4/7] fs: Introduce O_MAYEXEC flag for openat2(2) Mickaël Salaün
@ 2020-07-15 20:06   ` Kees Cook
  2020-07-16 14:18     ` Mickaël Salaün
  0 siblings, 1 reply; 25+ messages in thread
From: Kees Cook @ 2020-07-15 20:06 UTC (permalink / raw)
  To: 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, Lakshmi Ramasubramanian,
	Matthew Garrett, Matthew Wilcox, Michael Kerrisk,
	Mickaël Salaün, 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, Jul 14, 2020 at 08:16:35PM +0200, Mickaël Salaün wrote:
> When the O_MAYEXEC flag is passed, openat2(2) may be subject to
> additional restrictions depending on a security policy managed by the
> kernel through a sysctl or implemented by an LSM thanks to the
> inode_permission hook.  This new flag is ignored by open(2) and
> openat(2) because of their unspecified flags handling.
> 
> The underlying idea is to be able to restrict scripts interpretation
> according to a policy defined by the system administrator.  For this to
> be possible, script interpreters must use the O_MAYEXEC flag
> appropriately.  To be fully effective, these interpreters also need to
> handle the other ways to execute code: command line parameters (e.g.,
> option -e for Perl), module loading (e.g., option -m for Python), stdin,
> file sourcing, environment variables, configuration files, etc.
> According to the threat model, it may be acceptable to allow some script
> interpreters (e.g. Bash) to interpret commands from stdin, may it be a
> TTY or a pipe, because it may not be enough to (directly) perform
> syscalls.  Further documentation can be found in a following patch.
> 
> Even without enforced security policy, userland interpreters can set it
> to enforce the system policy at their level, knowing that it will not
> break anything on running systems which do not care about this feature.
> However, on systems which want this feature enforced, there will be
> knowledgeable people (i.e. sysadmins who enforced O_MAYEXEC
> deliberately) to manage it.  A simple security policy implementation,
> configured through a dedicated sysctl, is available in a following
> patch.
> 
> O_MAYEXEC should not be confused with the O_EXEC flag which is intended
> for execute-only, which obviously doesn't work for scripts.  However, a
> similar behavior could be implemented in userland with O_PATH:
> https://lore.kernel.org/lkml/1e2f6913-42f2-3578-28ed-567f6a4bdda1@digikod.net/
> 
> The implementation of O_MAYEXEC almost duplicates what execve(2) and
> uselib(2) are already doing: setting MAY_OPENEXEC in acc_mode (which can
> then be checked as MAY_EXEC, if enforced), and propagating FMODE_EXEC to
> _fmode via __FMODE_EXEC flag (which can then trigger a
> fanotify/FAN_OPEN_EXEC event).
> 
> This is an updated subset of the patch initially written by Vincent
> Strubel for CLIP OS 4:
> https://github.com/clipos-archive/src_platform_clip-patches/blob/f5cb330d6b684752e403b4e41b39f7004d88e561/1901_open_mayexec.patch
> This patch has been used for more than 12 years with customized script
> interpreters.  Some examples (with the original name O_MAYEXEC) can be
> found here:
> https://github.com/clipos-archive/clipos4_portage-overlay/search?q=O_MAYEXEC
> 
> Co-developed-by: Vincent Strubel <vincent.strubel@ssi.gouv.fr>
> Signed-off-by: Vincent Strubel <vincent.strubel@ssi.gouv.fr>
> 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@digikod.net>
> Reviewed-by: Deven Bowers <deven.desai@linux.microsoft.com>
> Reviewed-by: Kees Cook <keescook@chromium.org>
> Cc: Aleksa Sarai <cyphar@cyphar.com>
> Cc: Al Viro <viro@zeniv.linux.org.uk>
> ---
> 
> Changes since v5:
> * Update commit message.
> 
> Changes since v3:
> * Switch back to O_MAYEXEC, but only handle it with openat2(2) which
>   checks unknown flags (suggested by Aleksa Sarai). Cf.
>   https://lore.kernel.org/lkml/20200430015429.wuob7m5ofdewubui@yavin.dot.cyphar.com/
> 
> Changes since v2:
> * Replace O_MAYEXEC with RESOLVE_MAYEXEC from openat2(2).  This change
>   enables to not break existing application using bogus O_* flags that
>   may be ignored by current kernels by using a new dedicated flag, only
>   usable through openat2(2) (suggested by Jeff Layton).  Using this flag
>   will results in an error if the running kernel does not support it.
>   User space needs to manage this case, as with other RESOLVE_* flags.
>   The best effort approach to security (for most common distros) will
>   simply consists of ignoring such an error and retry without
>   RESOLVE_MAYEXEC.  However, a fully controlled system may which to
>   error out if such an inconsistency is detected.
> 
> Changes since v1:
> * Set __FMODE_EXEC when using O_MAYEXEC to make this information
>   available through the new fanotify/FAN_OPEN_EXEC event (suggested by
>   Jan Kara and Matthew Bobrowski):
>   https://lore.kernel.org/lkml/20181213094658.GA996@lithium.mbobrowski.org/
> ---
>  fs/fcntl.c                       | 2 +-
>  fs/open.c                        | 8 ++++++++
>  include/linux/fcntl.h            | 2 +-
>  include/linux/fs.h               | 2 ++
>  include/uapi/asm-generic/fcntl.h | 7 +++++++
>  5 files changed, 19 insertions(+), 2 deletions(-)
> 
> diff --git a/fs/fcntl.c b/fs/fcntl.c
> index 2e4c0fa2074b..0357ad667563 100644
> --- a/fs/fcntl.c
> +++ b/fs/fcntl.c
> @@ -1033,7 +1033,7 @@ static int __init fcntl_init(void)
>  	 * Exceptions: O_NONBLOCK is a two bit define on parisc; O_NDELAY
>  	 * is defined as O_NONBLOCK on some platforms and not on others.
>  	 */
> -	BUILD_BUG_ON(21 - 1 /* for O_RDONLY being 0 */ !=
> +	BUILD_BUG_ON(22 - 1 /* for O_RDONLY being 0 */ !=
>  		HWEIGHT32(
>  			(VALID_OPEN_FLAGS & ~(O_NONBLOCK | O_NDELAY)) |
>  			__FMODE_EXEC | __FMODE_NONOTIFY));
> diff --git a/fs/open.c b/fs/open.c
> index 623b7506a6db..38e434bdbbb6 100644
> --- a/fs/open.c
> +++ b/fs/open.c
> @@ -987,6 +987,8 @@ inline struct open_how build_open_how(int flags, umode_t mode)
>  		.mode = mode & S_IALLUGO,
>  	};
>  
> +	/* O_MAYEXEC is ignored by syscalls relying on build_open_how(). */
> +	how.flags &= ~O_MAYEXEC;
>  	/* O_PATH beats everything else. */
>  	if (how.flags & O_PATH)
>  		how.flags &= O_PATH_FLAGS;
> @@ -1054,6 +1056,12 @@ inline int build_open_flags(const struct open_how *how, struct open_flags *op)
>  	if (flags & __O_SYNC)
>  		flags |= O_DSYNC;
>  
> +	/* Checks execution permissions on open. */
> +	if (flags & O_MAYEXEC) {
> +		acc_mode |= MAY_OPENEXEC;
> +		flags |= __FMODE_EXEC;
> +	}

Adding __FMODE_EXEC here will immediately change the behaviors of NFS
and fsnotify. If that's going to happen, I think it needs to be under
the control of the later patches doing the behavioral controls.
(specifically, NFS looks like it completely changes its access control
test when this is set and ignores the read/write checks entirely, which
is not what's wanted).


-- 
Kees Cook

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH v6 5/7] fs,doc: Enable to enforce noexec mounts or file exec through O_MAYEXEC
  2020-07-14 18:16 ` [PATCH v6 5/7] fs,doc: Enable to enforce noexec mounts or file exec through O_MAYEXEC Mickaël Salaün
  2020-07-14 18:40   ` Randy Dunlap
@ 2020-07-15 20:37   ` Kees Cook
  2020-07-16 14:39     ` Mickaël Salaün
  1 sibling, 1 reply; 25+ messages in thread
From: Kees Cook @ 2020-07-15 20:37 UTC (permalink / raw)
  To: 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, Lakshmi Ramasubramanian,
	Matthew Garrett, Matthew Wilcox, Michael Kerrisk,
	Mickaël Salaün, 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, Jul 14, 2020 at 08:16:36PM +0200, Mickaël Salaün wrote:
> @@ -2849,7 +2855,7 @@ static int may_open(const struct path *path, int acc_mode, int flag)
>  	case S_IFLNK:
>  		return -ELOOP;
>  	case S_IFDIR:
> -		if (acc_mode & (MAY_WRITE | MAY_EXEC))
> +		if (acc_mode & (MAY_WRITE | MAY_EXEC | MAY_OPENEXEC))
>  			return -EISDIR;
>  		break;

(I need to figure out where "open for reading" rejects S_IFDIR, since
it's clearly not here...)

>  	case S_IFBLK:
> @@ -2859,13 +2865,26 @@ static int may_open(const struct path *path, int acc_mode, int flag)
>  		fallthrough;
>  	case S_IFIFO:
>  	case S_IFSOCK:
> -		if (acc_mode & MAY_EXEC)
> +		if (acc_mode & (MAY_EXEC | MAY_OPENEXEC))
>  			return -EACCES;
>  		flag &= ~O_TRUNC;
>  		break;

This will immediately break a system that runs code with MAY_OPENEXEC
set but reads from a block, char, fifo, or socket, even in the case of
a sysadmin leaving the "file" sysctl disabled.

>  	case S_IFREG:
> -		if ((acc_mode & MAY_EXEC) && path_noexec(path))
> -			return -EACCES;
> +		if (path_noexec(path)) {
> +			if (acc_mode & MAY_EXEC)
> +				return -EACCES;
> +			if ((acc_mode & MAY_OPENEXEC) &&
> +					(sysctl_open_mayexec_enforce & OPEN_MAYEXEC_ENFORCE_MOUNT))
> +				return -EACCES;
> +		}
> +		if ((acc_mode & MAY_OPENEXEC) &&
> +				(sysctl_open_mayexec_enforce & OPEN_MAYEXEC_ENFORCE_FILE))
> +			/*
> +			 * Because acc_mode may change here, the next and only
> +			 * use of acc_mode should then be by the following call
> +			 * to inode_permission().
> +			 */
> +			acc_mode |= MAY_EXEC;
>  		break;
>  	}

Likely very minor, but I'd like to avoid the path_noexec() call in the
fast-path (it dereferences a couple pointers where as doing bit tests on
acc_mode is fast).

Given that and the above observations, I think that may_open() likely
needs to start with:

	if (acc_mode & MAY_OPENEXEC) {
		/* Reject all file types when mount enforcement set. */
		if ((sysctl_open_mayexec_enforce & OPEN_MAYEXEC_ENFORCE_MOUNT) &&
		    path_noexec(path))
			return -EACCES;
		/* Treat the same as MAY_EXEC. */
		if (sysctl_open_mayexec_enforce & OPEN_MAYEXEC_ENFORCE_FILE))
			acc_mode |= MAY_EXEC;
	}

(Though I'm not 100% sure that path_noexec() is safe to be called for
all file types: i.e. path->mnt and path->-mnt->mnt_sb *always* non-NULL?)

This change would also imply that OPEN_MAYEXEC_ENFORCE_FILE *includes*
OPEN_MAYEXEC_ENFORCE_MOUNT (i.e. the sysctl should not be a bitfield),
since path_noexec() would get checked for S_ISREG. I can't come up with
a rationale where one would want OPEN_MAYEXEC_ENFORCE_FILE but _not_
OPEN_MAYEXEC_ENFORCE_MOUNT?

(I can absolutely see wanting only OPEN_MAYEXEC_ENFORCE_MOUNT, or
suddenly one has to go mark every loaded thing with the exec bit and
most distros haven't done this to, for example, shared libraries. But
setting the exec bit and then NOT wanting to enforce the mount check
seems... not sensible?)

Outside of this change, yes, I like this now -- it's much cleaner
because we have all the checks in the same place where they belong. :)

> diff --git a/kernel/sysctl.c b/kernel/sysctl.c
> index db1ce7af2563..5008a2566e79 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;

Oh, are these still here? I thought they got removed (or at least made
const). Where did that series go? Hmpf, see sysctl_vals, but yes, for
now, this is fine.

> @@ -888,7 +889,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)
>  {
> @@ -897,7 +897,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
> @@ -3264,6 +3263,15 @@ static struct ctl_table fs_table[] = {
>  		.extra1		= SYSCTL_ZERO,
>  		.extra2		= &two,
>  	},
> +	{
> +		.procname       = "open_mayexec_enforce",
> +		.data           = &sysctl_open_mayexec_enforce,
> +		.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.27.0
> 

-- 
Kees Cook

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH v6 6/7] selftest/openat2: Add tests for O_MAYEXEC enforcing
  2020-07-14 18:16 ` [PATCH v6 6/7] selftest/openat2: Add tests for O_MAYEXEC enforcing Mickaël Salaün
@ 2020-07-15 20:38   ` Kees Cook
  0 siblings, 0 replies; 25+ messages in thread
From: Kees Cook @ 2020-07-15 20:38 UTC (permalink / raw)
  To: 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, Lakshmi Ramasubramanian,
	Matthew Garrett, Matthew Wilcox, Michael Kerrisk,
	Mickaël Salaün, 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, Jul 14, 2020 at 08:16:37PM +0200, Mickaël Salaün wrote:
> Test propagation of noexec mount points or file executability through
> files open with or without O_MAYEXEC, thanks to the
> fs.open_mayexec_enforce sysctl.
> 
> Signed-off-by: Mickaël Salaün <mic@digikod.net>
> Reviewed-by: Thibaut Sautereau <thibaut.sautereau@ssi.gouv.fr>
> Cc: Aleksa Sarai <cyphar@cyphar.com>
> Cc: Al Viro <viro@zeniv.linux.org.uk>
> Cc: Kees Cook <keescook@chromium.org>
> Cc: Shuah Khan <shuah@kernel.org>

Yay variants! :)

Reviewed-by: Kees Cook <keescook@chromium.org>

-- 
Kees Cook

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH v6 7/7] ima: add policy support for the new file open MAY_OPENEXEC flag
  2020-07-14 18:16 ` [PATCH v6 7/7] ima: add policy support for the new file open MAY_OPENEXEC flag Mickaël Salaün
@ 2020-07-15 20:40   ` Kees Cook
  2020-07-16 14:40     ` Mickaël Salaün
  0 siblings, 1 reply; 25+ messages in thread
From: Kees Cook @ 2020-07-15 20:40 UTC (permalink / raw)
  To: 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, Lakshmi Ramasubramanian,
	Matthew Garrett, Matthew Wilcox, Michael Kerrisk,
	Mickaël Salaün, 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, Jul 14, 2020 at 08:16:38PM +0200, Mickaël Salaün wrote:
> From: Mimi Zohar <zohar@linux.ibm.com>
> 
> The kernel has no way of differentiating between a file containing data
> or code being opened by an interpreter.  The proposed O_MAYEXEC
> openat2(2) flag bridges this gap by defining and enabling the
> MAY_OPENEXEC flag.
> 
> This patch adds IMA policy support for the new MAY_OPENEXEC flag.
> 
> Example:
> measure func=FILE_CHECK mask=^MAY_OPENEXEC
> appraise func=FILE_CHECK appraise_type=imasig mask=^MAY_OPENEXEC
> 
> Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
> Reviewed-by: Lakshmi Ramasubramanian <nramas@linux.microsoft.com>
> Acked-by: Mickaël Salaün <mic@digikod.net>

(Process nit: if you're sending this on behalf of another author, then
this should be Signed-off-by rather than Acked-by.)

-- 
Kees Cook

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH v6 4/7] fs: Introduce O_MAYEXEC flag for openat2(2)
  2020-07-15 20:06   ` Kees Cook
@ 2020-07-16 14:18     ` Mickaël Salaün
  2020-07-16 15:31       ` Kees Cook
  0 siblings, 1 reply; 25+ messages in thread
From: Mickaël Salaün @ 2020-07-16 14:18 UTC (permalink / raw)
  To: Kees Cook, Jan Kara, Matthew Bobrowski, linux-nfs
  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,
	Jann Horn, Jonathan Corbet, Lakshmi Ramasubramanian,
	Matthew Garrett, Matthew Wilcox, Michael Kerrisk,
	Mickaël Salaün, 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 15/07/2020 22:06, Kees Cook wrote:
> On Tue, Jul 14, 2020 at 08:16:35PM +0200, Mickaël Salaün wrote:
>> When the O_MAYEXEC flag is passed, openat2(2) may be subject to
>> additional restrictions depending on a security policy managed by the
>> kernel through a sysctl or implemented by an LSM thanks to the
>> inode_permission hook.  This new flag is ignored by open(2) and
>> openat(2) because of their unspecified flags handling.
>>
>> The underlying idea is to be able to restrict scripts interpretation
>> according to a policy defined by the system administrator.  For this to
>> be possible, script interpreters must use the O_MAYEXEC flag
>> appropriately.  To be fully effective, these interpreters also need to
>> handle the other ways to execute code: command line parameters (e.g.,
>> option -e for Perl), module loading (e.g., option -m for Python), stdin,
>> file sourcing, environment variables, configuration files, etc.
>> According to the threat model, it may be acceptable to allow some script
>> interpreters (e.g. Bash) to interpret commands from stdin, may it be a
>> TTY or a pipe, because it may not be enough to (directly) perform
>> syscalls.  Further documentation can be found in a following patch.
>>
>> Even without enforced security policy, userland interpreters can set it
>> to enforce the system policy at their level, knowing that it will not
>> break anything on running systems which do not care about this feature.
>> However, on systems which want this feature enforced, there will be
>> knowledgeable people (i.e. sysadmins who enforced O_MAYEXEC
>> deliberately) to manage it.  A simple security policy implementation,
>> configured through a dedicated sysctl, is available in a following
>> patch.
>>
>> O_MAYEXEC should not be confused with the O_EXEC flag which is intended
>> for execute-only, which obviously doesn't work for scripts.  However, a
>> similar behavior could be implemented in userland with O_PATH:
>> https://lore.kernel.org/lkml/1e2f6913-42f2-3578-28ed-567f6a4bdda1@digikod.net/
>>
>> The implementation of O_MAYEXEC almost duplicates what execve(2) and
>> uselib(2) are already doing: setting MAY_OPENEXEC in acc_mode (which can
>> then be checked as MAY_EXEC, if enforced), and propagating FMODE_EXEC to
>> _fmode via __FMODE_EXEC flag (which can then trigger a
>> fanotify/FAN_OPEN_EXEC event).
>>
>> This is an updated subset of the patch initially written by Vincent
>> Strubel for CLIP OS 4:
>> https://github.com/clipos-archive/src_platform_clip-patches/blob/f5cb330d6b684752e403b4e41b39f7004d88e561/1901_open_mayexec.patch
>> This patch has been used for more than 12 years with customized script
>> interpreters.  Some examples (with the original name O_MAYEXEC) can be
>> found here:
>> https://github.com/clipos-archive/clipos4_portage-overlay/search?q=O_MAYEXEC
>>
>> Co-developed-by: Vincent Strubel <vincent.strubel@ssi.gouv.fr>
>> Signed-off-by: Vincent Strubel <vincent.strubel@ssi.gouv.fr>
>> 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@digikod.net>
>> Reviewed-by: Deven Bowers <deven.desai@linux.microsoft.com>
>> Reviewed-by: Kees Cook <keescook@chromium.org>
>> Cc: Aleksa Sarai <cyphar@cyphar.com>
>> Cc: Al Viro <viro@zeniv.linux.org.uk>
>> ---
>>
>> Changes since v5:
>> * Update commit message.
>>
>> Changes since v3:
>> * Switch back to O_MAYEXEC, but only handle it with openat2(2) which
>>   checks unknown flags (suggested by Aleksa Sarai). Cf.
>>   https://lore.kernel.org/lkml/20200430015429.wuob7m5ofdewubui@yavin.dot.cyphar.com/
>>
>> Changes since v2:
>> * Replace O_MAYEXEC with RESOLVE_MAYEXEC from openat2(2).  This change
>>   enables to not break existing application using bogus O_* flags that
>>   may be ignored by current kernels by using a new dedicated flag, only
>>   usable through openat2(2) (suggested by Jeff Layton).  Using this flag
>>   will results in an error if the running kernel does not support it.
>>   User space needs to manage this case, as with other RESOLVE_* flags.
>>   The best effort approach to security (for most common distros) will
>>   simply consists of ignoring such an error and retry without
>>   RESOLVE_MAYEXEC.  However, a fully controlled system may which to
>>   error out if such an inconsistency is detected.
>>
>> Changes since v1:
>> * Set __FMODE_EXEC when using O_MAYEXEC to make this information
>>   available through the new fanotify/FAN_OPEN_EXEC event (suggested by
>>   Jan Kara and Matthew Bobrowski):
>>   https://lore.kernel.org/lkml/20181213094658.GA996@lithium.mbobrowski.org/
>> ---
>>  fs/fcntl.c                       | 2 +-
>>  fs/open.c                        | 8 ++++++++
>>  include/linux/fcntl.h            | 2 +-
>>  include/linux/fs.h               | 2 ++
>>  include/uapi/asm-generic/fcntl.h | 7 +++++++
>>  5 files changed, 19 insertions(+), 2 deletions(-)
>>
>> diff --git a/fs/fcntl.c b/fs/fcntl.c
>> index 2e4c0fa2074b..0357ad667563 100644
>> --- a/fs/fcntl.c
>> +++ b/fs/fcntl.c
>> @@ -1033,7 +1033,7 @@ static int __init fcntl_init(void)
>>  	 * Exceptions: O_NONBLOCK is a two bit define on parisc; O_NDELAY
>>  	 * is defined as O_NONBLOCK on some platforms and not on others.
>>  	 */
>> -	BUILD_BUG_ON(21 - 1 /* for O_RDONLY being 0 */ !=
>> +	BUILD_BUG_ON(22 - 1 /* for O_RDONLY being 0 */ !=
>>  		HWEIGHT32(
>>  			(VALID_OPEN_FLAGS & ~(O_NONBLOCK | O_NDELAY)) |
>>  			__FMODE_EXEC | __FMODE_NONOTIFY));
>> diff --git a/fs/open.c b/fs/open.c
>> index 623b7506a6db..38e434bdbbb6 100644
>> --- a/fs/open.c
>> +++ b/fs/open.c
>> @@ -987,6 +987,8 @@ inline struct open_how build_open_how(int flags, umode_t mode)
>>  		.mode = mode & S_IALLUGO,
>>  	};
>>  
>> +	/* O_MAYEXEC is ignored by syscalls relying on build_open_how(). */
>> +	how.flags &= ~O_MAYEXEC;
>>  	/* O_PATH beats everything else. */
>>  	if (how.flags & O_PATH)
>>  		how.flags &= O_PATH_FLAGS;
>> @@ -1054,6 +1056,12 @@ inline int build_open_flags(const struct open_how *how, struct open_flags *op)
>>  	if (flags & __O_SYNC)
>>  		flags |= O_DSYNC;
>>  
>> +	/* Checks execution permissions on open. */
>> +	if (flags & O_MAYEXEC) {
>> +		acc_mode |= MAY_OPENEXEC;
>> +		flags |= __FMODE_EXEC;
>> +	}
> 
> Adding __FMODE_EXEC here will immediately change the behaviors of NFS
> and fsnotify. If that's going to happen, I think it needs to be under
> the control of the later patches doing the behavioral controls.
> (specifically, NFS looks like it completely changes its access control
> test when this is set and ignores the read/write checks entirely, which
> is not what's wanted).

__FMODE_EXEC was suggested by Jan Kara and Matthew Bobrowski because of
fsnotify. However, the NFS handling of SUID binaries [1] indeed leads to
an unintended behavior. This also means that uselib(2) shouldn't work
properly with NFS. I can remove the __FMODE_EXEC flag for now.

[1]
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=f8d9a897d4384b77f13781ea813156568f68b83e

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH v6 5/7] fs,doc: Enable to enforce noexec mounts or file exec through O_MAYEXEC
  2020-07-15 20:37   ` Kees Cook
@ 2020-07-16 14:39     ` Mickaël Salaün
  2020-07-22 16:16       ` Thibaut Sautereau
  0 siblings, 1 reply; 25+ messages in thread
From: Mickaël Salaün @ 2020-07-16 14:39 UTC (permalink / raw)
  To: Kees Cook
  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, Lakshmi Ramasubramanian,
	Matthew Garrett, Matthew Wilcox, Michael Kerrisk,
	Mickaël Salaün, 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 15/07/2020 22:37, Kees Cook wrote:
> On Tue, Jul 14, 2020 at 08:16:36PM +0200, Mickaël Salaün wrote:
>> @@ -2849,7 +2855,7 @@ static int may_open(const struct path *path, int acc_mode, int flag)
>>  	case S_IFLNK:
>>  		return -ELOOP;
>>  	case S_IFDIR:
>> -		if (acc_mode & (MAY_WRITE | MAY_EXEC))
>> +		if (acc_mode & (MAY_WRITE | MAY_EXEC | MAY_OPENEXEC))
>>  			return -EISDIR;
>>  		break;
> 
> (I need to figure out where "open for reading" rejects S_IFDIR, since
> it's clearly not here...)
> 
>>  	case S_IFBLK:
>> @@ -2859,13 +2865,26 @@ static int may_open(const struct path *path, int acc_mode, int flag)
>>  		fallthrough;
>>  	case S_IFIFO:
>>  	case S_IFSOCK:
>> -		if (acc_mode & MAY_EXEC)
>> +		if (acc_mode & (MAY_EXEC | MAY_OPENEXEC))
>>  			return -EACCES;
>>  		flag &= ~O_TRUNC;
>>  		break;
> 
> This will immediately break a system that runs code with MAY_OPENEXEC
> set but reads from a block, char, fifo, or socket, even in the case of
> a sysadmin leaving the "file" sysctl disabled.

As documented, O_MAYEXEC is for regular files. The only legitimate use
case seems to be with pipes, which should probably be allowed when
enforcement is disabled.

> 
>>  	case S_IFREG:
>> -		if ((acc_mode & MAY_EXEC) && path_noexec(path))
>> -			return -EACCES;
>> +		if (path_noexec(path)) {
>> +			if (acc_mode & MAY_EXEC)
>> +				return -EACCES;
>> +			if ((acc_mode & MAY_OPENEXEC) &&
>> +					(sysctl_open_mayexec_enforce & OPEN_MAYEXEC_ENFORCE_MOUNT))
>> +				return -EACCES;
>> +		}
>> +		if ((acc_mode & MAY_OPENEXEC) &&
>> +				(sysctl_open_mayexec_enforce & OPEN_MAYEXEC_ENFORCE_FILE))
>> +			/*
>> +			 * Because acc_mode may change here, the next and only
>> +			 * use of acc_mode should then be by the following call
>> +			 * to inode_permission().
>> +			 */
>> +			acc_mode |= MAY_EXEC;
>>  		break;
>>  	}
> 
> Likely very minor, but I'd like to avoid the path_noexec() call in the
> fast-path (it dereferences a couple pointers where as doing bit tests on
> acc_mode is fast).
> 
> Given that and the above observations, I think that may_open() likely
> needs to start with:
> 
> 	if (acc_mode & MAY_OPENEXEC) {
> 		/* Reject all file types when mount enforcement set. */
> 		if ((sysctl_open_mayexec_enforce & OPEN_MAYEXEC_ENFORCE_MOUNT) &&
> 		    path_noexec(path))
> 			return -EACCES;
> 		/* Treat the same as MAY_EXEC. */
> 		if (sysctl_open_mayexec_enforce & OPEN_MAYEXEC_ENFORCE_FILE))
> 			acc_mode |= MAY_EXEC;
> 	}

OK

> 
> (Though I'm not 100% sure that path_noexec() is safe to be called for
> all file types: i.e. path->mnt and path->-mnt->mnt_sb *always* non-NULL?)

path->mnt should always be non-NULL:
https://lore.kernel.org/lkml/20200317164709.GA23230@ZenIV.linux.org.uk/

> 
> This change would also imply that OPEN_MAYEXEC_ENFORCE_FILE *includes*
> OPEN_MAYEXEC_ENFORCE_MOUNT (i.e. the sysctl should not be a bitfield),
> since path_noexec() would get checked for S_ISREG. I can't come up with
> a rationale where one would want OPEN_MAYEXEC_ENFORCE_FILE but _not_
> OPEN_MAYEXEC_ENFORCE_MOUNT?

I don't see why it is an inclusion.

> 
> (I can absolutely see wanting only OPEN_MAYEXEC_ENFORCE_MOUNT, or
> suddenly one has to go mark every loaded thing with the exec bit and
> most distros haven't done this to, for example, shared libraries. But
> setting the exec bit and then NOT wanting to enforce the mount check
> seems... not sensible?)
> 
> Outside of this change, yes, I like this now -- it's much cleaner
> because we have all the checks in the same place where they belong. :)
> 
>> diff --git a/kernel/sysctl.c b/kernel/sysctl.c
>> index db1ce7af2563..5008a2566e79 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;
> 
> Oh, are these still here? I thought they got removed (or at least made
> const). Where did that series go? Hmpf, see sysctl_vals, but yes, for
> now, this is fine.
> 
>> @@ -888,7 +889,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)
>>  {
>> @@ -897,7 +897,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
>> @@ -3264,6 +3263,15 @@ static struct ctl_table fs_table[] = {
>>  		.extra1		= SYSCTL_ZERO,
>>  		.extra2		= &two,
>>  	},
>> +	{
>> +		.procname       = "open_mayexec_enforce",
>> +		.data           = &sysctl_open_mayexec_enforce,
>> +		.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.27.0
>>
> 

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH v6 7/7] ima: add policy support for the new file open MAY_OPENEXEC flag
  2020-07-15 20:40   ` Kees Cook
@ 2020-07-16 14:40     ` Mickaël Salaün
  2020-07-16 14:59       ` Randy Dunlap
  2020-07-16 19:12       ` Kees Cook
  0 siblings, 2 replies; 25+ messages in thread
From: Mickaël Salaün @ 2020-07-16 14:40 UTC (permalink / raw)
  To: Kees Cook
  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, Lakshmi Ramasubramanian,
	Matthew Garrett, Matthew Wilcox, Michael Kerrisk,
	Mickaël Salaün, 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 15/07/2020 22:40, Kees Cook wrote:
> On Tue, Jul 14, 2020 at 08:16:38PM +0200, Mickaël Salaün wrote:
>> From: Mimi Zohar <zohar@linux.ibm.com>
>>
>> The kernel has no way of differentiating between a file containing data
>> or code being opened by an interpreter.  The proposed O_MAYEXEC
>> openat2(2) flag bridges this gap by defining and enabling the
>> MAY_OPENEXEC flag.
>>
>> This patch adds IMA policy support for the new MAY_OPENEXEC flag.
>>
>> Example:
>> measure func=FILE_CHECK mask=^MAY_OPENEXEC
>> appraise func=FILE_CHECK appraise_type=imasig mask=^MAY_OPENEXEC
>>
>> Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
>> Reviewed-by: Lakshmi Ramasubramanian <nramas@linux.microsoft.com>
>> Acked-by: Mickaël Salaün <mic@digikod.net>
> 
> (Process nit: if you're sending this on behalf of another author, then
> this should be Signed-off-by rather than Acked-by.)

I'm not a co-author of this patch.

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH v6 5/7] fs,doc: Enable to enforce noexec mounts or file exec through O_MAYEXEC
  2020-07-14 18:40   ` Randy Dunlap
@ 2020-07-16 14:40     ` Mickaël Salaün
  0 siblings, 0 replies; 25+ messages in thread
From: Mickaël Salaün @ 2020-07-16 14:40 UTC (permalink / raw)
  To: Randy Dunlap, 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,
	Mickaël Salaün, 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 14/07/2020 20:40, Randy Dunlap wrote:
> Hi,
> 
> On 7/14/20 11:16 AM, Mickaël Salaün wrote:
> 
>> ---
>>  Documentation/admin-guide/sysctl/fs.rst | 45 +++++++++++++++++++++++++
>>  fs/namei.c                              | 29 +++++++++++++---
>>  include/linux/fs.h                      |  1 +
>>  kernel/sysctl.c                         | 12 +++++--
>>  4 files changed, 80 insertions(+), 7 deletions(-)
>>
>> diff --git a/Documentation/admin-guide/sysctl/fs.rst b/Documentation/admin-guide/sysctl/fs.rst
>> index 2a45119e3331..02ec384b8bbf 100644
>> --- a/Documentation/admin-guide/sysctl/fs.rst
>> +++ b/Documentation/admin-guide/sysctl/fs.rst
> 
> Reviewed-by: Randy Dunlap <rdunlap@infradead.org>
> 
> with one tiny nit:
> 
>> @@ -165,6 +166,50 @@ system needs to prune the inode list instead of allocating
>> +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
> 
> Can you move that period from the beginning of the line to the end of the
> previous line?

OK, done. Thanks!

> 
>> +kernel or mapped as executable memory (e.g. libraries).  With script
>> +interpreters using the ``O_MAYEXEC`` flag, the executable permission can then
>> +be checked before reading commands from files. This makes it possible to
>> +enforce the ``noexec`` at the interpreter level, and thus propagates this
>> +security policy to scripts.  To be fully effective, these interpreters also
>> +need to handle the other ways to execute code: command line parameters (e.g.,
>> +option ``-e`` for Perl), module loading (e.g., option ``-m`` for Python),
>> +stdin, file sourcing, environment variables, configuration files, etc.
>> +According to the threat model, it may be acceptable to allow some script
>> +interpreters (e.g. Bash) to interpret commands from stdin, may it be a TTY or a
>> +pipe, because it may not be enough to (directly) perform syscalls.
> 
> thanks.
> 

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH v6 7/7] ima: add policy support for the new file open MAY_OPENEXEC flag
  2020-07-16 14:40     ` Mickaël Salaün
@ 2020-07-16 14:59       ` Randy Dunlap
  2020-07-16 15:22         ` Mickaël Salaün
  2020-07-16 19:13         ` Kees Cook
  2020-07-16 19:12       ` Kees Cook
  1 sibling, 2 replies; 25+ messages in thread
From: Randy Dunlap @ 2020-07-16 14:59 UTC (permalink / raw)
  To: Mickaël Salaün, Kees Cook
  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, Lakshmi Ramasubramanian,
	Matthew Garrett, Matthew Wilcox, Michael Kerrisk,
	Mickaël Salaün, 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 7/16/20 7:40 AM, Mickaël Salaün wrote:
> 
> On 15/07/2020 22:40, Kees Cook wrote:
>> On Tue, Jul 14, 2020 at 08:16:38PM +0200, Mickaël Salaün wrote:
>>> From: Mimi Zohar <zohar@linux.ibm.com>
>>>
>>> The kernel has no way of differentiating between a file containing data
>>> or code being opened by an interpreter.  The proposed O_MAYEXEC
>>> openat2(2) flag bridges this gap by defining and enabling the
>>> MAY_OPENEXEC flag.
>>>
>>> This patch adds IMA policy support for the new MAY_OPENEXEC flag.
>>>
>>> Example:
>>> measure func=FILE_CHECK mask=^MAY_OPENEXEC
>>> appraise func=FILE_CHECK appraise_type=imasig mask=^MAY_OPENEXEC
>>>
>>> Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
>>> Reviewed-by: Lakshmi Ramasubramanian <nramas@linux.microsoft.com>
>>> Acked-by: Mickaël Salaün <mic@digikod.net>
>>
>> (Process nit: if you're sending this on behalf of another author, then
>> this should be Signed-off-by rather than Acked-by.)
> 
> I'm not a co-author of this patch.
> 

from Documentation/process/submitting-patches.rst:

The Signed-off-by: tag indicates that the signer was involved in the
development of the patch, or that he/she was in the patch's delivery path.
                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

-- 
~Randy


^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH v6 7/7] ima: add policy support for the new file open MAY_OPENEXEC flag
  2020-07-16 14:59       ` Randy Dunlap
@ 2020-07-16 15:22         ` Mickaël Salaün
  2020-07-16 19:13         ` Kees Cook
  1 sibling, 0 replies; 25+ messages in thread
From: Mickaël Salaün @ 2020-07-16 15:22 UTC (permalink / raw)
  To: Randy Dunlap, Kees Cook
  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, Lakshmi Ramasubramanian,
	Matthew Garrett, Matthew Wilcox, Michael Kerrisk,
	Mickaël Salaün, 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 16/07/2020 16:59, Randy Dunlap wrote:
> On 7/16/20 7:40 AM, Mickaël Salaün wrote:
>>
>> On 15/07/2020 22:40, Kees Cook wrote:
>>> On Tue, Jul 14, 2020 at 08:16:38PM +0200, Mickaël Salaün wrote:
>>>> From: Mimi Zohar <zohar@linux.ibm.com>
>>>>
>>>> The kernel has no way of differentiating between a file containing data
>>>> or code being opened by an interpreter.  The proposed O_MAYEXEC
>>>> openat2(2) flag bridges this gap by defining and enabling the
>>>> MAY_OPENEXEC flag.
>>>>
>>>> This patch adds IMA policy support for the new MAY_OPENEXEC flag.
>>>>
>>>> Example:
>>>> measure func=FILE_CHECK mask=^MAY_OPENEXEC
>>>> appraise func=FILE_CHECK appraise_type=imasig mask=^MAY_OPENEXEC
>>>>
>>>> Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
>>>> Reviewed-by: Lakshmi Ramasubramanian <nramas@linux.microsoft.com>
>>>> Acked-by: Mickaël Salaün <mic@digikod.net>
>>>
>>> (Process nit: if you're sending this on behalf of another author, then
>>> this should be Signed-off-by rather than Acked-by.)
>>
>> I'm not a co-author of this patch.
>>
> 
> from Documentation/process/submitting-patches.rst:
> 
> The Signed-off-by: tag indicates that the signer was involved in the
> development of the patch, or that he/she was in the patch's delivery path.
>                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> 

OK, I though such tag had to go along with the From/Author, the
Committer or a Co-developed-by tag, but there is also this specific
case. I'll fix that in the next series.

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH v6 4/7] fs: Introduce O_MAYEXEC flag for openat2(2)
  2020-07-16 14:18     ` Mickaël Salaün
@ 2020-07-16 15:31       ` Kees Cook
  0 siblings, 0 replies; 25+ messages in thread
From: Kees Cook @ 2020-07-16 15:31 UTC (permalink / raw)
  To: Mickaël Salaün
  Cc: Jan Kara, Matthew Bobrowski, linux-nfs, 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, Jann Horn,
	Jonathan Corbet, Lakshmi Ramasubramanian, Matthew Garrett,
	Matthew Wilcox, Michael Kerrisk, Mickaël Salaün,
	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 Thu, Jul 16, 2020 at 04:18:27PM +0200, Mickaël Salaün wrote:
> On 15/07/2020 22:06, Kees Cook wrote:
> > On Tue, Jul 14, 2020 at 08:16:35PM +0200, Mickaël Salaün wrote:
> >> The implementation of O_MAYEXEC almost duplicates what execve(2) and
> >> uselib(2) are already doing: setting MAY_OPENEXEC in acc_mode (which can
> >> then be checked as MAY_EXEC, if enforced), and propagating FMODE_EXEC to
> >> _fmode via __FMODE_EXEC flag (which can then trigger a
> >> fanotify/FAN_OPEN_EXEC event).
> >> [...]
> > 
> > Adding __FMODE_EXEC here will immediately change the behaviors of NFS
> > and fsnotify. If that's going to happen, I think it needs to be under
> > the control of the later patches doing the behavioral controls.
> > (specifically, NFS looks like it completely changes its access control
> > test when this is set and ignores the read/write checks entirely, which
> > is not what's wanted).
> 
> __FMODE_EXEC was suggested by Jan Kara and Matthew Bobrowski because of
> fsnotify. However, the NFS handling of SUID binaries [1] indeed leads to
> an unintended behavior. This also means that uselib(2) shouldn't work
> properly with NFS. I can remove the __FMODE_EXEC flag for now.

I kind of wonder if we need to more completely fix __FMODE_EXEC?

> [1] https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=f8d9a897d4384b77f13781ea813156568f68b83e

Hmpf, this implies that "fmode" should contain MAY_EXEC? It really looks
like __FMODE_EXEC is a hack for places where only "flags" were passed
around, and this only seems to be an issue for NFS at this point? And it
should be fixable for fsnotify too?

Hmm. (And nothing should use uselib anyway...)

-- 
Kees Cook

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH v6 7/7] ima: add policy support for the new file open MAY_OPENEXEC flag
  2020-07-16 14:40     ` Mickaël Salaün
  2020-07-16 14:59       ` Randy Dunlap
@ 2020-07-16 19:12       ` Kees Cook
  1 sibling, 0 replies; 25+ messages in thread
From: Kees Cook @ 2020-07-16 19:12 UTC (permalink / raw)
  To: 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, Lakshmi Ramasubramanian,
	Matthew Garrett, Matthew Wilcox, Michael Kerrisk,
	Mickaël Salaün, 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 Thu, Jul 16, 2020 at 04:40:15PM +0200, Mickaël Salaün wrote:
> 
> On 15/07/2020 22:40, Kees Cook wrote:
> > On Tue, Jul 14, 2020 at 08:16:38PM +0200, Mickaël Salaün wrote:
> >> From: Mimi Zohar <zohar@linux.ibm.com>
> >>
> >> The kernel has no way of differentiating between a file containing data
> >> or code being opened by an interpreter.  The proposed O_MAYEXEC
> >> openat2(2) flag bridges this gap by defining and enabling the
> >> MAY_OPENEXEC flag.
> >>
> >> This patch adds IMA policy support for the new MAY_OPENEXEC flag.
> >>
> >> Example:
> >> measure func=FILE_CHECK mask=^MAY_OPENEXEC
> >> appraise func=FILE_CHECK appraise_type=imasig mask=^MAY_OPENEXEC
> >>
> >> Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
> >> Reviewed-by: Lakshmi Ramasubramanian <nramas@linux.microsoft.com>
> >> Acked-by: Mickaël Salaün <mic@digikod.net>
> > 
> > (Process nit: if you're sending this on behalf of another author, then
> > this should be Signed-off-by rather than Acked-by.)
> 
> I'm not a co-author of this patch.

Correct, but you are part of the delivery path to its entry to the
tree. If you were co-author, you would include "Co-developed-by" with
a Signed-off-by. (So my nit stands)

For excruciating details:

https://www.kernel.org/doc/html/latest/process/submitting-patches.html#when-to-use-acked-by-cc-and-co-developed-by

"The Signed-off-by: tag indicates that the signer was ... in the patch’s
delivery path."

"Co-developed-by: ... is a used to give attribution to co-authors ..."

-- 
Kees Cook

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH v6 7/7] ima: add policy support for the new file open MAY_OPENEXEC flag
  2020-07-16 14:59       ` Randy Dunlap
  2020-07-16 15:22         ` Mickaël Salaün
@ 2020-07-16 19:13         ` Kees Cook
  1 sibling, 0 replies; 25+ messages in thread
From: Kees Cook @ 2020-07-16 19:13 UTC (permalink / raw)
  To: Randy Dunlap
  Cc: Mickaël Salaün, 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, Lakshmi Ramasubramanian, Matthew Garrett,
	Matthew Wilcox, Michael Kerrisk, Mickaël Salaün,
	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 Thu, Jul 16, 2020 at 07:59:20AM -0700, Randy Dunlap wrote:
> On 7/16/20 7:40 AM, Mickaël Salaün wrote:
> > 
> > On 15/07/2020 22:40, Kees Cook wrote:
> >> On Tue, Jul 14, 2020 at 08:16:38PM +0200, Mickaël Salaün wrote:
> >>> From: Mimi Zohar <zohar@linux.ibm.com>
> >>>
> >>> The kernel has no way of differentiating between a file containing data
> >>> or code being opened by an interpreter.  The proposed O_MAYEXEC
> >>> openat2(2) flag bridges this gap by defining and enabling the
> >>> MAY_OPENEXEC flag.
> >>>
> >>> This patch adds IMA policy support for the new MAY_OPENEXEC flag.
> >>>
> >>> Example:
> >>> measure func=FILE_CHECK mask=^MAY_OPENEXEC
> >>> appraise func=FILE_CHECK appraise_type=imasig mask=^MAY_OPENEXEC
> >>>
> >>> Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
> >>> Reviewed-by: Lakshmi Ramasubramanian <nramas@linux.microsoft.com>
> >>> Acked-by: Mickaël Salaün <mic@digikod.net>
> >>
> >> (Process nit: if you're sending this on behalf of another author, then
> >> this should be Signed-off-by rather than Acked-by.)
> > 
> > I'm not a co-author of this patch.
> > 
> 
> from Documentation/process/submitting-patches.rst:
> 
> The Signed-off-by: tag indicates that the signer was involved in the
> development of the patch, or that he/she was in the patch's delivery path.
>                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Randy beat me to it. :)

-- 
Kees Cook

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH v6 5/7] fs,doc: Enable to enforce noexec mounts or file exec through O_MAYEXEC
  2020-07-16 14:39     ` Mickaël Salaün
@ 2020-07-22 16:16       ` Thibaut Sautereau
  2020-07-22 19:04         ` Mickaël Salaün
  0 siblings, 1 reply; 25+ messages in thread
From: Thibaut Sautereau @ 2020-07-22 16:16 UTC (permalink / raw)
  To: Kees Cook, 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, Lakshmi Ramasubramanian,
	Matthew Garrett, Matthew Wilcox, Michael Kerrisk,
	Mickaël Salaün, 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 Thu, Jul 16, 2020 at 04:39:14PM +0200, Mickaël Salaün wrote:
> 
> On 15/07/2020 22:37, Kees Cook wrote:
> > On Tue, Jul 14, 2020 at 08:16:36PM +0200, Mickaël Salaün wrote:
> >> @@ -2849,7 +2855,7 @@ static int may_open(const struct path *path, int acc_mode, int flag)
> >>  	case S_IFLNK:
> >>  		return -ELOOP;
> >>  	case S_IFDIR:
> >> -		if (acc_mode & (MAY_WRITE | MAY_EXEC))
> >> +		if (acc_mode & (MAY_WRITE | MAY_EXEC | MAY_OPENEXEC))
> >>  			return -EISDIR;
> >>  		break;
> > 
> > (I need to figure out where "open for reading" rejects S_IFDIR, since
> > it's clearly not here...)

Doesn't it come from generic_read_dir() in fs/libfs.c?

> > 
> >>  	case S_IFBLK:
> >> @@ -2859,13 +2865,26 @@ static int may_open(const struct path *path, int acc_mode, int flag)
> >>  		fallthrough;
> >>  	case S_IFIFO:
> >>  	case S_IFSOCK:
> >> -		if (acc_mode & MAY_EXEC)
> >> +		if (acc_mode & (MAY_EXEC | MAY_OPENEXEC))
> >>  			return -EACCES;
> >>  		flag &= ~O_TRUNC;
> >>  		break;
> > 
> > This will immediately break a system that runs code with MAY_OPENEXEC
> > set but reads from a block, char, fifo, or socket, even in the case of
> > a sysadmin leaving the "file" sysctl disabled.
> 
> As documented, O_MAYEXEC is for regular files. The only legitimate use
> case seems to be with pipes, which should probably be allowed when
> enforcement is disabled.

By the way Kees, while we fix that for the next series, do you think it
would be relevant, at least for the sake of clarity, to add a
WARN_ON_ONCE(acc_mode & MAY_OPENEXEC) for the S_IFSOCK case, since a
socket cannot be open anyway?

-- 
Thibaut Sautereau
CLIP OS developer

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH v6 5/7] fs,doc: Enable to enforce noexec mounts or file exec through O_MAYEXEC
  2020-07-22 16:16       ` Thibaut Sautereau
@ 2020-07-22 19:04         ` Mickaël Salaün
  2020-07-22 19:40           ` Kees Cook
  0 siblings, 1 reply; 25+ messages in thread
From: Mickaël Salaün @ 2020-07-22 19:04 UTC (permalink / raw)
  To: Thibaut Sautereau, Kees Cook
  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, Lakshmi Ramasubramanian,
	Matthew Garrett, Matthew Wilcox, Michael Kerrisk,
	Mickaël Salaün, 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 22/07/2020 18:16, Thibaut Sautereau wrote:
> On Thu, Jul 16, 2020 at 04:39:14PM +0200, Mickaël Salaün wrote:
>>
>> On 15/07/2020 22:37, Kees Cook wrote:
>>> On Tue, Jul 14, 2020 at 08:16:36PM +0200, Mickaël Salaün wrote:
>>>> @@ -2849,7 +2855,7 @@ static int may_open(const struct path *path, int acc_mode, int flag)
>>>>  	case S_IFLNK:
>>>>  		return -ELOOP;
>>>>  	case S_IFDIR:
>>>> -		if (acc_mode & (MAY_WRITE | MAY_EXEC))
>>>> +		if (acc_mode & (MAY_WRITE | MAY_EXEC | MAY_OPENEXEC))
>>>>  			return -EISDIR;
>>>>  		break;
>>>
>>> (I need to figure out where "open for reading" rejects S_IFDIR, since
>>> it's clearly not here...)
> 
> Doesn't it come from generic_read_dir() in fs/libfs.c?
> 
>>>
>>>>  	case S_IFBLK:
>>>> @@ -2859,13 +2865,26 @@ static int may_open(const struct path *path, int acc_mode, int flag)
>>>>  		fallthrough;
>>>>  	case S_IFIFO:
>>>>  	case S_IFSOCK:
>>>> -		if (acc_mode & MAY_EXEC)
>>>> +		if (acc_mode & (MAY_EXEC | MAY_OPENEXEC))
>>>>  			return -EACCES;
>>>>  		flag &= ~O_TRUNC;
>>>>  		break;
>>>
>>> This will immediately break a system that runs code with MAY_OPENEXEC
>>> set but reads from a block, char, fifo, or socket, even in the case of
>>> a sysadmin leaving the "file" sysctl disabled.
>>
>> As documented, O_MAYEXEC is for regular files. The only legitimate use
>> case seems to be with pipes, which should probably be allowed when
>> enforcement is disabled.
> 
> By the way Kees, while we fix that for the next series, do you think it
> would be relevant, at least for the sake of clarity, to add a
> WARN_ON_ONCE(acc_mode & MAY_OPENEXEC) for the S_IFSOCK case, since a
> socket cannot be open anyway?
> 

We just did some more tests (for the next patch series) and it turns out
that may_open() can return EACCES before another part returns ENXIO.

As a reminder, the next series will deny access to block devices,
character devices, fifo and socket when opened with O_MAYEXEC *and* if
any policy is enforced (via the sysctl).

The question is then: do we prefer to return EACCES when a policy is
enforced (on a socket), or do we stick to the ENXIO? The EACCES approach
will be more consistent with devices and fifo handling, and seems safer
(belt and suspenders) thought.

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH v6 5/7] fs,doc: Enable to enforce noexec mounts or file exec through O_MAYEXEC
  2020-07-22 19:04         ` Mickaël Salaün
@ 2020-07-22 19:40           ` Kees Cook
  0 siblings, 0 replies; 25+ messages in thread
From: Kees Cook @ 2020-07-22 19:40 UTC (permalink / raw)
  To: Mickaël Salaün
  Cc: Thibaut Sautereau, 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, Lakshmi Ramasubramanian, Matthew Garrett,
	Matthew Wilcox, Michael Kerrisk, Mickaël Salaün,
	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, Jul 22, 2020 at 09:04:28PM +0200, Mickaël Salaün wrote:
> 
> On 22/07/2020 18:16, Thibaut Sautereau wrote:
> > On Thu, Jul 16, 2020 at 04:39:14PM +0200, Mickaël Salaün wrote:
> >>
> >> On 15/07/2020 22:37, Kees Cook wrote:
> >>> On Tue, Jul 14, 2020 at 08:16:36PM +0200, Mickaël Salaün wrote:
> >>>> @@ -2849,7 +2855,7 @@ static int may_open(const struct path *path, int acc_mode, int flag)
> >>>>  	case S_IFLNK:
> >>>>  		return -ELOOP;
> >>>>  	case S_IFDIR:
> >>>> -		if (acc_mode & (MAY_WRITE | MAY_EXEC))
> >>>> +		if (acc_mode & (MAY_WRITE | MAY_EXEC | MAY_OPENEXEC))
> >>>>  			return -EISDIR;
> >>>>  		break;
> >>>
> >>> (I need to figure out where "open for reading" rejects S_IFDIR, since
> >>> it's clearly not here...)
> > 
> > Doesn't it come from generic_read_dir() in fs/libfs.c?
> > 
> >>>
> >>>>  	case S_IFBLK:
> >>>> @@ -2859,13 +2865,26 @@ static int may_open(const struct path *path, int acc_mode, int flag)
> >>>>  		fallthrough;
> >>>>  	case S_IFIFO:
> >>>>  	case S_IFSOCK:
> >>>> -		if (acc_mode & MAY_EXEC)
> >>>> +		if (acc_mode & (MAY_EXEC | MAY_OPENEXEC))
> >>>>  			return -EACCES;
> >>>>  		flag &= ~O_TRUNC;
> >>>>  		break;
> >>>
> >>> This will immediately break a system that runs code with MAY_OPENEXEC
> >>> set but reads from a block, char, fifo, or socket, even in the case of
> >>> a sysadmin leaving the "file" sysctl disabled.
> >>
> >> As documented, O_MAYEXEC is for regular files. The only legitimate use
> >> case seems to be with pipes, which should probably be allowed when
> >> enforcement is disabled.
> > 
> > By the way Kees, while we fix that for the next series, do you think it
> > would be relevant, at least for the sake of clarity, to add a
> > WARN_ON_ONCE(acc_mode & MAY_OPENEXEC) for the S_IFSOCK case, since a
> > socket cannot be open anyway?

If it's a state that userspace should never be able to reach, then yes,
I think a WARN_ON_ONCE() would be nice.

> We just did some more tests (for the next patch series) and it turns out
> that may_open() can return EACCES before another part returns ENXIO.
> 
> As a reminder, the next series will deny access to block devices,
> character devices, fifo and socket when opened with O_MAYEXEC *and* if
> any policy is enforced (via the sysctl).
> 
> The question is then: do we prefer to return EACCES when a policy is
> enforced (on a socket), or do we stick to the ENXIO? The EACCES approach
> will be more consistent with devices and fifo handling, and seems safer
> (belt and suspenders) thought.

I think EACCES is correct for these cases, since it's a new flag, etc.

-- 
Kees Cook

^ permalink raw reply	[flat|nested] 25+ messages in thread

end of thread, back to index

Thread overview: 25+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-07-14 18:16 [PATCH v6 0/7] Add support for O_MAYEXEC Mickaël Salaün
2020-07-14 18:16 ` [PATCH v6 1/7] exec: Change uselib(2) IS_SREG() failure to EACCES Mickaël Salaün
2020-07-14 18:16 ` [PATCH v6 2/7] exec: Move S_ISREG() check earlier Mickaël Salaün
2020-07-14 18:16 ` [PATCH v6 3/7] exec: Move path_noexec() " Mickaël Salaün
2020-07-14 18:16 ` [PATCH v6 4/7] fs: Introduce O_MAYEXEC flag for openat2(2) Mickaël Salaün
2020-07-15 20:06   ` Kees Cook
2020-07-16 14:18     ` Mickaël Salaün
2020-07-16 15:31       ` Kees Cook
2020-07-14 18:16 ` [PATCH v6 5/7] fs,doc: Enable to enforce noexec mounts or file exec through O_MAYEXEC Mickaël Salaün
2020-07-14 18:40   ` Randy Dunlap
2020-07-16 14:40     ` Mickaël Salaün
2020-07-15 20:37   ` Kees Cook
2020-07-16 14:39     ` Mickaël Salaün
2020-07-22 16:16       ` Thibaut Sautereau
2020-07-22 19:04         ` Mickaël Salaün
2020-07-22 19:40           ` Kees Cook
2020-07-14 18:16 ` [PATCH v6 6/7] selftest/openat2: Add tests for O_MAYEXEC enforcing Mickaël Salaün
2020-07-15 20:38   ` Kees Cook
2020-07-14 18:16 ` [PATCH v6 7/7] ima: add policy support for the new file open MAY_OPENEXEC flag Mickaël Salaün
2020-07-15 20:40   ` Kees Cook
2020-07-16 14:40     ` Mickaël Salaün
2020-07-16 14:59       ` Randy Dunlap
2020-07-16 15:22         ` Mickaël Salaün
2020-07-16 19:13         ` Kees Cook
2020-07-16 19:12       ` Kees Cook

Kernel-hardening archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/kernel-hardening/0 kernel-hardening/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 kernel-hardening kernel-hardening/ https://lore.kernel.org/kernel-hardening \
		kernel-hardening@lists.openwall.com
	public-inbox-index kernel-hardening

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/com.openwall.lists.kernel-hardening


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git