---
 include/selinux/selinux.h |    6 ++
 src/android.c             |    4 +
 src/booleans.c            |  183 +++++++++++++++++++++++++++++++++++++++++++--
 src/selinux_internal.h    |    2 +
 4 files changed, 187 insertions(+), 8 deletions(-)

diff --git a/include/selinux/selinux.h b/include/selinux/selinux.h
index c7c2571..c8690f4 100644
--- a/include/selinux/selinux.h
+++ b/include/selinux/selinux.h
@@ -244,6 +244,12 @@ extern int security_get_boolean_active(const char *name);
 /* Set the pending value for the boolean */
 extern int security_set_boolean(const char *name, int value);
 
+/* Set the pending value for the permanent boolean */
+extern int security_set_permanent_boolean(const char *name, int value);
+
+/* reload permanent booleans */
+extern int security_reload_permanent_boolean(void);
+
 /* Commit the pending values for the booleans */
 extern int security_commit_booleans(void);
 
diff --git a/src/android.c b/src/android.c
index 8aa1ef6..146d0d7 100644
--- a/src/android.c
+++ b/src/android.c
@@ -774,6 +774,10 @@ int selinux_android_reload_policy(void)
        close(fd);
        selinux_log(SELINUX_INFO, "SELinux: Loaded policy from %s\n", 
sepolicy_file[i-1]);
 
+       rc = security_reload_permanent_boolean();
+       if (rc)
+           selinux_log(SELINUX_INFO, "SELinux: Fail to reload permanent 
sebooleans\n");
+
        return 0;
 }
 
diff --git a/src/booleans.c b/src/booleans.c
index 60bf963..d3d289c 100644
--- a/src/booleans.c
+++ b/src/booleans.c
@@ -18,11 +18,13 @@
 #include <limits.h>
 #include <ctype.h>
 #include <errno.h>
+#include <fts.h>
 
 #include "selinux_internal.h"
 #include "policy.h"
 
 #define SELINUX_BOOL_DIR "/booleans/"
+#define SELINUX_PBOOL_DIR "/data/security/booleans/"
 
 static int filename_select(const struct dirent *d)
 {
@@ -33,6 +35,43 @@ static int filename_select(const struct dirent *d)
        return 1;
 }
 
+static int readx(int fd, void *buf, size_t count)
+{
+       char *b = buf;
+       size_t n = 0, r;
+
+       while (n < count) {
+           r = read(fd, b + n, count - n);
+           if (r < 0) {
+               if (errno == EINTR)
+                   continue;
+               return -1;
+           } else {
+               if (r == 0)
+                   return 0; /* EOF */
+           }
+           n += r;
+       }
+       return 0;
+}
+
+static int writex(int fd, const void *buf, size_t count)
+{
+       const char *b = buf;
+       size_t n = 0, r;
+
+       while (n < count) {
+           r = write(fd, b + n, count - n);
+           if (r < 0) {
+               if (errno == EINTR)
+                   continue;
+               return -1;
+           }
+           n += r;
+       }
+       return 0;
+}
+
 int security_get_boolean_names(char ***names, int *len)
 {
        char path[PATH_MAX];
@@ -202,6 +241,132 @@ int security_set_boolean(const char *name, int value)
 
 hidden_def(security_set_boolean)
 
+int security_set_permanent_boolean(const char *name, int value)
+{
+       int fd, ret, len;
+       char buf[2], *fname;
+       struct stat fstat;
+
+       ret = security_set_boolean(name, value);
+       if (ret) {
+           fprintf(stderr, "Exceptions in security_set_boolean:%s\n",
+                       strerror(errno));
+           return -1;
+       }
+       len = strlen(name) + strlen(SELINUX_PBOOL_DIR) + 1;
+       fname = (char *)malloc(sizeof(char) * len);
+       if (!fname)
+           return -1;
+       snprintf(fname, len, "%s%s", SELINUX_PBOOL_DIR, name);
+       ret = stat(SELINUX_PBOOL_DIR, &fstat);
+       if (ret)
+           goto out;
+
+       fd = open(fname, O_WRONLY | O_CREAT, S_IWUSR | S_IRUSR);
+       if (fd < 0) {
+           ret = -1;
+           goto out;
+       }
+
+       if (value)
+           buf[0] = '1';
+       else
+           buf[0] = '0';
+       buf[1] = '\0';
+
+       ret = writex(fd, buf, 2);
+       close(fd);
+    out:
+       free(fname);
+       return ret;
+}
+
+hidden_def(security_set_permanent_boolean)
+
+static int do_reload_permanent_boolean(FTSENT *ftsent)
+{
+       int fd, ret;
+       char buf[2];
+       SELboolean b;
+
+       fd = open(ftsent->fts_path, O_RDONLY);
+       if (fd < 0) {
+           fprintf(stderr, "Cannot open file %s:%s\n",
+                       ftsent->fts_path, strerror(errno));
+           return -1;
+       }
+       ret = readx(fd, buf, 2);
+       if (ret < 0) {
+           ret = -1;
+           goto out;
+       }
+       b.name = ftsent->fts_accpath;
+       switch (buf[0]) {
+           case '0':
+               b.value = 0;
+               break;
+           case '1':
+               b.value = 1;
+               break;
+           default:
+               fprintf(stderr, "No effective value for %s\n", b.name);
+               ret = -1;
+               goto out;
+       }
+       ret = security_set_boolean_list(1, &b, 0);
+       if (ret) {
+           fprintf(stderr, "Could not set %s to %s: %s\n",
+                       ftsent->fts_accpath, buf, strerror(errno));
+           ret = -1;
+           goto out;
+       }
+       ret = 0;
+
+    out:
+       close(fd);
+       return ret;
+}
+
+int security_reload_permanent_boolean(void)
+{
+       int ret;
+       int ftsflags = FTS_PHYSICAL;
+       FTS *fts;
+       FTSENT *ftsent;
+
+       char *persbool[2] = { SELINUX_PBOOL_DIR, NULL };
+       fts = fts_open(persbool, ftsflags, NULL);
+       if (!fts) {
+           fprintf(stderr, "Could not open %s:%s\n",
+                       SELINUX_PBOOL_DIR, strerror(errno));
+           return -1;
+       }
+       while ((ftsent = fts_read(fts))) {
+           switch (ftsent->fts_info) {
+               case FTS_DP:
+                   break;
+               case FTS_DNR:
+               case FTS_ERR:
+               case FTS_NS:
+                   fprintf(stderr, "Could not access %s: %s\n",
+                               ftsent->fts_path,strerror(errno));
+                   fts_set(fts, ftsent, FTS_SKIP);
+                   break;
+               case FTS_F:
+                   ret = do_reload_permanent_boolean(ftsent);
+                   if (ret)
+                       fprintf(stderr, "Could not reload permanent booleans 
successfully\n");
+                   break;
+               default:
+                   break;
+           }
+       }
+       fts_close(fts);
+       return 0;
+}
+
+hidden_def(security_reload_permanent_boolean)
+
 int security_commit_booleans(void)
 {
        int fd, ret;
@@ -243,16 +408,18 @@ static void rollback(SELboolean * boollist, int end)
 }
 
 int security_set_boolean_list(size_t boolcnt, SELboolean * boollist,
-                             int permanent __attribute__((unused)))
+                             int permanent )
 {
-
        size_t i;
-       for (i = 0; i < boolcnt; i++) {
-               if (security_set_boolean(boollist[i].name, boollist[i].value)) {
-                       rollback(boollist, i);
-                       return -1;
-               }
-       }
+       int (*setbool_function)(char *, int) = permanent ?
+                       security_set_permanent_boolean : security_set_boolean;
+
+       for (i = 0; i < boolcnt; i++) {
+           if (setbool_function(boollist[i].name, boollist[i].value)) {
+               rollback(boollist, i);
+               return -1;
+           }
+       }
 
        /* OK, let's do the commit */
        if (security_commit_booleans()) {
diff --git a/src/selinux_internal.h b/src/selinux_internal.h
index 5087bb6..ccd5753 100644
--- a/src/selinux_internal.h
+++ b/src/selinux_internal.h
@@ -10,6 +10,8 @@ hidden_proto(selinux_mkload_policy)
     hidden_proto(security_get_boolean_active)
     hidden_proto(security_get_boolean_names)
     hidden_proto(security_set_boolean)
+    hidden_proto(security_set_permanent_boolean)
+    hidden_proto(security_reload_permanent_boolean)
     hidden_proto(security_commit_booleans)
     hidden_proto(security_check_context)
     hidden_proto(security_check_context_raw)
-- 
1.7.9.5


--
This message was distributed to subscribers of the seandroid-list mailing list.
If you no longer wish to subscribe, send mail to [email protected] with
the words "unsubscribe seandroid-list" without quotes as the message.

Reply via email to