SELinux: Socket retains creator role and MLS attribute
Harry Ciao [Wed, 2 Mar 2011 05:32:33 +0000 (13:32 +0800)]
The socket SID would be computed on creation and no longer inherit
its creator's SID by default. Socket may have a different type but
needs to retain the creator's role and MLS attribute in order not
to break labeled networking and network access control.

The kernel value for a class would be used to determine if the class
if one of socket classes. If security_compute_sid is called from
userspace the policy value for a class would be mapped to the relevant
kernel value first.

Signed-off-by: Harry Ciao <qingtao.cao@windriver.com>
Signed-off-by: Eric Paris <eparis@redhat.com>
Acked-by: Stephen Smalley <sds@tycho.nsa.gov>

security/selinux/ss/mls.c
security/selinux/ss/mls.h
security/selinux/ss/services.c

index 1ef8e4e..e961742 100644 (file)
@@ -512,7 +512,8 @@ int mls_compute_sid(struct context *scontext,
                    struct context *tcontext,
                    u16 tclass,
                    u32 specified,
-                   struct context *newcontext)
+                   struct context *newcontext,
+                   bool sock)
 {
        struct range_trans rtr;
        struct mls_range *r;
@@ -531,7 +532,7 @@ int mls_compute_sid(struct context *scontext,
                        return mls_range_set(newcontext, r);
                /* Fallthrough */
        case AVTAB_CHANGE:
-               if (tclass == policydb.process_class)
+               if ((tclass == policydb.process_class) || (sock == true))
                        /* Use the process MLS attributes. */
                        return mls_context_cpy(newcontext, scontext);
                else
index cd91526..037bf9d 100644 (file)
@@ -49,7 +49,8 @@ int mls_compute_sid(struct context *scontext,
                    struct context *tcontext,
                    u16 tclass,
                    u32 specified,
-                   struct context *newcontext);
+                   struct context *newcontext,
+                   bool sock);
 
 int mls_setup_user_range(struct context *fromcon, struct user_datum *user,
                         struct context *usercon);
index 2e36e03..3e7544d 100644 (file)
@@ -201,6 +201,21 @@ static u16 unmap_class(u16 tclass)
        return tclass;
 }
 
+/*
+ * Get kernel value for class from its policy value
+ */
+static u16 map_class(u16 pol_value)
+{
+       u16 i;
+
+       for (i = 1; i < current_mapping_size; i++) {
+               if (current_mapping[i].value == pol_value)
+                       return i;
+       }
+
+       return pol_value;
+}
+
 static void map_decision(u16 tclass, struct av_decision *avd,
                         int allow_unknown)
 {
@@ -1374,6 +1389,7 @@ static int security_compute_sid(u32 ssid,
        struct avtab_node *node;
        u16 tclass;
        int rc = 0;
+       bool sock;
 
        if (!ss_initialized) {
                switch (orig_tclass) {
@@ -1391,10 +1407,13 @@ static int security_compute_sid(u32 ssid,
 
        read_lock(&policy_rwlock);
 
-       if (kern)
+       if (kern) {
                tclass = unmap_class(orig_tclass);
-       else
+               sock = security_is_socket_class(orig_tclass);
+       } else {
                tclass = orig_tclass;
+               sock = security_is_socket_class(map_class(tclass));
+       }
 
        scontext = sidtab_search(&sidtab, ssid);
        if (!scontext) {
@@ -1425,7 +1444,7 @@ static int security_compute_sid(u32 ssid,
        }
 
        /* Set the role and type to default values. */
-       if (tclass == policydb.process_class) {
+       if ((tclass == policydb.process_class) || (sock == true)) {
                /* Use the current role and type of process. */
                newcontext.role = scontext->role;
                newcontext.type = scontext->type;
@@ -1482,7 +1501,8 @@ static int security_compute_sid(u32 ssid,
 
        /* Set the MLS attributes.
           This is done last because it may allocate memory. */
-       rc = mls_compute_sid(scontext, tcontext, tclass, specified, &newcontext);
+       rc = mls_compute_sid(scontext, tcontext, tclass, specified,
+                            &newcontext, sock);
        if (rc)
                goto out_unlock;