lkml.org 
[lkml]   [2020]   [Apr]   [28]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v3 1/5] fs: Add support for a RESOLVE_MAYEXEC flag on openat2(2)
    Date
    When the RESOLVE_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.

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

    A simple security policy implementation, configured through a dedicated
    sysctl, is available in a following patch.

    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 11 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

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

    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).
    ---
    fs/open.c | 6 ++++++
    include/linux/fcntl.h | 2 +-
    include/linux/fs.h | 2 ++
    include/uapi/linux/openat2.h | 6 ++++++
    4 files changed, 15 insertions(+), 1 deletion(-)

    diff --git a/fs/open.c b/fs/open.c
    index 719b320ede52..ca5a145761a2 100644
    --- a/fs/open.c
    +++ b/fs/open.c
    @@ -1029,6 +1029,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 (how->resolve & RESOLVE_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..a37e213220ad 100644
    --- a/include/linux/fcntl.h
    +++ b/include/linux/fcntl.h
    @@ -19,7 +19,7 @@
    /* List of all valid flags for the how->resolve argument: */
    #define VALID_RESOLVE_FLAGS \
    (RESOLVE_NO_XDEV | RESOLVE_NO_MAGICLINKS | RESOLVE_NO_SYMLINKS | \
    - RESOLVE_BENEATH | RESOLVE_IN_ROOT)
    + RESOLVE_BENEATH | RESOLVE_IN_ROOT | RESOLVE_MAYEXEC)

    /* List of all open_how "versions". */
    #define OPEN_HOW_SIZE_VER0 24 /* sizeof first published struct */
    diff --git a/include/linux/fs.h b/include/linux/fs.h
    index 4f6f59b4f22a..f5be4be7c01d 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 RESOLVE_MAYEXEC */
    +#define MAY_OPENEXEC 0x00000100

    /*
    * flags in file.f_mode. Note that FMODE_READ and FMODE_WRITE must correspond
    diff --git a/include/uapi/linux/openat2.h b/include/uapi/linux/openat2.h
    index 58b1eb711360..86ed0a2321c3 100644
    --- a/include/uapi/linux/openat2.h
    +++ b/include/uapi/linux/openat2.h
    @@ -35,5 +35,11 @@ struct open_how {
    #define RESOLVE_IN_ROOT 0x10 /* Make all jumps to "/" and ".."
    be scoped inside the dirfd
    (similar to chroot(2)). */
    +#define RESOLVE_MAYEXEC 0x20 /* Code execution from the target file is
    + intended, checks such permission. A
    + simple policy can be enforced
    + system-wide as explained in
    + Documentation/admin-guide/sysctl/fs.rst
    + */

    #endif /* _UAPI_LINUX_OPENAT2_H */
    --
    2.26.2
    \
     
     \ /
      Last update: 2020-04-28 19:52    [W:4.304 / U:25.708 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site