lkml.org 
[lkml]   [2016]   [Sep]   [12]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.4 144/192] kernel: Add noaudit variant of ns_capable()
    Date
    4.4-stable review patch.  If anyone has any objections, please let me know.

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

    From: Tyler Hicks <tyhicks@canonical.com>

    commit 98f368e9e2630a3ce3e80fb10fb2e02038cf9578 upstream.

    When checking the current cred for a capability in a specific user
    namespace, it isn't always desirable to have the LSMs audit the check.
    This patch adds a noaudit variant of ns_capable() for when those
    situations arise.

    The common logic between ns_capable() and the new ns_capable_noaudit()
    is moved into a single, shared function to keep duplicated code to a
    minimum and ease maintainability.

    Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
    Acked-by: Serge E. Hallyn <serge.hallyn@ubuntu.com>
    Signed-off-by: James Morris <james.l.morris@oracle.com>
    Signed-off-by: Sasha Levin <alexander.levin@verizon.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    include/linux/capability.h | 5 ++++
    kernel/capability.c | 46 +++++++++++++++++++++++++++++++++++----------
    2 files changed, 41 insertions(+), 10 deletions(-)

    --- a/include/linux/capability.h
    +++ b/include/linux/capability.h
    @@ -214,6 +214,7 @@ extern bool has_ns_capability_noaudit(st
    struct user_namespace *ns, int cap);
    extern bool capable(int cap);
    extern bool ns_capable(struct user_namespace *ns, int cap);
    +extern bool ns_capable_noaudit(struct user_namespace *ns, int cap);
    #else
    static inline bool has_capability(struct task_struct *t, int cap)
    {
    @@ -241,6 +242,10 @@ static inline bool ns_capable(struct use
    {
    return true;
    }
    +static inline bool ns_capable_noaudit(struct user_namespace *ns, int cap)
    +{
    + return true;
    +}
    #endif /* CONFIG_MULTIUSER */
    extern bool capable_wrt_inode_uidgid(const struct inode *inode, int cap);
    extern bool file_ns_capable(const struct file *file, struct user_namespace *ns, int cap);
    --- a/kernel/capability.c
    +++ b/kernel/capability.c
    @@ -361,6 +361,24 @@ bool has_capability_noaudit(struct task_
    return has_ns_capability_noaudit(t, &init_user_ns, cap);
    }

    +static bool ns_capable_common(struct user_namespace *ns, int cap, bool audit)
    +{
    + int capable;
    +
    + if (unlikely(!cap_valid(cap))) {
    + pr_crit("capable() called with invalid cap=%u\n", cap);
    + BUG();
    + }
    +
    + capable = audit ? security_capable(current_cred(), ns, cap) :
    + security_capable_noaudit(current_cred(), ns, cap);
    + if (capable == 0) {
    + current->flags |= PF_SUPERPRIV;
    + return true;
    + }
    + return false;
    +}
    +
    /**
    * ns_capable - Determine if the current task has a superior capability in effect
    * @ns: The usernamespace we want the capability in
    @@ -374,19 +392,27 @@ bool has_capability_noaudit(struct task_
    */
    bool ns_capable(struct user_namespace *ns, int cap)
    {
    - if (unlikely(!cap_valid(cap))) {
    - pr_crit("capable() called with invalid cap=%u\n", cap);
    - BUG();
    - }
    -
    - if (security_capable(current_cred(), ns, cap) == 0) {
    - current->flags |= PF_SUPERPRIV;
    - return true;
    - }
    - return false;
    + return ns_capable_common(ns, cap, true);
    }
    EXPORT_SYMBOL(ns_capable);

    +/**
    + * ns_capable_noaudit - Determine if the current task has a superior capability
    + * (unaudited) in effect
    + * @ns: The usernamespace we want the capability in
    + * @cap: The capability to be tested for
    + *
    + * Return true if the current task has the given superior capability currently
    + * available for use, false if not.
    + *
    + * This sets PF_SUPERPRIV on the task if the capability is available on the
    + * assumption that it's about to be used.
    + */
    +bool ns_capable_noaudit(struct user_namespace *ns, int cap)
    +{
    + return ns_capable_common(ns, cap, false);
    +}
    +EXPORT_SYMBOL(ns_capable_noaudit);

    /**
    * capable - Determine if the current task has a superior capability in effect

    \
     
     \ /
      Last update: 2016-09-17 09:59    [W:4.744 / U:0.080 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site