-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 This patch looks good to me. acked. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.12 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iEYEARECAAYFAk/I+OUACgkQrlYvE4MpobMeEACdFM8OPAZvR588xzFVaaxF+nnm H3UAn1m9fEwaMUhIbPCVJdC8mCNw5ris =Fv2c -----END PGP SIGNATURE-----
>From d4b37405ec14c7f1d23ac9b7792ac5f33fe76f88 Mon Sep 17 00:00:00 2001 From: Eric Paris <eparis@xxxxxxxxxx> Date: Wed, 18 Apr 2012 11:00:24 -0400 Subject: [PATCH 35/90] libselinux: boolean name equivalency Add support for booleans.subs file. Basically this allows us to finally change badly named booleans to some standard name. Signed-off-by: Eric Paris <eparis@xxxxxxxxxx> --- libselinux/include/selinux/selinux.h | 1 + libselinux/src/booleans.c | 153 +++++++++++++++++++++++++++------- libselinux/src/file_path_suffixes.h | 1 + libselinux/src/selinux_config.c | 9 +- libselinux/src/selinux_internal.h | 1 + 5 files changed, 132 insertions(+), 33 deletions(-) diff --git a/libselinux/include/selinux/selinux.h b/libselinux/include/selinux/selinux.h index fbcd3ac..8e6f917 100644 --- a/libselinux/include/selinux/selinux.h +++ b/libselinux/include/selinux/selinux.h @@ -515,6 +515,7 @@ extern const char *selinux_x_context_path(void); extern const char *selinux_sepgsql_context_path(void); extern const char *selinux_contexts_path(void); extern const char *selinux_securetty_types_path(void); +extern const char *selinux_booleans_subs_path(void); extern const char *selinux_booleans_path(void); extern const char *selinux_customizable_types_path(void); extern const char *selinux_users_path(void); diff --git a/libselinux/src/booleans.c b/libselinux/src/booleans.c index 1510043..e027c18 100644 --- a/libselinux/src/booleans.c +++ b/libselinux/src/booleans.c @@ -5,6 +5,7 @@ * Dan Walsh <dwalsh@xxxxxxxxxx> - Added security_load_booleans(). */ +#include <assert.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> @@ -86,44 +87,141 @@ int security_get_boolean_names(char ***names, int *len) } hidden_def(security_get_boolean_names) + +static char *bool_sub(const char *name) +{ + char *sub = NULL; + char *line_buf = NULL; + size_t line_len; + FILE *cfg; + + if (!name) + return NULL; + + cfg = fopen(selinux_booleans_subs_path(), "r"); + if (!cfg) + return NULL; + + while (getline(&line_buf, &line_len, cfg)) { + char *ptr; + char *src = line_buf; + char *dst; + + while (*src && isspace(*src)) + src++; + if (!*src) + continue; + if (src[0] == '#') + continue; + ptr = src; + while (*ptr && !isspace(*ptr)) + ptr++; + *ptr++ = '\0'; + if (strcmp(src, name) != 0) + continue; + + dst = ptr; + while (*dst && isspace(*dst)) + dst++; + if (!*dst) + continue; + ptr=dst; + while (*ptr && !isspace(*ptr)) + ptr++; + *ptr='\0'; + + sub = strdup(dst); + break; + } + + free(line_buf); + fclose(cfg); + return sub; +} + +static int bool_open(const char *name, int flag) { + char *fname = NULL; + char *alt_name = NULL; + int len; + int fd = -1; + int ret; + char *ptr; + + if (!name) { + errno = EINVAL; + return -1; + } + + /* note the 'sizeof' gets us enough room for the '\0' */ + len = strlen(name) + strlen(selinux_mnt) + sizeof(SELINUX_BOOL_DIR); + fname = malloc(sizeof(char) * len); + if (!fname) + return -1; + + ret = snprintf(fname, len, "%s%s%s", selinux_mnt, SELINUX_BOOL_DIR, name); + if (ret < 0) + goto out; + assert(ret < len); + + fd = open(fname, flag); + if (fd >= 0 || errno != ENOENT) + goto out; + + alt_name = bool_sub(name); + if (!alt_name) + goto out; + + /* note the 'sizeof' gets us enough room for the '\0' */ + len = strlen(alt_name) + strlen(selinux_mnt) + sizeof(SELINUX_BOOL_DIR); + ptr = realloc(fname, len); + if (!ptr) + goto out; + fname = ptr; + + ret = snprintf(fname, len, "%s%s%s", selinux_mnt, SELINUX_BOOL_DIR, alt_name); + if (ret < 0) + goto out; + assert(ret < len); + + fd = open(fname, flag); +out: + free(fname); + free(alt_name); + + return fd; +} + #define STRBUF_SIZE 3 static int get_bool_value(const char *name, char **buf) { int fd, len; - char *fname = NULL; + int errno_tmp; if (!selinux_mnt) { errno = ENOENT; return -1; } - *buf = (char *)malloc(sizeof(char) * (STRBUF_SIZE + 1)); + *buf = malloc(sizeof(char) * (STRBUF_SIZE + 1)); if (!*buf) - goto out; - (*buf)[STRBUF_SIZE] = 0; + return -1; - len = strlen(name) + strlen(selinux_mnt) + sizeof(SELINUX_BOOL_DIR); - fname = (char *)malloc(sizeof(char) * len); - if (!fname) - goto out; - snprintf(fname, len, "%s%s%s", selinux_mnt, SELINUX_BOOL_DIR, name); + (*buf)[STRBUF_SIZE] = 0; - fd = open(fname, O_RDONLY); + fd = bool_open(name, O_RDONLY); if (fd < 0) - goto out; + goto out_err; len = read(fd, *buf, STRBUF_SIZE); + errno_tmp = errno; close(fd); + errno = errno_tmp; if (len != STRBUF_SIZE) - goto out; + goto out_err; - free(fname); return 0; - out: - if (*buf) - free(*buf); - if (fname) - free(fname); +out_err: + free(*buf); return -1; } @@ -164,8 +262,8 @@ hidden_def(security_get_boolean_active) int security_set_boolean(const char *name, int value) { - int fd, ret, len; - char buf[2], *fname; + int fd, ret; + char buf[2]; if (!selinux_mnt) { errno = ENOENT; @@ -176,17 +274,9 @@ int security_set_boolean(const char *name, int value) return -1; } - len = strlen(name) + strlen(selinux_mnt) + sizeof(SELINUX_BOOL_DIR); - fname = (char *)malloc(sizeof(char) * len); - if (!fname) + fd = bool_open(name, O_WRONLY); + if (fd < 0) return -1; - snprintf(fname, len, "%s%s%s", selinux_mnt, SELINUX_BOOL_DIR, name); - - fd = open(fname, O_WRONLY); - if (fd < 0) { - ret = -1; - goto out; - } if (value) buf[0] = '1'; @@ -196,8 +286,7 @@ int security_set_boolean(const char *name, int value) ret = write(fd, buf, 2); close(fd); - out: - free(fname); + if (ret > 0) return 0; else diff --git a/libselinux/src/file_path_suffixes.h b/libselinux/src/file_path_suffixes.h index 0b00156..1aa4734 100644 --- a/libselinux/src/file_path_suffixes.h +++ b/libselinux/src/file_path_suffixes.h @@ -25,3 +25,4 @@ S_(BINPOLICY, "/policy/policy") S_(FILE_CONTEXT_SUBS, "/contexts/files/file_contexts.subs") S_(FILE_CONTEXT_SUBS_DIST, "/contexts/files/file_contexts.subs_dist") S_(SEPGSQL_CONTEXTS, "/contexts/sepgsql_contexts") + S_(BOOLEAN_SUBS, "/booleans.subs") diff --git a/libselinux/src/selinux_config.c b/libselinux/src/selinux_config.c index 907b004..2ffaa84 100644 --- a/libselinux/src/selinux_config.c +++ b/libselinux/src/selinux_config.c @@ -47,7 +47,8 @@ #define FILE_CONTEXT_SUBS 23 #define SEPGSQL_CONTEXTS 24 #define FILE_CONTEXT_SUBS_DIST 25 -#define NEL 26 +#define BOOLEAN_SUBS 26 +#define NEL 27 /* Part of one-time lazy init */ static pthread_once_t once = PTHREAD_ONCE_INIT; @@ -442,6 +443,12 @@ const char *selinux_virtual_image_context_path(void) hidden_def(selinux_virtual_image_context_path) +const char * selinux_booleans_subs_path(void) { + return get_path(BOOLEAN_SUBS); +} + +hidden_def(selinux_booleans_subs_path) + const char * selinux_file_context_subs_path(void) { return get_path(FILE_CONTEXT_SUBS); } diff --git a/libselinux/src/selinux_internal.h b/libselinux/src/selinux_internal.h index 4db366a..8d752f7 100644 --- a/libselinux/src/selinux_internal.h +++ b/libselinux/src/selinux_internal.h @@ -60,6 +60,7 @@ hidden_proto(selinux_mkload_policy) hidden_proto(security_setenforce) hidden_proto(security_deny_unknown) hidden_proto(selinux_binary_policy_path) + hidden_proto(selinux_booleans_subs_path) hidden_proto(selinux_current_policy_path) hidden_proto(selinux_default_context_path) hidden_proto(selinux_securetty_types_path) -- 1.7.10.2