All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC PATCH v9 0/3] Add introspect_access(2) (was O_MAYEXEC)
@ 2020-09-10 16:46 Mickaël Salaün
  2020-09-10 16:46 ` [RFC PATCH v9 1/3] fs: Add introspect_access(2) syscall implementation and related sysctl Mickaël Salaün
                   ` (3 more replies)
  0 siblings, 4 replies; 17+ messages in thread
From: Mickaël Salaün @ 2020-09-10 16:46 UTC (permalink / raw)
  To: linux-kernel
  Cc: Mickaël Salaün, Aleksa Sarai, Alexei Starovoitov,
	Al Viro, Andrew Morton, Andy Lutomirski, Arnd Bergmann,
	Casey Schaufler, Christian Brauner, Christian Heimes,
	Daniel Borkmann, Deven Bowers, Dmitry Vyukov, Eric Biggers,
	Eric Chiang, Florian Weimer, James Morris, Jan Kara, Jann Horn,
	Jonathan Corbet, Kees Cook, Lakshmi Ramasubramanian,
	Matthew Garrett, Matthew Wilcox, Michael Kerrisk, Miklos Szeredi,
	Mimi Zohar, Philippe Trébuchet, Scott Shell,
	Sean Christopherson, Shuah Khan, Steve Dower, Steve Grubb,
	Tetsuo Handa, Thibaut Sautereau, Vincent Strubel,
	kernel-hardening, linux-api, linux-integrity,
	linux-security-module, linux-fsdevel

Hi,

This ninth patch series rework the previous AT_INTERPRETED and O_MAYEXEC
series with a new syscall: introspect_access(2) .  Access check are now
only possible on a file descriptor, which enable to avoid possible race
conditions in user space.

For now, the only LSM hook triggered by introspect_access(2) is
inode_permission() which takes a struct inode as argument.  However,
struct path is still available in this syscall, which enables to add a
new hook to fit the needs of IMA and other path-based LSMs.

Goal of introspect_access(2)
============================

The goal of this patch series is to enable to control script execution
with interpreters help.  A new introspect_access() system call is added
to enable user space 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_INTROSPECTION_EXEC flag is required to close a major IMA
measurement/appraisal interpreter integrity gap by bringing the ability
to check the use of scripts [1].  Other uses are expected, such as for
magic-links [2], SGX integration [3], bpffs [4] or IPE [5].

Possible extended usage
=======================

For now, only the X_OK mode is compatible with introspect_access(2).
This enables to restrict the addition of new control flows in a process.
Using R_OK or W_OK with introspect_access(2) returns -EINVAL.

Possible future use-cases for R_OK with introspect_access(2) may be to
check configuration files that may impact the behavior of applications
(i.e.  influence critical part of the current control flow).  Those
should then be trusted as well.  The W_OK with introspect_access(2)
could be used to check that a file descriptor is allowed to receive
sensitive data such as debug logs.

Prerequisite of its use
=======================

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

Examples
========

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

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

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

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

Previous version:
https://lore.kernel.org/lkml/20200908075956.1069018-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,

Mickaël Salaün (3):
  fs: Add introspect_access(2) syscall implementation and related sysctl
  arch: Wire up introspect_access(2)
  selftest/interpreter: Add tests for introspect_access(2) policies

 Documentation/admin-guide/sysctl/fs.rst       |  50 +++
 arch/alpha/kernel/syscalls/syscall.tbl        |   1 +
 arch/arm/tools/syscall.tbl                    |   1 +
 arch/arm64/include/asm/unistd.h               |   2 +-
 arch/arm64/include/asm/unistd32.h             |   2 +
 arch/ia64/kernel/syscalls/syscall.tbl         |   1 +
 arch/m68k/kernel/syscalls/syscall.tbl         |   1 +
 arch/microblaze/kernel/syscalls/syscall.tbl   |   1 +
 arch/mips/kernel/syscalls/syscall_n32.tbl     |   1 +
 arch/mips/kernel/syscalls/syscall_n64.tbl     |   1 +
 arch/mips/kernel/syscalls/syscall_o32.tbl     |   1 +
 arch/parisc/kernel/syscalls/syscall.tbl       |   1 +
 arch/powerpc/kernel/syscalls/syscall.tbl      |   1 +
 arch/s390/kernel/syscalls/syscall.tbl         |   1 +
 arch/sh/kernel/syscalls/syscall.tbl           |   1 +
 arch/sparc/kernel/syscalls/syscall.tbl        |   1 +
 arch/x86/entry/syscalls/syscall_32.tbl        |   1 +
 arch/x86/entry/syscalls/syscall_64.tbl        |   1 +
 arch/xtensa/kernel/syscalls/syscall.tbl       |   1 +
 fs/open.c                                     |  79 ++++
 include/linux/fs.h                            |   3 +
 include/linux/syscalls.h                      |   1 +
 include/uapi/asm-generic/unistd.h             |   4 +-
 kernel/sysctl.c                               |  12 +-
 .../testing/selftests/interpreter/.gitignore  |   2 +
 tools/testing/selftests/interpreter/Makefile  |  18 +
 tools/testing/selftests/interpreter/config    |   1 +
 .../interpreter/introspection_policy_test.c   | 361 ++++++++++++++++++
 28 files changed, 547 insertions(+), 4 deletions(-)
 create mode 100644 tools/testing/selftests/interpreter/.gitignore
 create mode 100644 tools/testing/selftests/interpreter/Makefile
 create mode 100644 tools/testing/selftests/interpreter/config
 create mode 100644 tools/testing/selftests/interpreter/introspection_policy_test.c

-- 
2.28.0


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

* [RFC PATCH v9 1/3] fs: Add introspect_access(2) syscall implementation and related sysctl
  2020-09-10 16:46 [RFC PATCH v9 0/3] Add introspect_access(2) (was O_MAYEXEC) Mickaël Salaün
@ 2020-09-10 16:46 ` Mickaël Salaün
  2020-09-10 16:46 ` [RFC PATCH v9 2/3] arch: Wire up introspect_access(2) Mickaël Salaün
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 17+ messages in thread
From: Mickaël Salaün @ 2020-09-10 16:46 UTC (permalink / raw)
  To: linux-kernel
  Cc: Mickaël Salaün, Aleksa Sarai, Alexei Starovoitov,
	Al Viro, Andrew Morton, Andy Lutomirski, Arnd Bergmann,
	Casey Schaufler, Christian Brauner, Christian Heimes,
	Daniel Borkmann, Deven Bowers, Dmitry Vyukov, Eric Biggers,
	Eric Chiang, Florian Weimer, James Morris, Jan Kara, Jann Horn,
	Jonathan Corbet, Kees Cook, Lakshmi Ramasubramanian,
	Matthew Garrett, Matthew Wilcox, Michael Kerrisk, Miklos Szeredi,
	Mimi Zohar, Philippe Trébuchet, Scott Shell,
	Sean Christopherson, Shuah Khan, Steve Dower, Steve Grubb,
	Tetsuo Handa, Thibaut Sautereau, Vincent Strubel,
	kernel-hardening, linux-api, linux-integrity,
	linux-security-module, linux-fsdevel, Thibaut Sautereau,
	Mickaël Salaün

From: Mickaël Salaün <mic@linux.microsoft.com>

The introspect_access() syscall enables user space tasks to check that
files are allowed to be executed or interpreted by user space.  This may
allow script interpreters to check execution permission before reading
commands from a file, or dynamic linkers to allow shared object loading.
This may be seen as a way for a trusted task (e.g. interpreter) to check
the trustworthiness of files (e.g. scripts) before extending its control
flow graph with new ones originating from these files.

The security policy is consistently managed by the kernel through a
sysctl or implemented by an LSM thanks to the inode_permission hook and
a new kernel flag: MAY_INTROSPECTION_EXEC .

The new sysctl fs.introspection_policy enables 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.

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 introspect_access(2) with the
X_OK mode.  To be fully effective, these interpreters also need to
handle the other ways to execute code: command line parameters (e.g.,
option -e for Perl), module loading (e.g., option -m for Python), stdin,
file sourcing, environment variables, configuration files, etc.
According to the threat model, it may be acceptable to allow some script
interpreters (e.g. Bash) to interpret commands from stdin, may it be a
TTY or a pipe, because it may not be enough to (directly) perform
syscalls.

Even without enforced security policy, user space interpreters can use
this syscall to try as much as possible 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.  system
administrator who configured fs.introspection_policy deliberately) to
manage it.

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

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

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).

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

Co-developed-by: Thibaut Sautereau <thibaut.sautereau@ssi.gouv.fr>
Signed-off-by: Thibaut Sautereau <thibaut.sautereau@ssi.gouv.fr>
Signed-off-by: Mickaël Salaün <mic@linux.microsoft.com>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Jonathan Corbet <corbet@lwn.net>
Cc: Kees Cook <keescook@chromium.org>
Cc: Vincent Strubel <vincent.strubel@ssi.gouv.fr>
---

Changes since v8:
* Add a dedicated syscall introspect_access() (requested by Al Viro).
* Rename MAY_INTERPRETED_EXEC to MAY_INTROSPECTION_EXEC .
* Rename the sysctl fs.interpreted_access to fs.introspection_policy .
* Update documentation.

Changes since v7:
* Replaces openat2/O_MAYEXEC with faccessat2/X_OK/AT_INTERPRETED .
  Switching to an FD-based syscall was suggested by Al Viro and Jann
  Horn.
* Handle special file descriptors.
* Add a compatibility mode for execute/read check.
* Move the sysctl policy from fs/namei.c to fs/open.c for the new
  faccessat2/AT_INTERPRETED.
* Rename the sysctl from fs.open_mayexec_enforce to
  fs.interpreted_access .
* Update documentation accordingly.

Changes since v6:
* Allow opening pipes, block devices and character devices with
  O_MAYEXEC when there is no enforced policy, but forbid any non-regular
  file opened with O_MAYEXEC otherwise (i.e. for any enforced policy).
* Add a paragraph about the non-regular files policy.
* Move path_noexec() calls out of the fast-path (suggested by Kees
  Cook).
* Do not set __FMODE_EXEC for now because of inconsistent behavior:
  https://lore.kernel.org/lkml/202007160822.CCDB5478@keescook/
* Returns EISDIR when opening a directory with O_MAYEXEC.
* Removed Deven Bowers and Kees Cook Reviewed-by tags because of the
  current update.

Changes since v5:
* 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:
* 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.
* Cosmetic changes.

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/
* 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 | 50 ++++++++++++++++
 fs/open.c                               | 79 +++++++++++++++++++++++++
 include/linux/fs.h                      |  3 +
 include/linux/syscalls.h                |  1 +
 kernel/sysctl.c                         | 12 +++-
 5 files changed, 143 insertions(+), 2 deletions(-)

diff --git a/Documentation/admin-guide/sysctl/fs.rst b/Documentation/admin-guide/sysctl/fs.rst
index f48277a0a850..2f244e968a1d 100644
--- a/Documentation/admin-guide/sysctl/fs.rst
+++ b/Documentation/admin-guide/sysctl/fs.rst
@@ -36,6 +36,7 @@ Currently, these files are in /proc/sys/fs:
 - inode-max
 - inode-nr
 - inode-state
+- introspection_policy
 - nr_open
 - overflowuid
 - overflowgid
@@ -165,6 +166,55 @@ system needs to prune the inode list instead of allocating
 more.
 
 
+introspection_policy
+--------------------
+
+An interpreter can call :manpage:`introspect_access(2)` with an ``X_OK`` mode
+to check that opened regular files are expected to be executable.  If the file
+is not identified as executable, then the syscall returns -EACCES.  This may
+allow a script interpreter to check executable permission before reading
+commands from a file, or a dynamic linker to only load executable shared
+objects.  One interesting use case is to enforce a "write xor execute" policy
+through interpreters.
+
+The ability to restrict code execution must be thought as a system-wide policy,
+which first starts by restricting mount points with the ``noexec`` option.
+This option is also automatically applied to special filesystems such as /proc .
+This prevents files on such mount points to be directly executed by the kernel
+or mapped as executable memory (e.g. libraries).  With script interpreters
+using :manpage:`introspect_access(2)`, 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.introspection_policy`` sysctl (writable only with ``CAP_SYS_ADMIN``)
+as a bitmask:
+
+1 - Mount restriction: checks that the mount options for the underlying VFS
+    mount do not prevent execution.
+
+2 - File permission restriction: checks that the file is marked as
+    executable for the current process (e.g., POSIX permissions, ACLs).
+
+Note that as long as a policy is enforced, checking any non-regular file with
+:manpage:`introspect_access(2)` returns -EACCES (e.g. TTYs, pipe), even when
+such a file is marked as executable or is on an executable mount point.
+
+Code samples can be found in
+tools/testing/selftests/interpreter/introspection_policy_test.c and interpreter
+patches (for the original O_MAYEXEC) are available at
+https://github.com/clipos-archive/clipos4_portage-overlay/search?q=O_MAYEXEC .
+See also an overview article: https://lwn.net/Articles/820000/ .
+
+
 overflowgid & overflowuid
 -------------------------
 
diff --git a/fs/open.c b/fs/open.c
index 9af548fb841b..390cef411236 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -32,6 +32,7 @@
 #include <linux/ima.h>
 #include <linux/dnotify.h>
 #include <linux/compat.h>
+#include <linux/sysctl.h>
 
 #include "internal.h"
 
@@ -482,6 +483,84 @@ SYSCALL_DEFINE2(access, const char __user *, filename, int, mode)
 	return do_faccessat(AT_FDCWD, filename, mode, 0);
 }
 
+#define INTROSPECTION_EXEC_MOUNT		BIT(0)
+#define INTROSPECTION_EXEC_FILE			BIT(1)
+
+int sysctl_introspection_policy __read_mostly;
+
+SYSCALL_DEFINE3(introspect_access, const int, fd, const int, mode, const int, flags)
+{
+	int mask, err = -EACCES;
+	struct fd f;
+	struct inode *inode;
+
+	if (flags)
+		return -EINVAL;
+
+	/* Only allows X_OK for now. */
+	if (mode != S_IXOTH)
+		return -EINVAL;
+	mask = MAY_EXEC;
+
+	f = fdget(fd);
+	if (!f.file)
+		return -EBADF;
+	inode = d_backing_inode(f.file->f_path.dentry);
+
+	/*
+	 * For compatibility reasons, without a defined security policy (via
+	 * sysctl or LSM), we must map the execute permission to the read
+	 * permission.  Indeed, from user space point of view, being able to
+	 * execute data (e.g. scripts) implies to be able to read this data.
+	 *
+	 * The MAY_INTROSPECTION_EXEC bit is set to enable LSMs to add custom
+	 * checks, while being compatible with current policies.
+	 */
+	if ((mask & MAY_EXEC)) {
+		mask |= MAY_INTROSPECTION_EXEC;
+		/*
+		 * If there is a system-wide execute policy enforced, then
+		 * forbids access to non-regular files and special superblocks.
+		 */
+		if ((sysctl_introspection_policy & (INTROSPECTION_EXEC_MOUNT |
+						INTROSPECTION_EXEC_FILE))) {
+			if (!S_ISREG(inode->i_mode))
+				goto out_fd;
+			/*
+			 * Denies access to pseudo filesystems that will never
+			 * be mountable (e.g. sockfs, pipefs) but can still be
+			 * reachable through /proc/self/fd, or memfd-like file
+			 * descriptors, or nsfs-like files.
+			 *
+			 * According to the tests, SB_NOEXEC seems to be only
+			 * used by proc and nsfs filesystems.  Is it correct?
+			 */
+			if ((f.file->f_path.dentry->d_sb->s_flags &
+						(SB_NOUSER | SB_KERNMOUNT | SB_NOEXEC)))
+				goto out_fd;
+		}
+
+		if ((sysctl_introspection_policy & INTROSPECTION_EXEC_MOUNT) &&
+				path_noexec(&f.file->f_path))
+			goto out_fd;
+		/*
+		 * For compatibility reasons, if the system-wide policy doesn't
+		 * enforce file permission checks, then replaces the execute
+		 * permission request with a read permission request.
+		 */
+		if (!(sysctl_introspection_policy & INTROSPECTION_EXEC_FILE))
+			mask &= ~MAY_EXEC;
+		/* To be executed *by* user space, files must be readable. */
+		mask |= MAY_READ;
+	}
+
+	err = inode_permission(inode, mask | MAY_ACCESS);
+
+out_fd:
+	fdput(f);
+	return err;
+}
+
 SYSCALL_DEFINE1(chdir, const char __user *, filename)
 {
 	struct path path;
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 7519ae003a08..3f9c4fe199ce 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_introspection_policy;
 
 typedef __kernel_rwf_t rwf_t;
 
@@ -101,6 +102,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
+/* introspection accesses, cf. introspect_access(2) */
+#define MAY_INTROSPECTION_EXEC	0x00000100
 
 /*
  * flags in file.f_mode.  Note that FMODE_READ and FMODE_WRITE must correspond
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index 75ac7f8ae93c..e8cb6846dea2 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -429,6 +429,7 @@ asmlinkage long sys_fallocate(int fd, int mode, loff_t offset, loff_t len);
 asmlinkage long sys_faccessat(int dfd, const char __user *filename, int mode);
 asmlinkage long sys_faccessat2(int dfd, const char __user *filename, int mode,
 			       int flags);
+asmlinkage long sys_introspect_access(int fd, int mode, int flags);
 asmlinkage long sys_chdir(const char __user *filename);
 asmlinkage long sys_fchdir(unsigned int fd);
 asmlinkage long sys_chroot(const char __user *filename);
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 09e70ee2332e..d9c2aca9a0c0 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -113,6 +113,7 @@ static int sixty = 60;
 
 static int __maybe_unused neg_one = -1;
 static int __maybe_unused two = 2;
+static int __maybe_unused three = 3;
 static int __maybe_unused four = 4;
 static unsigned long zero_ul;
 static unsigned long one_ul = 1;
@@ -887,7 +888,6 @@ static int proc_taint(struct ctl_table *table, int write,
 	return err;
 }
 
-#ifdef CONFIG_PRINTK
 static int proc_dointvec_minmax_sysadmin(struct ctl_table *table, int write,
 				void *buffer, size_t *lenp, loff_t *ppos)
 {
@@ -896,7 +896,6 @@ static int proc_dointvec_minmax_sysadmin(struct ctl_table *table, int write,
 
 	return proc_dointvec_minmax(table, write, buffer, lenp, ppos);
 }
-#endif
 
 /**
  * struct do_proc_dointvec_minmax_conv_param - proc_dointvec_minmax() range checking structure
@@ -3293,6 +3292,15 @@ static struct ctl_table fs_table[] = {
 		.extra1		= SYSCTL_ZERO,
 		.extra2		= &two,
 	},
+	{
+		.procname       = "introspection_policy",
+		.data           = &sysctl_introspection_policy,
+		.maxlen         = sizeof(int),
+		.mode           = 0600,
+		.proc_handler	= proc_dointvec_minmax_sysadmin,
+		.extra1		= SYSCTL_ZERO,
+		.extra2		= &three,
+	},
 #if defined(CONFIG_BINFMT_MISC) || defined(CONFIG_BINFMT_MISC_MODULE)
 	{
 		.procname	= "binfmt_misc",
-- 
2.28.0


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

* [RFC PATCH v9 2/3] arch: Wire up introspect_access(2)
  2020-09-10 16:46 [RFC PATCH v9 0/3] Add introspect_access(2) (was O_MAYEXEC) Mickaël Salaün
  2020-09-10 16:46 ` [RFC PATCH v9 1/3] fs: Add introspect_access(2) syscall implementation and related sysctl Mickaël Salaün
@ 2020-09-10 16:46 ` Mickaël Salaün
  2020-09-15 13:32   ` Arnd Bergmann
  2020-09-10 16:46 ` [RFC PATCH v9 3/3] selftest/interpreter: Add tests for introspect_access(2) policies Mickaël Salaün
  2020-09-10 17:04 ` [RFC PATCH v9 0/3] Add introspect_access(2) (was O_MAYEXEC) Matthew Wilcox
  3 siblings, 1 reply; 17+ messages in thread
From: Mickaël Salaün @ 2020-09-10 16:46 UTC (permalink / raw)
  To: linux-kernel
  Cc: Mickaël Salaün, Aleksa Sarai, Alexei Starovoitov,
	Al Viro, Andrew Morton, Andy Lutomirski, Arnd Bergmann,
	Casey Schaufler, Christian Brauner, Christian Heimes,
	Daniel Borkmann, Deven Bowers, Dmitry Vyukov, Eric Biggers,
	Eric Chiang, Florian Weimer, James Morris, Jan Kara, Jann Horn,
	Jonathan Corbet, Kees Cook, Lakshmi Ramasubramanian,
	Matthew Garrett, Matthew Wilcox, Michael Kerrisk, Miklos Szeredi,
	Mimi Zohar, Philippe Trébuchet, Scott Shell,
	Sean Christopherson, Shuah Khan, Steve Dower, Steve Grubb,
	Tetsuo Handa, Thibaut Sautereau, Vincent Strubel,
	kernel-hardening, linux-api, linux-integrity,
	linux-security-module, linux-fsdevel, Mickaël Salaün,
	Thibaut Sautereau

From: Mickaël Salaün <mic@linux.microsoft.com>

Wire up access_interpreted(2) for all architectures.

Signed-off-by: Mickaël Salaün <mic@linux.microsoft.com>
Reviewed-by: Thibaut Sautereau <thibaut.sautereau@ssi.gouv.fr>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Kees Cook <keescook@chromium.org>
Cc: Vincent Strubel <vincent.strubel@ssi.gouv.fr>
---

Changes since v7:
* New patch for the new syscall.
* Increase syscall numbers by 2 to leave space for new ones (in
  linux-next): watch_mount(2) and process_madvise(2).
---
 arch/alpha/kernel/syscalls/syscall.tbl      | 1 +
 arch/arm/tools/syscall.tbl                  | 1 +
 arch/arm64/include/asm/unistd.h             | 2 +-
 arch/arm64/include/asm/unistd32.h           | 2 ++
 arch/ia64/kernel/syscalls/syscall.tbl       | 1 +
 arch/m68k/kernel/syscalls/syscall.tbl       | 1 +
 arch/microblaze/kernel/syscalls/syscall.tbl | 1 +
 arch/mips/kernel/syscalls/syscall_n32.tbl   | 1 +
 arch/mips/kernel/syscalls/syscall_n64.tbl   | 1 +
 arch/mips/kernel/syscalls/syscall_o32.tbl   | 1 +
 arch/parisc/kernel/syscalls/syscall.tbl     | 1 +
 arch/powerpc/kernel/syscalls/syscall.tbl    | 1 +
 arch/s390/kernel/syscalls/syscall.tbl       | 1 +
 arch/sh/kernel/syscalls/syscall.tbl         | 1 +
 arch/sparc/kernel/syscalls/syscall.tbl      | 1 +
 arch/x86/entry/syscalls/syscall_32.tbl      | 1 +
 arch/x86/entry/syscalls/syscall_64.tbl      | 1 +
 arch/xtensa/kernel/syscalls/syscall.tbl     | 1 +
 include/uapi/asm-generic/unistd.h           | 4 +++-
 19 files changed, 22 insertions(+), 2 deletions(-)

diff --git a/arch/alpha/kernel/syscalls/syscall.tbl b/arch/alpha/kernel/syscalls/syscall.tbl
index ec8bed9e7b75..6c0d26a4910a 100644
--- a/arch/alpha/kernel/syscalls/syscall.tbl
+++ b/arch/alpha/kernel/syscalls/syscall.tbl
@@ -479,3 +479,4 @@
 547	common	openat2				sys_openat2
 548	common	pidfd_getfd			sys_pidfd_getfd
 549	common	faccessat2			sys_faccessat2
+552	common	introspect_access		sys_introspect_access
diff --git a/arch/arm/tools/syscall.tbl b/arch/arm/tools/syscall.tbl
index 171077cbf419..b444148d49be 100644
--- a/arch/arm/tools/syscall.tbl
+++ b/arch/arm/tools/syscall.tbl
@@ -453,3 +453,4 @@
 437	common	openat2				sys_openat2
 438	common	pidfd_getfd			sys_pidfd_getfd
 439	common	faccessat2			sys_faccessat2
+442	common	introspect_access		sys_introspect_access
diff --git a/arch/arm64/include/asm/unistd.h b/arch/arm64/include/asm/unistd.h
index 3b859596840d..949788f5ba40 100644
--- a/arch/arm64/include/asm/unistd.h
+++ b/arch/arm64/include/asm/unistd.h
@@ -38,7 +38,7 @@
 #define __ARM_NR_compat_set_tls		(__ARM_NR_COMPAT_BASE + 5)
 #define __ARM_NR_COMPAT_END		(__ARM_NR_COMPAT_BASE + 0x800)
 
-#define __NR_compat_syscalls		440
+#define __NR_compat_syscalls		443
 #endif
 
 #define __ARCH_WANT_SYS_CLONE
diff --git a/arch/arm64/include/asm/unistd32.h b/arch/arm64/include/asm/unistd32.h
index 734860ac7cf9..a5b3cd7973ff 100644
--- a/arch/arm64/include/asm/unistd32.h
+++ b/arch/arm64/include/asm/unistd32.h
@@ -887,6 +887,8 @@ __SYSCALL(__NR_openat2, sys_openat2)
 __SYSCALL(__NR_pidfd_getfd, sys_pidfd_getfd)
 #define __NR_faccessat2 439
 __SYSCALL(__NR_faccessat2, sys_faccessat2)
+#define __NR_introspect_access 442
+__SYSCALL(__NR_introspect_access, sys_introspect_access)
 
 /*
  * Please add new compat syscalls above this comment and update
diff --git a/arch/ia64/kernel/syscalls/syscall.tbl b/arch/ia64/kernel/syscalls/syscall.tbl
index f52a41f4c340..6b0ff458392a 100644
--- a/arch/ia64/kernel/syscalls/syscall.tbl
+++ b/arch/ia64/kernel/syscalls/syscall.tbl
@@ -360,3 +360,4 @@
 437	common	openat2				sys_openat2
 438	common	pidfd_getfd			sys_pidfd_getfd
 439	common	faccessat2			sys_faccessat2
+442	common	introspect_access		sys_introspect_access
diff --git a/arch/m68k/kernel/syscalls/syscall.tbl b/arch/m68k/kernel/syscalls/syscall.tbl
index 81fc799d8392..37ae4690bc26 100644
--- a/arch/m68k/kernel/syscalls/syscall.tbl
+++ b/arch/m68k/kernel/syscalls/syscall.tbl
@@ -439,3 +439,4 @@
 437	common	openat2				sys_openat2
 438	common	pidfd_getfd			sys_pidfd_getfd
 439	common	faccessat2			sys_faccessat2
+442	common	introspect_access		sys_introspect_access
diff --git a/arch/microblaze/kernel/syscalls/syscall.tbl b/arch/microblaze/kernel/syscalls/syscall.tbl
index b4e263916f41..e797242a8849 100644
--- a/arch/microblaze/kernel/syscalls/syscall.tbl
+++ b/arch/microblaze/kernel/syscalls/syscall.tbl
@@ -445,3 +445,4 @@
 437	common	openat2				sys_openat2
 438	common	pidfd_getfd			sys_pidfd_getfd
 439	common	faccessat2			sys_faccessat2
+442	common	introspect_access		sys_introspect_access
diff --git a/arch/mips/kernel/syscalls/syscall_n32.tbl b/arch/mips/kernel/syscalls/syscall_n32.tbl
index f9df9edb67a4..7b8ad951f3e7 100644
--- a/arch/mips/kernel/syscalls/syscall_n32.tbl
+++ b/arch/mips/kernel/syscalls/syscall_n32.tbl
@@ -378,3 +378,4 @@
 437	n32	openat2				sys_openat2
 438	n32	pidfd_getfd			sys_pidfd_getfd
 439	n32	faccessat2			sys_faccessat2
+442	n32	introspect_access		sys_introspect_access
diff --git a/arch/mips/kernel/syscalls/syscall_n64.tbl b/arch/mips/kernel/syscalls/syscall_n64.tbl
index 557f9954a2b9..96ad1861e004 100644
--- a/arch/mips/kernel/syscalls/syscall_n64.tbl
+++ b/arch/mips/kernel/syscalls/syscall_n64.tbl
@@ -354,3 +354,4 @@
 437	n64	openat2				sys_openat2
 438	n64	pidfd_getfd			sys_pidfd_getfd
 439	n64	faccessat2			sys_faccessat2
+442	n64	introspect_access		sys_introspect_access
diff --git a/arch/mips/kernel/syscalls/syscall_o32.tbl b/arch/mips/kernel/syscalls/syscall_o32.tbl
index 195b43cf27c8..963a6ebe5ece 100644
--- a/arch/mips/kernel/syscalls/syscall_o32.tbl
+++ b/arch/mips/kernel/syscalls/syscall_o32.tbl
@@ -427,3 +427,4 @@
 437	o32	openat2				sys_openat2
 438	o32	pidfd_getfd			sys_pidfd_getfd
 439	o32	faccessat2			sys_faccessat2
+442	o32	introspect_access		sys_introspect_access
diff --git a/arch/parisc/kernel/syscalls/syscall.tbl b/arch/parisc/kernel/syscalls/syscall.tbl
index def64d221cd4..209e66c024c0 100644
--- a/arch/parisc/kernel/syscalls/syscall.tbl
+++ b/arch/parisc/kernel/syscalls/syscall.tbl
@@ -437,3 +437,4 @@
 437	common	openat2				sys_openat2
 438	common	pidfd_getfd			sys_pidfd_getfd
 439	common	faccessat2			sys_faccessat2
+442	common	introspect_access		sys_introspect_access
diff --git a/arch/powerpc/kernel/syscalls/syscall.tbl b/arch/powerpc/kernel/syscalls/syscall.tbl
index c2d737ff2e7b..474e00ee811c 100644
--- a/arch/powerpc/kernel/syscalls/syscall.tbl
+++ b/arch/powerpc/kernel/syscalls/syscall.tbl
@@ -529,3 +529,4 @@
 437	common	openat2				sys_openat2
 438	common	pidfd_getfd			sys_pidfd_getfd
 439	common	faccessat2			sys_faccessat2
+442	common	introspect_access		sys_introspect_access
diff --git a/arch/s390/kernel/syscalls/syscall.tbl b/arch/s390/kernel/syscalls/syscall.tbl
index 10456bc936fb..ca0233bee7c1 100644
--- a/arch/s390/kernel/syscalls/syscall.tbl
+++ b/arch/s390/kernel/syscalls/syscall.tbl
@@ -442,3 +442,4 @@
 437  common	openat2			sys_openat2			sys_openat2
 438  common	pidfd_getfd		sys_pidfd_getfd			sys_pidfd_getfd
 439  common	faccessat2		sys_faccessat2			sys_faccessat2
+442  common	introspect_access		sys_introspect_access		sys_introspect_access
diff --git a/arch/sh/kernel/syscalls/syscall.tbl b/arch/sh/kernel/syscalls/syscall.tbl
index ae0a00beea5f..fcd71c2ce909 100644
--- a/arch/sh/kernel/syscalls/syscall.tbl
+++ b/arch/sh/kernel/syscalls/syscall.tbl
@@ -442,3 +442,4 @@
 437	common	openat2				sys_openat2
 438	common	pidfd_getfd			sys_pidfd_getfd
 439	common	faccessat2			sys_faccessat2
+442	common	introspect_access		sys_introspect_access
diff --git a/arch/sparc/kernel/syscalls/syscall.tbl b/arch/sparc/kernel/syscalls/syscall.tbl
index 4af114e84f20..d0c5fff613c7 100644
--- a/arch/sparc/kernel/syscalls/syscall.tbl
+++ b/arch/sparc/kernel/syscalls/syscall.tbl
@@ -485,3 +485,4 @@
 437	common	openat2			sys_openat2
 438	common	pidfd_getfd			sys_pidfd_getfd
 439	common	faccessat2			sys_faccessat2
+442	common	introspect_access		sys_introspect_access
diff --git a/arch/x86/entry/syscalls/syscall_32.tbl b/arch/x86/entry/syscalls/syscall_32.tbl
index 9d1102873666..64e270d811dd 100644
--- a/arch/x86/entry/syscalls/syscall_32.tbl
+++ b/arch/x86/entry/syscalls/syscall_32.tbl
@@ -444,3 +444,4 @@
 437	i386	openat2			sys_openat2
 438	i386	pidfd_getfd		sys_pidfd_getfd
 439	i386	faccessat2		sys_faccessat2
+442	i386	introspect_access		sys_introspect_access
diff --git a/arch/x86/entry/syscalls/syscall_64.tbl b/arch/x86/entry/syscalls/syscall_64.tbl
index f30d6ae9a688..afaf848bf8cd 100644
--- a/arch/x86/entry/syscalls/syscall_64.tbl
+++ b/arch/x86/entry/syscalls/syscall_64.tbl
@@ -361,6 +361,7 @@
 437	common	openat2			sys_openat2
 438	common	pidfd_getfd		sys_pidfd_getfd
 439	common	faccessat2		sys_faccessat2
+442	common	introspect_access		sys_introspect_access
 
 #
 # x32-specific system call numbers start at 512 to avoid cache impact
diff --git a/arch/xtensa/kernel/syscalls/syscall.tbl b/arch/xtensa/kernel/syscalls/syscall.tbl
index 6276e3c2d3fc..815be731b6df 100644
--- a/arch/xtensa/kernel/syscalls/syscall.tbl
+++ b/arch/xtensa/kernel/syscalls/syscall.tbl
@@ -410,3 +410,4 @@
 437	common	openat2				sys_openat2
 438	common	pidfd_getfd			sys_pidfd_getfd
 439	common	faccessat2			sys_faccessat2
+442	common	introspect_access		sys_introspect_access
diff --git a/include/uapi/asm-generic/unistd.h b/include/uapi/asm-generic/unistd.h
index 995b36c2ea7d..57120ab8a0b7 100644
--- a/include/uapi/asm-generic/unistd.h
+++ b/include/uapi/asm-generic/unistd.h
@@ -859,9 +859,11 @@ __SYSCALL(__NR_openat2, sys_openat2)
 __SYSCALL(__NR_pidfd_getfd, sys_pidfd_getfd)
 #define __NR_faccessat2 439
 __SYSCALL(__NR_faccessat2, sys_faccessat2)
+#define __NR_introspect_access 442
+__SYSCALL(__NR_introspect_access, sys_introspect_access)
 
 #undef __NR_syscalls
-#define __NR_syscalls 440
+#define __NR_syscalls 443
 
 /*
  * 32 bit systems traditionally used different
-- 
2.28.0


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

* [RFC PATCH v9 3/3] selftest/interpreter: Add tests for introspect_access(2) policies
  2020-09-10 16:46 [RFC PATCH v9 0/3] Add introspect_access(2) (was O_MAYEXEC) Mickaël Salaün
  2020-09-10 16:46 ` [RFC PATCH v9 1/3] fs: Add introspect_access(2) syscall implementation and related sysctl Mickaël Salaün
  2020-09-10 16:46 ` [RFC PATCH v9 2/3] arch: Wire up introspect_access(2) Mickaël Salaün
@ 2020-09-10 16:46 ` Mickaël Salaün
  2020-09-10 17:04 ` [RFC PATCH v9 0/3] Add introspect_access(2) (was O_MAYEXEC) Matthew Wilcox
  3 siblings, 0 replies; 17+ messages in thread
From: Mickaël Salaün @ 2020-09-10 16:46 UTC (permalink / raw)
  To: linux-kernel
  Cc: Mickaël Salaün, Aleksa Sarai, Alexei Starovoitov,
	Al Viro, Andrew Morton, Andy Lutomirski, Arnd Bergmann,
	Casey Schaufler, Christian Brauner, Christian Heimes,
	Daniel Borkmann, Deven Bowers, Dmitry Vyukov, Eric Biggers,
	Eric Chiang, Florian Weimer, James Morris, Jan Kara, Jann Horn,
	Jonathan Corbet, Kees Cook, Lakshmi Ramasubramanian,
	Matthew Garrett, Matthew Wilcox, Michael Kerrisk, Miklos Szeredi,
	Mimi Zohar, Philippe Trébuchet, Scott Shell,
	Sean Christopherson, Shuah Khan, Steve Dower, Steve Grubb,
	Tetsuo Handa, Thibaut Sautereau, Vincent Strubel,
	kernel-hardening, linux-api, linux-integrity,
	linux-security-module, linux-fsdevel, Mickaël Salaün,
	Thibaut Sautereau

From: Mickaël Salaün <mic@linux.microsoft.com>

Test that checks performed by introspect_access(2) on file descriptors
are consistent with noexec mount points and file execute permissions,
according to the policy configured with the fs.introspection_policy
sysctl.

Signed-off-by: Mickaël Salaün <mic@linux.microsoft.com>
Reviewed-by: Thibaut Sautereau <thibaut.sautereau@ssi.gouv.fr>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Kees Cook <keescook@chromium.org>
Cc: Shuah Khan <shuah@kernel.org>
Cc: Vincent Strubel <vincent.strubel@ssi.gouv.fr>
---

Changes since v8:
* Update with the dedicated syscall introspect_access(2) and the renamed
  fs.introspection_policy sysctl.
* Remove check symlink which can't be use as is anymore.
* Use socketpair(2) to test UNIX socket.

Changes since v7:
* Update tests with faccessat2/AT_INTERPRETED, including new ones to
  check that setting R_OK or W_OK returns EINVAL.
* Add tests for memfd, pipefs and nsfs.
* Rename and move back tests to a standalone directory.

Changes since v6:
* Add full combination tests for all file types, including block
  devices, character devices, fifos, sockets and symlinks.
* Properly save and restore initial sysctl value for all tests.

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

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

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

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

diff --git a/tools/testing/selftests/interpreter/.gitignore b/tools/testing/selftests/interpreter/.gitignore
new file mode 100644
index 000000000000..82a4846cbc4b
--- /dev/null
+++ b/tools/testing/selftests/interpreter/.gitignore
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0-only
+/*_test
diff --git a/tools/testing/selftests/interpreter/Makefile b/tools/testing/selftests/interpreter/Makefile
new file mode 100644
index 000000000000..6b3e8c3e533b
--- /dev/null
+++ b/tools/testing/selftests/interpreter/Makefile
@@ -0,0 +1,18 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+CFLAGS += -Wall -O2
+LDLIBS += -lcap
+
+src_test := $(wildcard *_test.c)
+TEST_GEN_PROGS := $(src_test:.c=)
+
+KSFT_KHDR_INSTALL := 1
+include ../lib.mk
+
+khdr_dir = $(top_srcdir)/usr/include
+
+$(khdr_dir)/asm-generic/unistd.h: khdr
+	@:
+
+$(OUTPUT)/%_test: %_test.c $(khdr_dir)/asm-generic/unistd.h ../kselftest_harness.h
+	$(LINK.c) $< $(LDLIBS) -o $@ -I$(khdr_dir)
diff --git a/tools/testing/selftests/interpreter/config b/tools/testing/selftests/interpreter/config
new file mode 100644
index 000000000000..dd53c266bf52
--- /dev/null
+++ b/tools/testing/selftests/interpreter/config
@@ -0,0 +1 @@
+CONFIG_SYSCTL=y
diff --git a/tools/testing/selftests/interpreter/introspection_policy_test.c b/tools/testing/selftests/interpreter/introspection_policy_test.c
new file mode 100644
index 000000000000..e5a63cb05877
--- /dev/null
+++ b/tools/testing/selftests/interpreter/introspection_policy_test.c
@@ -0,0 +1,361 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Test introspect_access(2) with fs.introspection_policy sysctl
+ *
+ * Copyright © 2018-2020 ANSSI
+ *
+ * Author: Mickaël Salaün <mic@digikod.net>
+ */
+
+#define _GNU_SOURCE
+#include <asm-generic/unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/capability.h>
+#include <sys/mman.h>
+#include <sys/mount.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/syscall.h>
+#include <sys/sysmacros.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "../kselftest_harness.h"
+
+#ifndef introspect_access
+static int introspect_access(const int fd, const int mode, const int flags)
+{
+	errno = 0;
+	return syscall(__NR_introspect_access, fd, mode, flags);
+}
+#endif
+
+static const char sysctl_path[] = "/proc/sys/fs/introspection_policy";
+
+static const char workdir_path[] = "./test-mount";
+static const char reg_file_path[] = "./test-mount/regular_file";
+static const char dir_path[] = "./test-mount/directory";
+static const char block_dev_path[] = "./test-mount/block_device";
+static const char char_dev_path[] = "./test-mount/character_device";
+static const char fifo_path[] = "./test-mount/fifo";
+
+static 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_access)
+{
+	int flags = O_RDONLY | O_CLOEXEC;
+	int fd, access_ret, access_errno;
+
+	/* Do not block on pipes. */
+	if (path == fifo_path)
+		flags |= O_NONBLOCK;
+
+	fd = open(path, flags);
+	ASSERT_LE(0, fd) {
+		TH_LOG("Failed to open %s: %s", path, strerror(errno));
+	}
+	access_ret = introspect_access(fd, X_OK, 0);
+	access_errno = errno;
+	if (err_access) {
+		ASSERT_EQ(err_access, access_errno) {
+			TH_LOG("Wrong error for introspect_access(2) with %s: %s",
+					path, strerror(access_errno));
+		}
+		ASSERT_EQ(-1, access_ret);
+	} else {
+		ASSERT_EQ(0, access_ret) {
+			TH_LOG("Access denied for %s: %s", path, strerror(access_errno));
+		}
+	}
+
+	/* Tests read access. */
+	access_ret = introspect_access(fd, R_OK, 0);
+	ASSERT_EQ(-1, access_ret);
+	ASSERT_EQ(EINVAL, errno);
+
+	/* Tests write access. */
+	access_ret = introspect_access(fd, W_OK, 0);
+	ASSERT_EQ(-1, access_ret);
+	ASSERT_EQ(EINVAL, errno);
+
+	EXPECT_EQ(0, close(fd));
+}
+
+static void test_policy_fd(struct __test_metadata *_metadata, const int fd,
+		const bool has_policy)
+{
+	const int ret = introspect_access(fd, X_OK, 0);
+
+	if (has_policy) {
+		ASSERT_EQ(-1, ret);
+		ASSERT_EQ(EACCES, errno) {
+			TH_LOG("Wrong error for introspect_access(2) with FD: %s", strerror(errno));
+		}
+	} else {
+		ASSERT_EQ(0, ret) {
+			TH_LOG("Access denied for FD: %s", strerror(errno));
+		}
+	}
+}
+
+FIXTURE(access) {
+	char initial_sysctl_value;
+	int memfd, pipefd;
+	int pipe_fds[2], socket_fds[2];
+};
+
+static void test_file_types(struct __test_metadata *_metadata, FIXTURE_DATA(access) *self,
+		const int err_code, const bool has_policy)
+{
+	/* Tests are performed on a tmpfs mount point. */
+	test_omx(_metadata, reg_file_path, err_code);
+	test_omx(_metadata, dir_path, has_policy ? EACCES : 0);
+	test_omx(_metadata, block_dev_path, has_policy ? EACCES : 0);
+	test_omx(_metadata, char_dev_path, has_policy ? EACCES : 0);
+	test_omx(_metadata, fifo_path, has_policy ? EACCES : 0);
+
+	/* Checks that exec is denied for any socket FD. */
+	test_policy_fd(_metadata, self->socket_fds[0], has_policy);
+
+	/* Checks that exec is denied for any memfd. */
+	test_policy_fd(_metadata, self->memfd, has_policy);
+
+	/* Checks that exec is denied for any pipefs FD. */
+	test_policy_fd(_metadata, self->pipefd, has_policy);
+}
+
+static void test_files(struct __test_metadata *_metadata, FIXTURE_DATA(access) *self,
+		const int err_code, const bool has_policy)
+{
+	/* Tests as root. */
+	ignore_dac(_metadata, 1);
+	test_file_types(_metadata, self, err_code, has_policy);
+
+	/* Tests without bypass. */
+	ignore_dac(_metadata, 0);
+	test_file_types(_metadata, self, err_code, has_policy);
+}
+
+static void sysctl_write_char(struct __test_metadata *_metadata, const char value)
+{
+	int fd;
+
+	fd = open(sysctl_path, O_WRONLY | O_CLOEXEC);
+	ASSERT_LE(0, fd);
+	ASSERT_EQ(1, write(fd, &value, 1));
+	EXPECT_EQ(0, close(fd));
+}
+
+static char sysctl_read_char(struct __test_metadata *_metadata)
+{
+	int fd;
+	char sysctl_value;
+
+	fd = open(sysctl_path, O_RDONLY | O_CLOEXEC);
+	ASSERT_LE(0, fd);
+	ASSERT_EQ(1, read(fd, &sysctl_value, 1));
+	EXPECT_EQ(0, close(fd));
+	return sysctl_value;
+}
+
+FIXTURE_VARIANT(access) {
+	const bool mount_exec;
+	const bool file_exec;
+	const int sysctl_err_code[3];
+};
+
+FIXTURE_VARIANT_ADD(access, mount_exec_file_exec) {
+	.mount_exec = true,
+	.file_exec = true,
+	.sysctl_err_code = {0, 0, 0},
+};
+
+FIXTURE_VARIANT_ADD(access, mount_exec_file_noexec)
+{
+	.mount_exec = true,
+	.file_exec = false,
+	.sysctl_err_code = {0, EACCES, EACCES},
+};
+
+FIXTURE_VARIANT_ADD(access, mount_noexec_file_exec)
+{
+	.mount_exec = false,
+	.file_exec = true,
+	.sysctl_err_code = {EACCES, 0, EACCES},
+};
+
+FIXTURE_VARIANT_ADD(access, mount_noexec_file_noexec)
+{
+	.mount_exec = false,
+	.file_exec = false,
+	.sysctl_err_code = {EACCES, EACCES, EACCES},
+};
+
+FIXTURE_SETUP(access)
+{
+	int procfd_path_size;
+	static const char path_template[] = "/proc/self/fd/%d";
+	char procfd_path[sizeof(path_template) + 10];
+
+	/*
+	 * Cleans previous workspace if any error previously happened (don't
+	 * check errors).
+	 */
+	umount(workdir_path);
+	rmdir(workdir_path);
+
+	/* Creates a clean mount point. */
+	ASSERT_EQ(0, mkdir(workdir_path, 00700));
+	ASSERT_EQ(0, mount("test", workdir_path, "tmpfs", MS_MGC_VAL |
+				(variant->mount_exec ? 0 : MS_NOEXEC),
+				"mode=0700,size=4k"));
+
+	/* Creates a regular file. */
+	ASSERT_EQ(0, mknod(reg_file_path, S_IFREG | (variant->file_exec ? 0500 : 0400), 0));
+	/* Creates a directory. */
+	ASSERT_EQ(0, mkdir(dir_path, variant->file_exec ? 0500 : 0400));
+	/* Creates a character device: /dev/null. */
+	ASSERT_EQ(0, mknod(char_dev_path, S_IFCHR | 0400, makedev(1, 3)));
+	/* Creates a block device: /dev/loop0 */
+	ASSERT_EQ(0, mknod(block_dev_path, S_IFBLK | 0400, makedev(7, 0)));
+	/* Creates a fifo. */
+	ASSERT_EQ(0, mknod(fifo_path, S_IFIFO | 0400, 0));
+
+	/* Creates a regular file without user mount point. */
+	self->memfd = memfd_create("test-interpreted", MFD_CLOEXEC);
+	ASSERT_LE(0, self->memfd);
+	/* Sets mode, which must be ignored by the exec check. */
+	ASSERT_EQ(0, fchmod(self->memfd, variant->file_exec ? 0500 : 0400));
+
+	/* Creates a pipefs file descriptor. */
+	ASSERT_EQ(0, pipe(self->pipe_fds));
+	procfd_path_size = snprintf(procfd_path, sizeof(procfd_path),
+			path_template, self->pipe_fds[0]);
+	ASSERT_LT(procfd_path_size, sizeof(procfd_path));
+	self->pipefd = open(procfd_path, O_RDONLY | O_CLOEXEC);
+	ASSERT_LE(0, self->pipefd);
+	ASSERT_EQ(0, fchmod(self->pipefd, variant->file_exec ? 0500 : 0400));
+
+	/* Creates a socket file descriptor. */
+	ASSERT_EQ(0, socketpair(AF_UNIX, SOCK_DGRAM | SOCK_CLOEXEC, 0, self->socket_fds));
+
+	/* Saves initial sysctl value. */
+	self->initial_sysctl_value = sysctl_read_char(_metadata);
+
+	/* Prepares for sysctl writes. */
+	ignore_sys_admin(_metadata, 1);
+}
+
+FIXTURE_TEARDOWN(access)
+{
+	EXPECT_EQ(0, close(self->memfd));
+	EXPECT_EQ(0, close(self->pipefd));
+	EXPECT_EQ(0, close(self->pipe_fds[0]));
+	EXPECT_EQ(0, close(self->pipe_fds[1]));
+	EXPECT_EQ(0, close(self->socket_fds[0]));
+	EXPECT_EQ(0, close(self->socket_fds[1]));
+
+	/* Restores initial sysctl value. */
+	sysctl_write_char(_metadata, self->initial_sysctl_value);
+
+	/* There is no need to unlink the test files. */
+	ASSERT_EQ(0, umount(workdir_path));
+	ASSERT_EQ(0, rmdir(workdir_path));
+}
+
+TEST_F(access, sysctl_0)
+{
+	/* Do not enforce anything. */
+	sysctl_write_char(_metadata, '0');
+	test_files(_metadata, self, 0, false);
+}
+
+TEST_F(access, sysctl_1)
+{
+	/* Enforces mount exec check. */
+	sysctl_write_char(_metadata, '1');
+	test_files(_metadata, self, variant->sysctl_err_code[0], true);
+}
+
+TEST_F(access, sysctl_2)
+{
+	/* Enforces file exec check. */
+	sysctl_write_char(_metadata, '2');
+	test_files(_metadata, self, variant->sysctl_err_code[1], true);
+}
+
+TEST_F(access, sysctl_3)
+{
+	/* Enforces mount and file exec check. */
+	sysctl_write_char(_metadata, '3');
+	test_files(_metadata, self, variant->sysctl_err_code[2], true);
+}
+
+FIXTURE(cleanup) {
+	char initial_sysctl_value;
+};
+
+FIXTURE_SETUP(cleanup)
+{
+	/* Saves initial sysctl value. */
+	self->initial_sysctl_value = sysctl_read_char(_metadata);
+}
+
+FIXTURE_TEARDOWN(cleanup)
+{
+	/* Restores initial sysctl value. */
+	ignore_sys_admin(_metadata, 1);
+	sysctl_write_char(_metadata, self->initial_sysctl_value);
+}
+
+TEST_F(cleanup, sysctl_access_write)
+{
+	int fd;
+	ssize_t ret;
+
+	ignore_sys_admin(_metadata, 1);
+	sysctl_write_char(_metadata, '0');
+
+	ignore_sys_admin(_metadata, 0);
+	fd = open(sysctl_path, O_WRONLY | O_CLOEXEC);
+	ASSERT_LE(0, fd);
+	ret = write(fd, "0", 1);
+	ASSERT_EQ(-1, ret);
+	ASSERT_EQ(EPERM, errno);
+	EXPECT_EQ(0, close(fd));
+}
+
+TEST_HARNESS_MAIN
-- 
2.28.0


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

* Re: [RFC PATCH v9 0/3] Add introspect_access(2) (was O_MAYEXEC)
  2020-09-10 16:46 [RFC PATCH v9 0/3] Add introspect_access(2) (was O_MAYEXEC) Mickaël Salaün
                   ` (2 preceding siblings ...)
  2020-09-10 16:46 ` [RFC PATCH v9 3/3] selftest/interpreter: Add tests for introspect_access(2) policies Mickaël Salaün
@ 2020-09-10 17:04 ` Matthew Wilcox
  2020-09-10 17:21   ` Mickaël Salaün
  3 siblings, 1 reply; 17+ messages in thread
From: Matthew Wilcox @ 2020-09-10 17:04 UTC (permalink / raw)
  To: Mickaël Salaün
  Cc: linux-kernel, Aleksa Sarai, Alexei Starovoitov, Al Viro,
	Andrew Morton, Andy Lutomirski, Arnd Bergmann, Casey Schaufler,
	Christian Brauner, Christian Heimes, Daniel Borkmann,
	Deven Bowers, Dmitry Vyukov, Eric Biggers, Eric Chiang,
	Florian Weimer, James Morris, Jan Kara, Jann Horn,
	Jonathan Corbet, Kees Cook, Lakshmi Ramasubramanian,
	Matthew Garrett, Michael Kerrisk, Miklos Szeredi, Mimi Zohar,
	Philippe Trébuchet, Scott Shell, Sean Christopherson,
	Shuah Khan, Steve Dower, Steve Grubb, Tetsuo Handa,
	Thibaut Sautereau, Vincent Strubel, kernel-hardening, linux-api,
	linux-integrity, linux-security-module, linux-fsdevel

On Thu, Sep 10, 2020 at 06:46:09PM +0200, Mickaël Salaün wrote:
> This ninth patch series rework the previous AT_INTERPRETED and O_MAYEXEC
> series with a new syscall: introspect_access(2) .  Access check are now
> only possible on a file descriptor, which enable to avoid possible race
> conditions in user space.

But introspection is about examining _yourself_.  This isn't about
doing that.  It's about doing ... something ... to a script that you're
going to execute.  If the script were going to call the syscall, then
it might be introspection.  Or if the interpreter were measuring itself,
that would be introspection.  But neither of those would be useful things
to do, because an attacker could simply avoid doing them.

So, bad name.  What might be better?  sys_security_check()?
sys_measure()?  sys_verify_fd()?  I don't know.


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

* Re: [RFC PATCH v9 0/3] Add introspect_access(2) (was O_MAYEXEC)
  2020-09-10 17:04 ` [RFC PATCH v9 0/3] Add introspect_access(2) (was O_MAYEXEC) Matthew Wilcox
@ 2020-09-10 17:21   ` Mickaël Salaün
  2020-09-10 17:47     ` Mickaël Salaün
  2020-09-10 18:08     ` Mimi Zohar
  0 siblings, 2 replies; 17+ messages in thread
From: Mickaël Salaün @ 2020-09-10 17:21 UTC (permalink / raw)
  To: Matthew Wilcox
  Cc: linux-kernel, Aleksa Sarai, Alexei Starovoitov, Al Viro,
	Andrew Morton, Andy Lutomirski, Arnd Bergmann, Casey Schaufler,
	Christian Brauner, Christian Heimes, Daniel Borkmann,
	Deven Bowers, Dmitry Vyukov, Eric Biggers, Eric Chiang,
	Florian Weimer, James Morris, Jan Kara, Jann Horn,
	Jonathan Corbet, Kees Cook, Lakshmi Ramasubramanian,
	Matthew Garrett, Michael Kerrisk, Miklos Szeredi, Mimi Zohar,
	Philippe Trébuchet, Scott Shell, Sean Christopherson,
	Shuah Khan, Steve Dower, Steve Grubb, Tetsuo Handa,
	Thibaut Sautereau, Vincent Strubel, kernel-hardening, linux-api,
	linux-integrity, linux-security-module, linux-fsdevel


On 10/09/2020 19:04, Matthew Wilcox wrote:
> On Thu, Sep 10, 2020 at 06:46:09PM +0200, Mickaël Salaün wrote:
>> This ninth patch series rework the previous AT_INTERPRETED and O_MAYEXEC
>> series with a new syscall: introspect_access(2) .  Access check are now
>> only possible on a file descriptor, which enable to avoid possible race
>> conditions in user space.
> 
> But introspection is about examining _yourself_.  This isn't about
> doing that.  It's about doing ... something ... to a script that you're
> going to execute.  If the script were going to call the syscall, then
> it might be introspection.  Or if the interpreter were measuring itself,
> that would be introspection.  But neither of those would be useful things
> to do, because an attacker could simply avoid doing them.

Picking a good name other than "access" (or faccessat2) is not easy. The
idea with introspect_access() is for the calling task to ask the kernel
if this task should allows to do give access to a kernel resource which
is already available to this task. In this sense, we think that
introspection makes sense because it is the choice of the task to allow
or deny an access.

> 
> So, bad name.  What might be better?  sys_security_check()?
> sys_measure()?  sys_verify_fd()?  I don't know.
> 

"security_check" looks quite broad, "measure" doesn't make sense here,
"verify_fd" doesn't reflect that it is an access check. Yes, not easy,
but if this is the only concern we are on the good track. :)


Other ideas:
- interpret_access (mainly, but not only, for interpreters)
- indirect_access
- may_access
- faccessat3

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

* Re: [RFC PATCH v9 0/3] Add introspect_access(2) (was O_MAYEXEC)
  2020-09-10 17:21   ` Mickaël Salaün
@ 2020-09-10 17:47     ` Mickaël Salaün
  2020-09-10 18:08     ` Mimi Zohar
  1 sibling, 0 replies; 17+ messages in thread
From: Mickaël Salaün @ 2020-09-10 17:47 UTC (permalink / raw)
  To: Matthew Wilcox
  Cc: linux-kernel, Aleksa Sarai, Alexei Starovoitov, Al Viro,
	Andrew Morton, Andy Lutomirski, Arnd Bergmann, Casey Schaufler,
	Christian Brauner, Christian Heimes, Daniel Borkmann,
	Deven Bowers, Dmitry Vyukov, Eric Biggers, Eric Chiang,
	Florian Weimer, James Morris, Jan Kara, Jann Horn,
	Jonathan Corbet, Kees Cook, Lakshmi Ramasubramanian,
	Matthew Garrett, Michael Kerrisk, Miklos Szeredi, Mimi Zohar,
	Philippe Trébuchet, Scott Shell, Sean Christopherson,
	Shuah Khan, Steve Dower, Steve Grubb, Tetsuo Handa,
	Thibaut Sautereau, Vincent Strubel, kernel-hardening, linux-api,
	linux-integrity, linux-security-module, linux-fsdevel


On 10/09/2020 19:21, Mickaël Salaün wrote:
> 
> On 10/09/2020 19:04, Matthew Wilcox wrote:
>> On Thu, Sep 10, 2020 at 06:46:09PM +0200, Mickaël Salaün wrote:
>>> This ninth patch series rework the previous AT_INTERPRETED and O_MAYEXEC
>>> series with a new syscall: introspect_access(2) .  Access check are now
>>> only possible on a file descriptor, which enable to avoid possible race
>>> conditions in user space.
>>
>> But introspection is about examining _yourself_.  This isn't about
>> doing that.  It's about doing ... something ... to a script that you're
>> going to execute.  If the script were going to call the syscall, then
>> it might be introspection.  Or if the interpreter were measuring itself,
>> that would be introspection.  But neither of those would be useful things
>> to do, because an attacker could simply avoid doing them.
> 
> Picking a good name other than "access" (or faccessat2) is not easy. The
> idea with introspect_access() is for the calling task to ask the kernel
> if this task should allows to do give access to a kernel resource which
> is already available to this task. In this sense, we think that
> introspection makes sense because it is the choice of the task to allow
> or deny an access.
> 
>>
>> So, bad name.  What might be better?  sys_security_check()?
>> sys_measure()?  sys_verify_fd()?  I don't know.
>>
> 
> "security_check" looks quite broad, "measure" doesn't make sense here,
> "verify_fd" doesn't reflect that it is an access check. Yes, not easy,
> but if this is the only concern we are on the good track. :)
> 
> 
> Other ideas:
> - interpret_access (mainly, but not only, for interpreters)
> - indirect_access
> - may_access
> - faccessat3
> 

I think that entrusted_access(2) looks good. What do you think?

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

* Re: [RFC PATCH v9 0/3] Add introspect_access(2) (was O_MAYEXEC)
  2020-09-10 17:21   ` Mickaël Salaün
  2020-09-10 17:47     ` Mickaël Salaün
@ 2020-09-10 18:08     ` Mimi Zohar
  2020-09-10 18:38       ` Mickaël Salaün
  1 sibling, 1 reply; 17+ messages in thread
From: Mimi Zohar @ 2020-09-10 18:08 UTC (permalink / raw)
  To: Mickaël Salaün, Matthew Wilcox
  Cc: linux-kernel, Aleksa Sarai, Alexei Starovoitov, Al Viro,
	Andrew Morton, Andy Lutomirski, Arnd Bergmann, Casey Schaufler,
	Christian Brauner, Christian Heimes, Daniel Borkmann,
	Deven Bowers, Dmitry Vyukov, Eric Biggers, Eric Chiang,
	Florian Weimer, James Morris, Jan Kara, Jann Horn,
	Jonathan Corbet, Kees Cook, Lakshmi Ramasubramanian,
	Matthew Garrett, Michael Kerrisk, Miklos Szeredi,
	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, 2020-09-10 at 19:21 +0200, Mickaël Salaün wrote:
> On 10/09/2020 19:04, Matthew Wilcox wrote:
> > On Thu, Sep 10, 2020 at 06:46:09PM +0200, Mickaël Salaün wrote:
> >> This ninth patch series rework the previous AT_INTERPRETED and O_MAYEXEC
> >> series with a new syscall: introspect_access(2) .  Access check are now
> >> only possible on a file descriptor, which enable to avoid possible race
> >> conditions in user space.
> > 
> > But introspection is about examining _yourself_.  This isn't about
> > doing that.  It's about doing ... something ... to a script that you're
> > going to execute.  If the script were going to call the syscall, then
> > it might be introspection.  Or if the interpreter were measuring itself,
> > that would be introspection.  But neither of those would be useful things
> > to do, because an attacker could simply avoid doing them.
> 

Michael, is the confusion here that IMA isn't measuring anything, but
verifying the integrity of the file?   The usecase, from an IMA
perspective, is enforcing a system wide policy requiring everything
executed to be signed.  In this particular use case, the interpreter is
asking the kernel if the script is signed with a permitted key.  The
signature may be an IMA signature or an EVM portable and immutable
signature, based on policy.

> Picking a good name other than "access" (or faccessat2) is not easy. The
> idea with introspect_access() is for the calling task to ask the kernel
> if this task should allows to do give access to a kernel resource which
> is already available to this task. In this sense, we think that
> introspection makes sense because it is the choice of the task to allow
> or deny an access.
> 
> > 
> > So, bad name.  What might be better?  sys_security_check()?
> > sys_measure()?  sys_verify_fd()?  I don't know.
> > 
> 
> "security_check" looks quite broad, "measure" doesn't make sense here,
> "verify_fd" doesn't reflect that it is an access check. Yes, not easy,
> but if this is the only concern we are on the good track. :)

Maybe replacing the term "measure" with "integrity", but rather than
"integrity_check", something along the lines of fgetintegrity,
freadintegrity, fcheckintegrity.

Mimi

> 
> 
> Other ideas:
> - interpret_access (mainly, but not only, for interpreters)
> - indirect_access
> - may_access
> - faccessat3



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

* Re: [RFC PATCH v9 0/3] Add introspect_access(2) (was O_MAYEXEC)
  2020-09-10 18:08     ` Mimi Zohar
@ 2020-09-10 18:38       ` Mickaël Salaün
  2020-09-10 18:40         ` Matthew Wilcox
  0 siblings, 1 reply; 17+ messages in thread
From: Mickaël Salaün @ 2020-09-10 18:38 UTC (permalink / raw)
  To: Mimi Zohar, Matthew Wilcox
  Cc: linux-kernel, Aleksa Sarai, Alexei Starovoitov, Al Viro,
	Andrew Morton, Andy Lutomirski, Arnd Bergmann, Casey Schaufler,
	Christian Brauner, Christian Heimes, Daniel Borkmann,
	Deven Bowers, Dmitry Vyukov, Eric Biggers, Eric Chiang,
	Florian Weimer, James Morris, Jan Kara, Jann Horn,
	Jonathan Corbet, Kees Cook, Lakshmi Ramasubramanian,
	Matthew Garrett, Michael Kerrisk, Miklos Szeredi,
	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 10/09/2020 20:08, Mimi Zohar wrote:
> On Thu, 2020-09-10 at 19:21 +0200, Mickaël Salaün wrote:
>> On 10/09/2020 19:04, Matthew Wilcox wrote:
>>> On Thu, Sep 10, 2020 at 06:46:09PM +0200, Mickaël Salaün wrote:
>>>> This ninth patch series rework the previous AT_INTERPRETED and O_MAYEXEC
>>>> series with a new syscall: introspect_access(2) .  Access check are now
>>>> only possible on a file descriptor, which enable to avoid possible race
>>>> conditions in user space.
>>>
>>> But introspection is about examining _yourself_.  This isn't about
>>> doing that.  It's about doing ... something ... to a script that you're
>>> going to execute.  If the script were going to call the syscall, then
>>> it might be introspection.  Or if the interpreter were measuring itself,
>>> that would be introspection.  But neither of those would be useful things
>>> to do, because an attacker could simply avoid doing them.
>>
> 
> Michael, is the confusion here that IMA isn't measuring anything, but
> verifying the integrity of the file?   The usecase, from an IMA
> perspective, is enforcing a system wide policy requiring everything
> executed to be signed.  In this particular use case, the interpreter is
> asking the kernel if the script is signed with a permitted key.  The
> signature may be an IMA signature or an EVM portable and immutable
> signature, based on policy.

There is also the use case of noexec mounts and file permissions. From
user space point of view, it doesn't matter which kernel component is in
charge of defining the policy. The syscall should then not be tied with
a verification/integrity/signature/appraisal vocabulary, but simply an
access control one.

> 
>> Picking a good name other than "access" (or faccessat2) is not easy. The
>> idea with introspect_access() is for the calling task to ask the kernel
>> if this task should allows to do give access to a kernel resource which
>> is already available to this task. In this sense, we think that
>> introspection makes sense because it is the choice of the task to allow
>> or deny an access.
>>
>>>
>>> So, bad name.  What might be better?  sys_security_check()?
>>> sys_measure()?  sys_verify_fd()?  I don't know.
>>>
>>
>> "security_check" looks quite broad, "measure" doesn't make sense here,
>> "verify_fd" doesn't reflect that it is an access check. Yes, not easy,
>> but if this is the only concern we are on the good track. :)
> 
> Maybe replacing the term "measure" with "integrity", but rather than
> "integrity_check", something along the lines of fgetintegrity,
> freadintegrity, fcheckintegrity.

What about entrusted_access(2)? It reflects the fact that the kernel
delegate to (trusted) user space tasks some access enforcements.

> 
> Mimi
> 
>>
>>
>> Other ideas:
>> - interpret_access (mainly, but not only, for interpreters)
>> - indirect_access
>> - may_access
>> - faccessat3
> 
> 

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

* Re: [RFC PATCH v9 0/3] Add introspect_access(2) (was O_MAYEXEC)
  2020-09-10 18:38       ` Mickaël Salaün
@ 2020-09-10 18:40         ` Matthew Wilcox
  2020-09-10 20:00           ` Al Viro
  2020-09-12  0:28           ` James Morris
  0 siblings, 2 replies; 17+ messages in thread
From: Matthew Wilcox @ 2020-09-10 18:40 UTC (permalink / raw)
  To: Mickaël Salaün
  Cc: Mimi Zohar, linux-kernel, Aleksa Sarai, Alexei Starovoitov,
	Al Viro, Andrew Morton, Andy Lutomirski, Arnd Bergmann,
	Casey Schaufler, Christian Brauner, Christian Heimes,
	Daniel Borkmann, Deven Bowers, Dmitry Vyukov, Eric Biggers,
	Eric Chiang, Florian Weimer, James Morris, Jan Kara, Jann Horn,
	Jonathan Corbet, Kees Cook, Lakshmi Ramasubramanian,
	Matthew Garrett, Michael Kerrisk, Miklos Szeredi,
	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, Sep 10, 2020 at 08:38:21PM +0200, Mickaël Salaün wrote:
> There is also the use case of noexec mounts and file permissions. From
> user space point of view, it doesn't matter which kernel component is in
> charge of defining the policy. The syscall should then not be tied with
> a verification/integrity/signature/appraisal vocabulary, but simply an
> access control one.

permission()?

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

* Re: [RFC PATCH v9 0/3] Add introspect_access(2) (was O_MAYEXEC)
  2020-09-10 18:40         ` Matthew Wilcox
@ 2020-09-10 20:00           ` Al Viro
  2020-09-10 20:05             ` Matthew Wilcox
  2020-09-12  0:28           ` James Morris
  1 sibling, 1 reply; 17+ messages in thread
From: Al Viro @ 2020-09-10 20:00 UTC (permalink / raw)
  To: Matthew Wilcox
  Cc: Mickaël Salaün, Mimi Zohar, linux-kernel, Aleksa Sarai,
	Alexei Starovoitov, Andrew Morton, Andy Lutomirski,
	Arnd Bergmann, Casey Schaufler, Christian Brauner,
	Christian Heimes, Daniel Borkmann, Deven Bowers, Dmitry Vyukov,
	Eric Biggers, Eric Chiang, Florian Weimer, James Morris,
	Jan Kara, Jann Horn, Jonathan Corbet, Kees Cook,
	Lakshmi Ramasubramanian, Matthew Garrett, Michael Kerrisk,
	Miklos Szeredi, 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, Sep 10, 2020 at 07:40:33PM +0100, Matthew Wilcox wrote:
> On Thu, Sep 10, 2020 at 08:38:21PM +0200, Mickaël Salaün wrote:
> > There is also the use case of noexec mounts and file permissions. From
> > user space point of view, it doesn't matter which kernel component is in
> > charge of defining the policy. The syscall should then not be tied with
> > a verification/integrity/signature/appraisal vocabulary, but simply an
> > access control one.
> 
> permission()?

int lsm(int fd, const char *how, char *error, int size);

Seriously, this is "ask LSM to apply special policy to file"; let's
_not_ mess with flags, etc. for that; give it decent bandwidth
and since it's completely opaque for the rest of the kernel,
just a pass a string to be parsed by LSM as it sees fit.

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

* Re: [RFC PATCH v9 0/3] Add introspect_access(2) (was O_MAYEXEC)
  2020-09-10 20:00           ` Al Viro
@ 2020-09-10 20:05             ` Matthew Wilcox
  2020-09-11 12:16               ` Mickaël Salaün
  2020-09-11 14:15               ` Igor Zhbanov
  0 siblings, 2 replies; 17+ messages in thread
From: Matthew Wilcox @ 2020-09-10 20:05 UTC (permalink / raw)
  To: Al Viro
  Cc: Mickaël Salaün, Mimi Zohar, linux-kernel, Aleksa Sarai,
	Alexei Starovoitov, Andrew Morton, Andy Lutomirski,
	Arnd Bergmann, Casey Schaufler, Christian Brauner,
	Christian Heimes, Daniel Borkmann, Deven Bowers, Dmitry Vyukov,
	Eric Biggers, Eric Chiang, Florian Weimer, James Morris,
	Jan Kara, Jann Horn, Jonathan Corbet, Kees Cook,
	Lakshmi Ramasubramanian, Matthew Garrett, Michael Kerrisk,
	Miklos Szeredi, 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, Sep 10, 2020 at 09:00:10PM +0100, Al Viro wrote:
> On Thu, Sep 10, 2020 at 07:40:33PM +0100, Matthew Wilcox wrote:
> > On Thu, Sep 10, 2020 at 08:38:21PM +0200, Mickaël Salaün wrote:
> > > There is also the use case of noexec mounts and file permissions. From
> > > user space point of view, it doesn't matter which kernel component is in
> > > charge of defining the policy. The syscall should then not be tied with
> > > a verification/integrity/signature/appraisal vocabulary, but simply an
> > > access control one.
> > 
> > permission()?
> 
> int lsm(int fd, const char *how, char *error, int size);
> 
> Seriously, this is "ask LSM to apply special policy to file"; let's
> _not_ mess with flags, etc. for that; give it decent bandwidth
> and since it's completely opaque for the rest of the kernel,
> just a pass a string to be parsed by LSM as it sees fit.

Hang on, it does have some things which aren't BD^W^WLSM.  It lets
the interpreter honour the mount -o noexec option.  I presume it's
not easily defeated by
	cat /home/salaun/bin/bad.pl | perl -


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

* Re: [RFC PATCH v9 0/3] Add introspect_access(2) (was O_MAYEXEC)
  2020-09-10 20:05             ` Matthew Wilcox
@ 2020-09-11 12:16               ` Mickaël Salaün
  2020-09-11 14:15               ` Igor Zhbanov
  1 sibling, 0 replies; 17+ messages in thread
From: Mickaël Salaün @ 2020-09-11 12:16 UTC (permalink / raw)
  To: Matthew Wilcox, Al Viro
  Cc: Mimi Zohar, linux-kernel, Aleksa Sarai, Alexei Starovoitov,
	Andrew Morton, Andy Lutomirski, Arnd Bergmann, Casey Schaufler,
	Christian Brauner, Christian Heimes, Daniel Borkmann,
	Deven Bowers, Dmitry Vyukov, Eric Biggers, Eric Chiang,
	Florian Weimer, James Morris, Jan Kara, Jann Horn,
	Jonathan Corbet, Kees Cook, Lakshmi Ramasubramanian,
	Matthew Garrett, Michael Kerrisk, Miklos Szeredi,
	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 10/09/2020 22:05, Matthew Wilcox wrote:
> On Thu, Sep 10, 2020 at 09:00:10PM +0100, Al Viro wrote:
>> On Thu, Sep 10, 2020 at 07:40:33PM +0100, Matthew Wilcox wrote:
>>> On Thu, Sep 10, 2020 at 08:38:21PM +0200, Mickaël Salaün wrote:
>>>> There is also the use case of noexec mounts and file permissions. From
>>>> user space point of view, it doesn't matter which kernel component is in
>>>> charge of defining the policy. The syscall should then not be tied with
>>>> a verification/integrity/signature/appraisal vocabulary, but simply an
>>>> access control one.
>>>
>>> permission()?
>>
>> int lsm(int fd, const char *how, char *error, int size);
>>
>> Seriously, this is "ask LSM to apply special policy to file"; let's
>> _not_ mess with flags, etc. for that; give it decent bandwidth
>> and since it's completely opaque for the rest of the kernel,
>> just a pass a string to be parsed by LSM as it sees fit.

Well, I don't know why you're so angry against LSM, but as noticed by
Matthew, the main focus of this patch series is not about LSM (no hook,
no security/* code, only file permission and mount option checks,
nothing fancy). Moreover, the syscall you're proposing doesn't make
sense, but I guess it's yet another sarcastic reply. Please, cool down.
We asked for constructive comments and already followed your previous
requests (even if we didn't get answers for some questions), but
seriously, this one is nonsense.

> 
> Hang on, it does have some things which aren't BD^W^WLSM.  It lets
> the interpreter honour the mount -o noexec option.  I presume it's
> not easily defeated by
> 	cat /home/salaun/bin/bad.pl | perl -
> 

Funny. I know there is a lot of text and links but please read the
commit messages before further comments.

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

* Re: [RFC PATCH v9 0/3] Add introspect_access(2) (was O_MAYEXEC)
  2020-09-10 20:05             ` Matthew Wilcox
  2020-09-11 12:16               ` Mickaël Salaün
@ 2020-09-11 14:15               ` Igor Zhbanov
  1 sibling, 0 replies; 17+ messages in thread
From: Igor Zhbanov @ 2020-09-11 14:15 UTC (permalink / raw)
  To: Matthew Wilcox, Al Viro
  Cc: Mickaël Salaün, Mimi Zohar, linux-kernel, Aleksa Sarai,
	Alexei Starovoitov, Andrew Morton, Andy Lutomirski,
	Arnd Bergmann, Casey Schaufler, Christian Brauner,
	Christian Heimes, Daniel Borkmann, Deven Bowers, Dmitry Vyukov,
	Eric Biggers, Eric Chiang, Florian Weimer, James Morris,
	Jan Kara, Jann Horn, Jonathan Corbet, Kees Cook,
	Lakshmi Ramasubramanian, Matthew Garrett, Michael Kerrisk,
	Miklos Szeredi, 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 10.09.2020 23:05, Matthew Wilcox wrote:
> On Thu, Sep 10, 2020 at 09:00:10PM +0100, Al Viro wrote:
>> On Thu, Sep 10, 2020 at 07:40:33PM +0100, Matthew Wilcox wrote:
>>> On Thu, Sep 10, 2020 at 08:38:21PM +0200, Mickaël Salaün wrote:
>>>> There is also the use case of noexec mounts and file permissions. From
>>>> user space point of view, it doesn't matter which kernel component is in
>>>> charge of defining the policy. The syscall should then not be tied with
>>>> a verification/integrity/signature/appraisal vocabulary, but simply an
>>>> access control one.
>>>
>>> permission()?
>>
>> int lsm(int fd, const char *how, char *error, int size);
>>
>> Seriously, this is "ask LSM to apply special policy to file"; let's
>> _not_ mess with flags, etc. for that; give it decent bandwidth
>> and since it's completely opaque for the rest of the kernel,
>> just a pass a string to be parsed by LSM as it sees fit.
> 
> Hang on, it does have some things which aren't BD^W^WLSM.  It lets
> the interpreter honour the mount -o noexec option.  I presume it's
> not easily defeated by
> 	cat /home/salaun/bin/bad.pl | perl -

Hi!

It could be bypassed this way. There are several ways of executing some
script:

1) /unsigned.sh (Already handled by IMA)
2) bash /unsigned.sh (Not handled. Works even with "-o noexec" mount)
3) bash < /unsigned.sh (Not handled. Works even with "-o noexec" mount)
4) cat /unsigned.sh | bash (Not handled. Works even with "-o noexec" mount)

AFAIK, the proposed syscall solves #2 and may be #3. As for #4 in security
critical environments there should be system-wide options to disable
interpreting scripts from the standard input. I suppose, executing commands
from the stdin is a rare case, and could be avoided entirely in security
critical environments. And yes, some help from the interpreters is needed
for that.

As for the usage of the system call, I have a proposal to extend its usage
to validate systemd unit files. Because a unit file could specify what UID
to use for a service, also it contains ExecStartPre which is actually a script
and is running as root (for the system session services).

For the syscall name it could be:
- trusted_file()
- trusted_file_content()
- valid_file()
- file_integrity()
because what we are checking here is the file content integrity (IMA) and
may be file permissions/attrs integrity (EVM).

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

* Re: [RFC PATCH v9 0/3] Add introspect_access(2) (was O_MAYEXEC)
  2020-09-10 18:40         ` Matthew Wilcox
  2020-09-10 20:00           ` Al Viro
@ 2020-09-12  0:28           ` James Morris
  2020-09-14 16:43             ` Mickaël Salaün
  1 sibling, 1 reply; 17+ messages in thread
From: James Morris @ 2020-09-12  0:28 UTC (permalink / raw)
  To: Matthew Wilcox
  Cc: Mickaël Salaün, Mimi Zohar, linux-kernel, Aleksa Sarai,
	Alexei Starovoitov, Al Viro, Andrew Morton, Andy Lutomirski,
	Arnd Bergmann, Casey Schaufler, Christian Brauner,
	Christian Heimes, Daniel Borkmann, Deven Bowers, Dmitry Vyukov,
	Eric Biggers, Eric Chiang, Florian Weimer, Jan Kara, Jann Horn,
	Jonathan Corbet, Kees Cook, Lakshmi Ramasubramanian,
	Matthew Garrett, Michael Kerrisk, Miklos Szeredi,
	Philippe Trébuchet, Scott Shell, Sean Christopherson,
	Shuah Khan, Steve Dower, Steve Grubb, Tetsuo Handa,
	Thibaut Sautereau, Vincent Strubel, kernel-hardening, linux-api,
	linux-integrity, linux-security-module, linux-fsdevel

[-- Attachment #1: Type: text/plain, Size: 872 bytes --]

On Thu, 10 Sep 2020, Matthew Wilcox wrote:

> On Thu, Sep 10, 2020 at 08:38:21PM +0200, Mickaël Salaün wrote:
> > There is also the use case of noexec mounts and file permissions. From
> > user space point of view, it doesn't matter which kernel component is in
> > charge of defining the policy. The syscall should then not be tied with
> > a verification/integrity/signature/appraisal vocabulary, but simply an
> > access control one.
> 
> permission()?
> 

The caller is not asking the kernel to grant permission, it's asking 
"SHOULD I access this file?"

The caller doesn't know, for example, if the script file it's about to 
execute has been signed, or if it's from a noexec mount. It's asking the 
kernel, which does know. (Note that this could also be extended to reading 
configuration files).

How about: should_faccessat ?

-- 
James Morris
<jmorris@namei.org>

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

* Re: [RFC PATCH v9 0/3] Add introspect_access(2) (was O_MAYEXEC)
  2020-09-12  0:28           ` James Morris
@ 2020-09-14 16:43             ` Mickaël Salaün
  0 siblings, 0 replies; 17+ messages in thread
From: Mickaël Salaün @ 2020-09-14 16:43 UTC (permalink / raw)
  To: Arnd Bergmann, Michael Kerrisk, linux-api
  Cc: James Morris, Matthew Wilcox, Mimi Zohar, linux-kernel,
	Aleksa Sarai, Alexei Starovoitov, Al Viro, Andrew Morton,
	Andy Lutomirski, Casey Schaufler, Christian Brauner,
	Christian Heimes, Daniel Borkmann, Deven Bowers, Dmitry Vyukov,
	Eric Biggers, Eric Chiang, Florian Weimer, Jan Kara, Jann Horn,
	Jonathan Corbet, Kees Cook, Lakshmi Ramasubramanian,
	Matthew Garrett, Miklos Szeredi, Philippe Trébuchet,
	Scott Shell, Sean Christopherson, Shuah Khan, Steve Dower,
	Steve Grubb, Tetsuo Handa, Thibaut Sautereau, Vincent Strubel,
	kernel-hardening, linux-integrity, linux-security-module,
	linux-fsdevel

Arnd and Michael,

What do you think of "should_faccessat" or "entrusted_faccessat" for
this new system call?


On 12/09/2020 02:28, James Morris wrote:
> On Thu, 10 Sep 2020, Matthew Wilcox wrote:
> 
>> On Thu, Sep 10, 2020 at 08:38:21PM +0200, Mickaël Salaün wrote:
>>> There is also the use case of noexec mounts and file permissions. From
>>> user space point of view, it doesn't matter which kernel component is in
>>> charge of defining the policy. The syscall should then not be tied with
>>> a verification/integrity/signature/appraisal vocabulary, but simply an
>>> access control one.
>>
>> permission()?
>>
> 
> The caller is not asking the kernel to grant permission, it's asking 
> "SHOULD I access this file?"
> 
> The caller doesn't know, for example, if the script file it's about to 
> execute has been signed, or if it's from a noexec mount. It's asking the 
> kernel, which does know. (Note that this could also be extended to reading 
> configuration files).
> 
> How about: should_faccessat ?
> 

Sounds good to me.

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

* Re: [RFC PATCH v9 2/3] arch: Wire up introspect_access(2)
  2020-09-10 16:46 ` [RFC PATCH v9 2/3] arch: Wire up introspect_access(2) Mickaël Salaün
@ 2020-09-15 13:32   ` Arnd Bergmann
  0 siblings, 0 replies; 17+ messages in thread
From: Arnd Bergmann @ 2020-09-15 13:32 UTC (permalink / raw)
  To: Mickaël Salaün
  Cc: linux-kernel, Aleksa Sarai, Alexei Starovoitov, Al Viro,
	Andrew Morton, Andy Lutomirski, Casey Schaufler,
	Christian Brauner, Christian Heimes, Daniel Borkmann,
	Deven Bowers, Dmitry Vyukov, Eric Biggers, Eric Chiang,
	Florian Weimer, James Morris, Jan Kara, Jann Horn,
	Jonathan Corbet, Kees Cook, Lakshmi Ramasubramanian,
	Matthew Garrett, Matthew Wilcox, Michael Kerrisk, Miklos Szeredi,
	Mimi Zohar, Philippe Trébuchet, Scott Shell,
	Sean Christopherson, Shuah Khan, Steve Dower, Steve Grubb,
	Tetsuo Handa, Thibaut Sautereau, Vincent Strubel,
	Kernel Hardening, Linux API, linux-integrity, LSM List,
	Linux FS-devel Mailing List, Mickaël Salaün,
	Thibaut Sautereau

On Thu, Sep 10, 2020 at 6:46 PM Mickaël Salaün <mic@digikod.net> wrote:
>
> From: Mickaël Salaün <mic@linux.microsoft.com>
>
> Wire up access_interpreted(2) for all architectures.
>
> Signed-off-by: Mickaël Salaün <mic@linux.microsoft.com>
> Reviewed-by: Thibaut Sautereau <thibaut.sautereau@ssi.gouv.fr>
> Cc: Al Viro <viro@zeniv.linux.org.uk>
> Cc: Andrew Morton <akpm@linux-foundation.org>
> Cc: Arnd Bergmann <arnd@arndb.de>
> Cc: Kees Cook <keescook@chromium.org>
> Cc: Vincent Strubel <vincent.strubel@ssi.gouv.fr>
> ---
>
> Changes since v7:
> * New patch for the new syscall.
> * Increase syscall numbers by 2 to leave space for new ones (in
>   linux-next): watch_mount(2) and process_madvise(2).

I checked that the syscall calling conventions are sane and that
it is wired up correctly on all architectures in this patch.

Acked-by: Arnd Bergmann <arnd@arndb.de>

I did not look at the system call implementation or its purpose though,
as that is not my area.

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

end of thread, other threads:[~2020-09-15 13:48 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-09-10 16:46 [RFC PATCH v9 0/3] Add introspect_access(2) (was O_MAYEXEC) Mickaël Salaün
2020-09-10 16:46 ` [RFC PATCH v9 1/3] fs: Add introspect_access(2) syscall implementation and related sysctl Mickaël Salaün
2020-09-10 16:46 ` [RFC PATCH v9 2/3] arch: Wire up introspect_access(2) Mickaël Salaün
2020-09-15 13:32   ` Arnd Bergmann
2020-09-10 16:46 ` [RFC PATCH v9 3/3] selftest/interpreter: Add tests for introspect_access(2) policies Mickaël Salaün
2020-09-10 17:04 ` [RFC PATCH v9 0/3] Add introspect_access(2) (was O_MAYEXEC) Matthew Wilcox
2020-09-10 17:21   ` Mickaël Salaün
2020-09-10 17:47     ` Mickaël Salaün
2020-09-10 18:08     ` Mimi Zohar
2020-09-10 18:38       ` Mickaël Salaün
2020-09-10 18:40         ` Matthew Wilcox
2020-09-10 20:00           ` Al Viro
2020-09-10 20:05             ` Matthew Wilcox
2020-09-11 12:16               ` Mickaël Salaün
2020-09-11 14:15               ` Igor Zhbanov
2020-09-12  0:28           ` James Morris
2020-09-14 16:43             ` Mickaël Salaün

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.