SELinux: rename filename_compute_type argument to *type instead of *con
[pandora-kernel.git] / security / selinux / ss / services.c
index a03cfaf..78bb810 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 SECCLASS_NULL;
+}
+
 static void map_decision(u16 tclass, struct av_decision *avd,
                         int allow_unknown)
 {
@@ -1343,10 +1358,27 @@ out:
        return -EACCES;
 }
 
+static void filename_compute_type(struct policydb *p, struct context *newcontext,
+                                 u32 stype, u32 ttype, u16 tclass,
+                                 const char *objname)
+{
+       struct filename_trans *ft;
+       for (ft = p->filename_trans; ft; ft = ft->next) {
+               if (ft->stype == stype &&
+                   ft->ttype == ttype &&
+                   ft->tclass == tclass &&
+                   !strcmp(ft->name, objname)) {
+                       newcontext->type = ft->otype;
+                       return;
+               }
+       }
+}
+
 static int security_compute_sid(u32 ssid,
                                u32 tsid,
                                u16 orig_tclass,
                                u32 specified,
+                               const char *objname,
                                u32 *out_sid,
                                bool kern)
 {
@@ -1357,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) {
@@ -1374,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) {
@@ -1408,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;
@@ -1442,25 +1478,29 @@ static int security_compute_sid(u32 ssid,
                newcontext.type = avdatum->data;
        }
 
+       /* if we have a objname this is a file trans check so check those rules */
+       if (objname)
+               filename_compute_type(&policydb, &newcontext, scontext->type,
+                                     tcontext->type, tclass, objname);
+
        /* Check for class-specific changes. */
-       if  (tclass == policydb.process_class) {
-               if (specified & AVTAB_TRANSITION) {
-                       /* Look for a role transition rule. */
-                       for (roletr = policydb.role_tr; roletr;
-                            roletr = roletr->next) {
-                               if (roletr->role == scontext->role &&
-                                   roletr->type == tcontext->type) {
-                                       /* Use the role transition rule. */
-                                       newcontext.role = roletr->new_role;
-                                       break;
-                               }
+       if (specified & AVTAB_TRANSITION) {
+               /* Look for a role transition rule. */
+               for (roletr = policydb.role_tr; roletr; roletr = roletr->next) {
+                       if ((roletr->role == scontext->role) &&
+                           (roletr->type == tcontext->type) &&
+                           (roletr->tclass == tclass)) {
+                               /* Use the role transition rule. */
+                               newcontext.role = roletr->new_role;
+                               break;
                        }
                }
        }
 
        /* 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;
 
@@ -1495,22 +1535,18 @@ out:
  * if insufficient memory is available, or %0 if the new SID was
  * computed successfully.
  */
-int security_transition_sid(u32 ssid,
-                           u32 tsid,
-                           u16 tclass,
-                           u32 *out_sid)
+int security_transition_sid(u32 ssid, u32 tsid, u16 tclass,
+                           const struct qstr *qstr, u32 *out_sid)
 {
        return security_compute_sid(ssid, tsid, tclass, AVTAB_TRANSITION,
-                                   out_sid, true);
+                                   qstr ? qstr->name : NULL, out_sid, true);
 }
 
-int security_transition_sid_user(u32 ssid,
-                                u32 tsid,
-                                u16 tclass,
-                                u32 *out_sid)
+int security_transition_sid_user(u32 ssid, u32 tsid, u16 tclass,
+                                const char *objname, u32 *out_sid)
 {
        return security_compute_sid(ssid, tsid, tclass, AVTAB_TRANSITION,
-                                   out_sid, false);
+                                   objname, out_sid, false);
 }
 
 /**
@@ -1531,8 +1567,8 @@ int security_member_sid(u32 ssid,
                        u16 tclass,
                        u32 *out_sid)
 {
-       return security_compute_sid(ssid, tsid, tclass, AVTAB_MEMBER, out_sid,
-                                   false);
+       return security_compute_sid(ssid, tsid, tclass, AVTAB_MEMBER, NULL,
+                                   out_sid, false);
 }
 
 /**
@@ -1553,8 +1589,8 @@ int security_change_sid(u32 ssid,
                        u16 tclass,
                        u32 *out_sid)
 {
-       return security_compute_sid(ssid, tsid, tclass, AVTAB_CHANGE, out_sid,
-                                   false);
+       return security_compute_sid(ssid, tsid, tclass, AVTAB_CHANGE, NULL,
+                                   out_sid, false);
 }
 
 /* Clone the SID into the new SID table. */
@@ -3153,7 +3189,7 @@ out:
  * @len: length of data in bytes
  *
  */
-int security_read_policy(void **data, ssize_t *len)
+int security_read_policy(void **data, size_t *len)
 {
        int rc;
        struct policy_file fp;