selinux: preserve boolean values across policy reloads
authorStephen Smalley <sds@tycho.nsa.gov>
Thu, 19 Apr 2007 18:16:19 +0000 (14:16 -0400)
committerJames Morris <jmorris@namei.org>
Thu, 26 Apr 2007 05:36:13 +0000 (01:36 -0400)
At present, the userland policy loading code has to go through contortions to preserve
boolean values across policy reloads, and cannot do so atomically.
As this is what we always want to do for reloads, let the kernel preserve them instead.

Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov>
Acked-by: Karl MacMillan <kmacmillan@mentalrootkit.com>
Signed-off-by: James Morris <jmorris@namei.org>
security/selinux/ss/services.c

index 21b8318979e37597d02918b378852b3bc9edbb6b..40660ffd49b64947c31ab32c617a316f407258d3 100644 (file)
@@ -1257,6 +1257,7 @@ bad:
 }
 
 extern void selinux_complete_init(void);
+static int security_preserve_bools(struct policydb *p);
 
 /**
  * security_load_policy - Load a security policy configuration.
@@ -1333,6 +1334,12 @@ int security_load_policy(void *data, size_t len)
                goto err;
        }
 
+       rc = security_preserve_bools(&newpolicydb);
+       if (rc) {
+               printk(KERN_ERR "security:  unable to preserve booleans\n");
+               goto err;
+       }
+
        /* Clone the SID table. */
        sidtab_shutdown(&sidtab);
        if (sidtab_map(&sidtab, clone_sid, &newsidtab)) {
@@ -1890,6 +1897,37 @@ out:
        return rc;
 }
 
+static int security_preserve_bools(struct policydb *p)
+{
+       int rc, nbools = 0, *bvalues = NULL, i;
+       char **bnames = NULL;
+       struct cond_bool_datum *booldatum;
+       struct cond_node *cur;
+
+       rc = security_get_bools(&nbools, &bnames, &bvalues);
+       if (rc)
+               goto out;
+       for (i = 0; i < nbools; i++) {
+               booldatum = hashtab_search(p->p_bools.table, bnames[i]);
+               if (booldatum)
+                       booldatum->state = bvalues[i];
+       }
+       for (cur = p->cond_list; cur != NULL; cur = cur->next) {
+               rc = evaluate_cond_node(p, cur);
+               if (rc)
+                       goto out;
+       }
+
+out:
+       if (bnames) {
+               for (i = 0; i < nbools; i++)
+                       kfree(bnames[i]);
+       }
+       kfree(bnames);
+       kfree(bvalues);
+       return rc;
+}
+
 /*
  * security_sid_mls_copy() - computes a new sid based on the given
  * sid and the mls portion of mls_sid.