]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/commitdiff
apparmor: add ns being viewed as a param to policy_view_capable()
authorJohn Johansen <john.johansen@canonical.com>
Mon, 16 Jan 2017 08:42:50 +0000 (00:42 -0800)
committerJohn Johansen <john.johansen@canonical.com>
Mon, 16 Jan 2017 09:18:39 +0000 (01:18 -0800)
Prepare for a tighter pairing of user namespaces and apparmor policy
namespaces, by making the ns to be viewed available and checking
that the user namespace level is the same as the policy ns level.

This strict pairing will be relaxed once true support of user namespaces
lands.

Signed-off-by: John Johansen <john.johansen@canonical.com>
security/apparmor/include/context.h
security/apparmor/include/policy.h
security/apparmor/lsm.c
security/apparmor/policy.c

index a0acc2390faea2d74a17392a6215d74043e4a66e..d378bff47ccd87ed01729a4c97abe1c54c4c2c01 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/sched.h>
 
 #include "policy.h"
+#include "policy_ns.h"
 
 #define cred_cxt(X) (X)->security
 #define current_cxt() cred_cxt(current_cred())
@@ -162,6 +163,11 @@ static inline struct aa_profile *aa_current_profile(void)
        return cxt->profile;
 }
 
+static inline struct aa_ns *aa_get_current_ns(void)
+{
+       return aa_get_ns(__aa_current_profile()->ns);
+}
+
 /**
  * aa_clear_task_cxt_trans - clear transition tracking info from the cxt
  * @cxt: task context to clear (NOT NULL)
index 8fcfb3c78d213449b8ad58020231f727ceb9c6e5..b0b65c525bcc189ccb775639ab20cdc271694395 100644 (file)
@@ -33,6 +33,8 @@
 
 struct aa_ns;
 
+extern int unprivileged_userns_apparmor_policy;
+
 extern const char *const aa_profile_mode_names[];
 #define APPARMOR_MODE_NAMES_MAX_INDEX 4
 
@@ -297,7 +299,7 @@ static inline int AUDIT_MODE(struct aa_profile *profile)
        return profile->audit;
 }
 
-bool policy_view_capable(void);
+bool policy_view_capable(struct aa_ns *ns);
 bool policy_admin_capable(void);
 bool aa_may_manage_policy(int op);
 
index f852cd626f2e48ea396c48b530f36db9665f2a5c..f83ba33651a0350f07afdb1992002faa711241e9 100644 (file)
@@ -745,7 +745,7 @@ static int param_set_aalockpolicy(const char *val, const struct kernel_param *kp
 
 static int param_get_aalockpolicy(char *buffer, const struct kernel_param *kp)
 {
-       if (!policy_view_capable())
+       if (!policy_view_capable(NULL))
                return -EPERM;
        return param_get_bool(buffer, kp);
 }
@@ -759,7 +759,7 @@ static int param_set_aabool(const char *val, const struct kernel_param *kp)
 
 static int param_get_aabool(char *buffer, const struct kernel_param *kp)
 {
-       if (!policy_view_capable())
+       if (!policy_view_capable(NULL))
                return -EPERM;
        return param_get_bool(buffer, kp);
 }
@@ -773,14 +773,14 @@ static int param_set_aauint(const char *val, const struct kernel_param *kp)
 
 static int param_get_aauint(char *buffer, const struct kernel_param *kp)
 {
-       if (!policy_view_capable())
+       if (!policy_view_capable(NULL))
                return -EPERM;
        return param_get_uint(buffer, kp);
 }
 
 static int param_get_audit(char *buffer, struct kernel_param *kp)
 {
-       if (!policy_view_capable())
+       if (!policy_view_capable(NULL))
                return -EPERM;
 
        if (!apparmor_enabled)
index 0125de6061fddf3c5560f485381b84aa19db949f..f092c04c7c4e7dc8b29930abde6bc155f6b735e3 100644 (file)
@@ -76,6 +76,7 @@
 #include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/string.h>
+#include <linux/user_namespace.h>
 
 #include "include/apparmor.h"
 #include "include/capability.h"
@@ -89,6 +90,7 @@
 #include "include/policy_unpack.h"
 #include "include/resource.h"
 
+int unprivileged_userns_apparmor_policy = 1;
 
 const char *const aa_profile_mode_names[] = {
        "enforce",
@@ -607,20 +609,37 @@ static int audit_policy(struct aa_profile *profile, int op, gfp_t gfp,
                        &sa, NULL);
 }
 
-bool policy_view_capable(void)
+/**
+ * policy_view_capable - check if viewing policy in at @ns is allowed
+ * ns: namespace being viewed by current task (may be NULL)
+ * Returns: true if viewing policy is allowed
+ *
+ * If @ns is NULL then the namespace being viewed is assumed to be the
+ * tasks current namespace.
+ */
+bool policy_view_capable(struct aa_ns *ns)
 {
        struct user_namespace *user_ns = current_user_ns();
+       struct aa_ns *view_ns = aa_get_current_ns();
+       bool root_in_user_ns = uid_eq(current_euid(), make_kuid(user_ns, 0)) ||
+                              in_egroup_p(make_kgid(user_ns, 0));
        bool response = false;
+       if (!ns)
+               ns = view_ns;
 
-       if (ns_capable(user_ns, CAP_MAC_ADMIN))
+       if (root_in_user_ns && aa_ns_visible(view_ns, ns, true) &&
+           (user_ns == &init_user_ns ||
+            (unprivileged_userns_apparmor_policy != 0 &&
+             user_ns->level == view_ns->level)))
                response = true;
+       aa_put_ns(view_ns);
 
        return response;
 }
 
 bool policy_admin_capable(void)
 {
-       return policy_view_capable() && !aa_g_lock_policy;
+       return policy_view_capable(NULL) && !aa_g_lock_policy;
 }
 
 /**