lkml.org 
[lkml]   [2018]   [Sep]   [7]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.9 48/63] userns: move user access out of the mutex
    Date
    4.9-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Jann Horn <jannh@google.com>

    commit 5820f140edef111a9ea2ef414ab2428b8cb805b1 upstream.

    The old code would hold the userns_state_mutex indefinitely if
    memdup_user_nul stalled due to e.g. a userfault region. Prevent that by
    moving the memdup_user_nul in front of the mutex_lock().

    Note: This changes the error precedence of invalid buf/count/*ppos vs
    map already written / capabilities missing.

    Fixes: 22d917d80e84 ("userns: Rework the user_namespace adding uid/gid...")
    Cc: stable@vger.kernel.org
    Signed-off-by: Jann Horn <jannh@google.com>
    Acked-by: Christian Brauner <christian@brauner.io>
    Acked-by: Serge Hallyn <serge@hallyn.com>
    Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    kernel/user_namespace.c | 24 ++++++++++--------------
    1 file changed, 10 insertions(+), 14 deletions(-)

    --- a/kernel/user_namespace.c
    +++ b/kernel/user_namespace.c
    @@ -649,7 +649,16 @@ static ssize_t map_write(struct file *fi
    unsigned idx;
    struct uid_gid_extent *extent = NULL;
    char *kbuf = NULL, *pos, *next_line;
    - ssize_t ret = -EINVAL;
    + ssize_t ret;
    +
    + /* Only allow < page size writes at the beginning of the file */
    + if ((*ppos != 0) || (count >= PAGE_SIZE))
    + return -EINVAL;
    +
    + /* Slurp in the user data */
    + kbuf = memdup_user_nul(buf, count);
    + if (IS_ERR(kbuf))
    + return PTR_ERR(kbuf);

    /*
    * The userns_state_mutex serializes all writes to any given map.
    @@ -683,19 +692,6 @@ static ssize_t map_write(struct file *fi
    if (cap_valid(cap_setid) && !file_ns_capable(file, ns, CAP_SYS_ADMIN))
    goto out;

    - /* Only allow < page size writes at the beginning of the file */
    - ret = -EINVAL;
    - if ((*ppos != 0) || (count >= PAGE_SIZE))
    - goto out;
    -
    - /* Slurp in the user data */
    - kbuf = memdup_user_nul(buf, count);
    - if (IS_ERR(kbuf)) {
    - ret = PTR_ERR(kbuf);
    - kbuf = NULL;
    - goto out;
    - }
    -
    /* Parse the user data */
    ret = -EINVAL;
    pos = kbuf;

    \
     
     \ /
      Last update: 2018-09-07 23:37    [W:5.951 / U:0.036 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site