]> Pileus Git - ~andy/linux/blobdiff - security/selinux/ss/services.c
Merge git://git.infradead.org/users/eparis/audit
[~andy/linux] / security / selinux / ss / services.c
index f4dda05d7db0b96da73ddb9a6257d278cef03c8f..c93c21127f0cc5b6bc55c2930fdfe2441dc2a19c 100644 (file)
@@ -72,6 +72,7 @@
 
 int selinux_policycap_netpeer;
 int selinux_policycap_openperm;
+int selinux_policycap_alwaysnetwork;
 
 static DEFINE_RWLOCK(policy_rwlock);
 
@@ -1812,6 +1813,8 @@ static void security_load_policycaps(void)
                                                  POLICYDB_CAPABILITY_NETPEER);
        selinux_policycap_openperm = ebitmap_get_bit(&policydb.policycaps,
                                                  POLICYDB_CAPABILITY_OPENPERM);
+       selinux_policycap_alwaysnetwork = ebitmap_get_bit(&policydb.policycaps,
+                                                 POLICYDB_CAPABILITY_ALWAYSNETWORK);
 }
 
 static int security_preserve_bools(struct policydb *p);
@@ -1828,7 +1831,7 @@ static int security_preserve_bools(struct policydb *p);
  */
 int security_load_policy(void *data, size_t len)
 {
-       struct policydb oldpolicydb, newpolicydb;
+       struct policydb *oldpolicydb, *newpolicydb;
        struct sidtab oldsidtab, newsidtab;
        struct selinux_mapping *oldmap, *map = NULL;
        struct convert_context_args args;
@@ -1837,12 +1840,19 @@ int security_load_policy(void *data, size_t len)
        int rc = 0;
        struct policy_file file = { data, len }, *fp = &file;
 
+       oldpolicydb = kzalloc(2 * sizeof(*oldpolicydb), GFP_KERNEL);
+       if (!oldpolicydb) {
+               rc = -ENOMEM;
+               goto out;
+       }
+       newpolicydb = oldpolicydb + 1;
+
        if (!ss_initialized) {
                avtab_cache_init();
                rc = policydb_read(&policydb, fp);
                if (rc) {
                        avtab_cache_destroy();
-                       return rc;
+                       goto out;
                }
 
                policydb.len = len;
@@ -1852,14 +1862,14 @@ int security_load_policy(void *data, size_t len)
                if (rc) {
                        policydb_destroy(&policydb);
                        avtab_cache_destroy();
-                       return rc;
+                       goto out;
                }
 
                rc = policydb_load_isids(&policydb, &sidtab);
                if (rc) {
                        policydb_destroy(&policydb);
                        avtab_cache_destroy();
-                       return rc;
+                       goto out;
                }
 
                security_load_policycaps();
@@ -1871,36 +1881,36 @@ int security_load_policy(void *data, size_t len)
                selinux_status_update_policyload(seqno);
                selinux_netlbl_cache_invalidate();
                selinux_xfrm_notify_policyload();
-               return 0;
+               goto out;
        }
 
 #if 0
        sidtab_hash_eval(&sidtab, "sids");
 #endif
 
-       rc = policydb_read(&newpolicydb, fp);
+       rc = policydb_read(newpolicydb, fp);
        if (rc)
-               return rc;
+               goto out;
 
-       newpolicydb.len = len;
+       newpolicydb->len = len;
        /* If switching between different policy types, log MLS status */
-       if (policydb.mls_enabled && !newpolicydb.mls_enabled)
+       if (policydb.mls_enabled && !newpolicydb->mls_enabled)
                printk(KERN_INFO "SELinux: Disabling MLS support...\n");
-       else if (!policydb.mls_enabled && newpolicydb.mls_enabled)
+       else if (!policydb.mls_enabled && newpolicydb->mls_enabled)
                printk(KERN_INFO "SELinux: Enabling MLS support...\n");
 
-       rc = policydb_load_isids(&newpolicydb, &newsidtab);
+       rc = policydb_load_isids(newpolicydb, &newsidtab);
        if (rc) {
                printk(KERN_ERR "SELinux:  unable to load the initial SIDs\n");
-               policydb_destroy(&newpolicydb);
-               return rc;
+               policydb_destroy(newpolicydb);
+               goto out;
        }
 
-       rc = selinux_set_mapping(&newpolicydb, secclass_map, &map, &map_size);
+       rc = selinux_set_mapping(newpolicydb, secclass_map, &map, &map_size);
        if (rc)
                goto err;
 
-       rc = security_preserve_bools(&newpolicydb);
+       rc = security_preserve_bools(newpolicydb);
        if (rc) {
                printk(KERN_ERR "SELinux:  unable to preserve booleans\n");
                goto err;
@@ -1918,7 +1928,7 @@ int security_load_policy(void *data, size_t len)
         * in the new SID table.
         */
        args.oldp = &policydb;
-       args.newp = &newpolicydb;
+       args.newp = newpolicydb;
        rc = sidtab_map(&newsidtab, convert_context, &args);
        if (rc) {
                printk(KERN_ERR "SELinux:  unable to convert the internal"
@@ -1928,12 +1938,12 @@ int security_load_policy(void *data, size_t len)
        }
 
        /* Save the old policydb and SID table to free later. */
-       memcpy(&oldpolicydb, &policydb, sizeof policydb);
+       memcpy(oldpolicydb, &policydb, sizeof(policydb));
        sidtab_set(&oldsidtab, &sidtab);
 
        /* Install the new policydb and SID table. */
        write_lock_irq(&policy_rwlock);
-       memcpy(&policydb, &newpolicydb, sizeof policydb);
+       memcpy(&policydb, newpolicydb, sizeof(policydb));
        sidtab_set(&sidtab, &newsidtab);
        security_load_policycaps();
        oldmap = current_mapping;
@@ -1943,7 +1953,7 @@ int security_load_policy(void *data, size_t len)
        write_unlock_irq(&policy_rwlock);
 
        /* Free the old policydb and SID table. */
-       policydb_destroy(&oldpolicydb);
+       policydb_destroy(oldpolicydb);
        sidtab_destroy(&oldsidtab);
        kfree(oldmap);
 
@@ -1953,14 +1963,17 @@ int security_load_policy(void *data, size_t len)
        selinux_netlbl_cache_invalidate();
        selinux_xfrm_notify_policyload();
 
-       return 0;
+       rc = 0;
+       goto out;
 
 err:
        kfree(map);
        sidtab_destroy(&newsidtab);
-       policydb_destroy(&newpolicydb);
-       return rc;
+       policydb_destroy(newpolicydb);
 
+out:
+       kfree(oldpolicydb);
+       return rc;
 }
 
 size_t security_policydb_len(void)
@@ -2323,17 +2336,14 @@ out:
 
 /**
  * security_fs_use - Determine how to handle labeling for a filesystem.
- * @fstype: filesystem type
- * @behavior: labeling behavior
- * @sid: SID for filesystem (superblock)
+ * @sb: superblock in question
  */
-int security_fs_use(
-       const char *fstype,
-       unsigned int *behavior,
-       u32 *sid)
+int security_fs_use(struct super_block *sb)
 {
        int rc = 0;
        struct ocontext *c;
+       struct superblock_security_struct *sbsec = sb->s_security;
+       const char *fstype = sb->s_type->name;
 
        read_lock(&policy_rwlock);
 
@@ -2345,21 +2355,21 @@ int security_fs_use(
        }
 
        if (c) {
-               *behavior = c->v.behavior;
+               sbsec->behavior = c->v.behavior;
                if (!c->sid[0]) {
                        rc = sidtab_context_to_sid(&sidtab, &c->context[0],
                                                   &c->sid[0]);
                        if (rc)
                                goto out;
                }
-               *sid = c->sid[0];
+               sbsec->sid = c->sid[0];
        } else {
-               rc = security_genfs_sid(fstype, "/", SECCLASS_DIR, sid);
+               rc = security_genfs_sid(fstype, "/", SECCLASS_DIR, &sbsec->sid);
                if (rc) {
-                       *behavior = SECURITY_FS_USE_NONE;
+                       sbsec->behavior = SECURITY_FS_USE_NONE;
                        rc = 0;
                } else {
-                       *behavior = SECURITY_FS_USE_GENFS;
+                       sbsec->behavior = SECURITY_FS_USE_GENFS;
                }
        }