---
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.