lkml.org 
[lkml]   [2019]   [Nov]   [22]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.4 104/159] apparmor: fix module parameters can be changed after policy is locked
    Date
    From: John Johansen <john.johansen@canonical.com>

    commit 58acf9d911c8831156634a44d0b022d683e1e50c upstream.

    the policy_lock parameter is a one way switch that prevents policy
    from being further modified. Unfortunately some of the module parameters
    can effectively modify policy by turning off enforcement.

    split policy_admin_capable into a view check and a full admin check,
    and update the admin check to test the policy_lock parameter.

    Signed-off-by: John Johansen <john.johansen@canonical.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    security/apparmor/include/policy.h | 2 ++
    security/apparmor/lsm.c | 22 ++++++++++------------
    security/apparmor/policy.c | 18 +++++++++++++++++-
    3 files changed, 29 insertions(+), 13 deletions(-)

    --- a/security/apparmor/include/policy.h
    +++ b/security/apparmor/include/policy.h
    @@ -403,6 +403,8 @@ static inline int AUDIT_MODE(struct aa_p
    return profile->audit;
    }

    +bool policy_view_capable(void);
    +bool policy_admin_capable(void);
    bool aa_may_manage_policy(int op);

    #endif /* __AA_POLICY_H */
    --- a/security/apparmor/lsm.c
    +++ b/security/apparmor/lsm.c
    @@ -749,51 +749,49 @@ __setup("apparmor=", apparmor_enabled_se
    /* set global flag turning off the ability to load policy */
    static int param_set_aalockpolicy(const char *val, const struct kernel_param *kp)
    {
    - if (!capable(CAP_MAC_ADMIN))
    + if (!policy_admin_capable())
    return -EPERM;
    - if (aa_g_lock_policy)
    - return -EACCES;
    return param_set_bool(val, kp);
    }

    static int param_get_aalockpolicy(char *buffer, const struct kernel_param *kp)
    {
    - if (!capable(CAP_MAC_ADMIN))
    + if (!policy_view_capable())
    return -EPERM;
    return param_get_bool(buffer, kp);
    }

    static int param_set_aabool(const char *val, const struct kernel_param *kp)
    {
    - if (!capable(CAP_MAC_ADMIN))
    + if (!policy_admin_capable())
    return -EPERM;
    return param_set_bool(val, kp);
    }

    static int param_get_aabool(char *buffer, const struct kernel_param *kp)
    {
    - if (!capable(CAP_MAC_ADMIN))
    + if (!policy_view_capable())
    return -EPERM;
    return param_get_bool(buffer, kp);
    }

    static int param_set_aauint(const char *val, const struct kernel_param *kp)
    {
    - if (!capable(CAP_MAC_ADMIN))
    + if (!policy_admin_capable())
    return -EPERM;
    return param_set_uint(val, kp);
    }

    static int param_get_aauint(char *buffer, const struct kernel_param *kp)
    {
    - if (!capable(CAP_MAC_ADMIN))
    + if (!policy_view_capable())
    return -EPERM;
    return param_get_uint(buffer, kp);
    }

    static int param_get_audit(char *buffer, struct kernel_param *kp)
    {
    - if (!capable(CAP_MAC_ADMIN))
    + if (!policy_view_capable())
    return -EPERM;

    if (!apparmor_enabled)
    @@ -805,7 +803,7 @@ static int param_get_audit(char *buffer,
    static int param_set_audit(const char *val, struct kernel_param *kp)
    {
    int i;
    - if (!capable(CAP_MAC_ADMIN))
    + if (!policy_admin_capable())
    return -EPERM;

    if (!apparmor_enabled)
    @@ -826,7 +824,7 @@ static int param_set_audit(const char *v

    static int param_get_mode(char *buffer, struct kernel_param *kp)
    {
    - if (!capable(CAP_MAC_ADMIN))
    + if (!policy_admin_capable())
    return -EPERM;

    if (!apparmor_enabled)
    @@ -838,7 +836,7 @@ static int param_get_mode(char *buffer,
    static int param_set_mode(const char *val, struct kernel_param *kp)
    {
    int i;
    - if (!capable(CAP_MAC_ADMIN))
    + if (!policy_admin_capable())
    return -EPERM;

    if (!apparmor_enabled)
    --- a/security/apparmor/policy.c
    +++ b/security/apparmor/policy.c
    @@ -916,6 +916,22 @@ static int audit_policy(int op, gfp_t gf
    &sa, NULL);
    }

    +bool policy_view_capable(void)
    +{
    + struct user_namespace *user_ns = current_user_ns();
    + bool response = false;
    +
    + if (ns_capable(user_ns, CAP_MAC_ADMIN))
    + response = true;
    +
    + return response;
    +}
    +
    +bool policy_admin_capable(void)
    +{
    + return policy_view_capable() && !aa_g_lock_policy;
    +}
    +
    /**
    * aa_may_manage_policy - can the current task manage policy
    * @op: the policy manipulation operation being done
    @@ -930,7 +946,7 @@ bool aa_may_manage_policy(int op)
    return 0;
    }

    - if (!capable(CAP_MAC_ADMIN)) {
    + if (!policy_admin_capable()) {
    audit_policy(op, GFP_KERNEL, NULL, "not policy admin", -EACCES);
    return 0;
    }

    \
     
     \ /
      Last update: 2019-11-22 11:36    [W:4.137 / U:0.048 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site