diff options
54 files changed, 418 insertions, 228 deletions
diff --git a/libselinux/src/audit2why.c b/libselinux/src/audit2why.c index 3135eeda..857383ac 100644 --- a/libselinux/src/audit2why.c +++ b/libselinux/src/audit2why.c @@ -201,7 +201,7 @@ static int __policy_init(const char *init_path) path[PATH_MAX-1] = '\0'; if (init_path) { strncpy(path, init_path, PATH_MAX-1); - fp = fopen(path, "r"); + fp = fopen(path, "re"); if (!fp) { snprintf(errormsg, sizeof(errormsg), "unable to open %s: %s\n", @@ -218,7 +218,7 @@ static int __policy_init(const char *init_path) PyErr_SetString( PyExc_ValueError, errormsg); return 1; } - fp = fopen(curpolicy, "r"); + fp = fopen(curpolicy, "re"); if (!fp) { snprintf(errormsg, sizeof(errormsg), "unable to open %s: %s\n", diff --git a/libselinux/src/booleans.c b/libselinux/src/booleans.c index ba9d9348..1da55bfd 100644 --- a/libselinux/src/booleans.c +++ b/libselinux/src/booleans.c @@ -97,7 +97,7 @@ char *selinux_boolean_sub(const char *name) if (!name) return NULL; - cfg = fopen(selinux_booleans_subs_path(), "r"); + cfg = fopen(selinux_booleans_subs_path(), "re"); if (!cfg) goto out; @@ -210,7 +210,7 @@ static int get_bool_value(const char *name, char **buf) (*buf)[STRBUF_SIZE] = 0; - fd = bool_open(name, O_RDONLY); + fd = bool_open(name, O_RDONLY | O_CLOEXEC); if (fd < 0) goto out_err; @@ -274,7 +274,7 @@ int security_set_boolean(const char *name, int value) return -1; } - fd = bool_open(name, O_WRONLY); + fd = bool_open(name, O_WRONLY | O_CLOEXEC); if (fd < 0) return -1; @@ -305,7 +305,7 @@ int security_commit_booleans(void) } snprintf(path, sizeof path, "%s/commit_pending_bools", selinux_mnt); - fd = open(path, O_WRONLY); + fd = open(path, O_WRONLY | O_CLOEXEC); if (fd < 0) return -1; @@ -342,30 +342,42 @@ static int process_boolean(char *buffer, char *name, int namesize, int *val) { char name1[BUFSIZ]; char *ptr = NULL; - char *tok = strtok_r(buffer, "=", &ptr); - if (tok) { - strncpy(name1, tok, BUFSIZ - 1); - strtrim(name, name1, namesize - 1); - if (name[0] == '#') - return 0; - tok = strtok_r(NULL, "\0", &ptr); - if (tok) { - while (isspace(*tok)) - tok++; - *val = -1; - if (isdigit(tok[0])) - *val = atoi(tok); - else if (!strncasecmp(tok, "true", sizeof("true") - 1)) - *val = 1; - else if (!strncasecmp - (tok, "false", sizeof("false") - 1)) - *val = 0; - if (*val != 0 && *val != 1) { - errno = EINVAL; - return -1; - } + char *tok; - } + /* Skip spaces */ + while (isspace(buffer[0])) + buffer++; + /* Ignore comments */ + if (buffer[0] == '#') + return 0; + + tok = strtok_r(buffer, "=", &ptr); + if (!tok) { + errno = EINVAL; + return -1; + } + strncpy(name1, tok, BUFSIZ - 1); + strtrim(name, name1, namesize - 1); + + tok = strtok_r(NULL, "\0", &ptr); + if (!tok) { + errno = EINVAL; + return -1; + } + + while (isspace(*tok)) + tok++; + + *val = -1; + if (isdigit(tok[0])) + *val = atoi(tok); + else if (!strncasecmp(tok, "true", sizeof("true") - 1)) + *val = 1; + else if (!strncasecmp(tok, "false", sizeof("false") - 1)) + *val = 0; + if (*val != 0 && *val != 1) { + errno = EINVAL; + return -1; } return 1; } @@ -399,7 +411,7 @@ static int save_booleans(size_t boolcnt, SELboolean * boollist) snprintf(local_bool_file, sizeof(local_bool_file), "%s.local", bool_file); - boolf = fopen(local_bool_file, "r"); + boolf = fopen(local_bool_file, "re"); if (boolf != NULL) { ssize_t ret; size_t size = 0; @@ -518,7 +530,7 @@ int security_load_booleans(char *path) int val; char name[BUFSIZ]; - boolf = fopen(path ? path : selinux_booleans_path(), "r"); + boolf = fopen(path ? path : selinux_booleans_path(), "re"); if (boolf == NULL) goto localbool; @@ -536,7 +548,7 @@ int security_load_booleans(char *path) localbool: snprintf(localbools, sizeof(localbools), "%s.local", (path ? path : selinux_booleans_path())); - boolf = fopen(localbools, "r"); + boolf = fopen(localbools, "re"); if (boolf != NULL) { int ret; diff --git a/libselinux/src/canonicalize_context.c b/libselinux/src/canonicalize_context.c index 7cf31395..ba4c9a2c 100644 --- a/libselinux/src/canonicalize_context.c +++ b/libselinux/src/canonicalize_context.c @@ -23,7 +23,7 @@ int security_canonicalize_context_raw(const char * con, } snprintf(path, sizeof path, "%s/context", selinux_mnt); - fd = open(path, O_RDWR); + fd = open(path, O_RDWR | O_CLOEXEC); if (fd < 0) return -1; diff --git a/libselinux/src/check_context.c b/libselinux/src/check_context.c index 52063fac..8a7997f0 100644 --- a/libselinux/src/check_context.c +++ b/libselinux/src/check_context.c @@ -20,7 +20,7 @@ int security_check_context_raw(const char * con) } snprintf(path, sizeof path, "%s/context", selinux_mnt); - fd = open(path, O_RDWR); + fd = open(path, O_RDWR | O_CLOEXEC); if (fd < 0) return -1; diff --git a/libselinux/src/compute_av.c b/libselinux/src/compute_av.c index 937e5c3e..1d05e7b6 100644 --- a/libselinux/src/compute_av.c +++ b/libselinux/src/compute_av.c @@ -27,7 +27,7 @@ int security_compute_av_flags_raw(const char * scon, } snprintf(path, sizeof path, "%s/access", selinux_mnt); - fd = open(path, O_RDWR); + fd = open(path, O_RDWR | O_CLOEXEC); if (fd < 0) return -1; diff --git a/libselinux/src/compute_create.c b/libselinux/src/compute_create.c index 9559d421..0975aeac 100644 --- a/libselinux/src/compute_create.c +++ b/libselinux/src/compute_create.c @@ -65,7 +65,7 @@ int security_compute_create_name_raw(const char * scon, } snprintf(path, sizeof path, "%s/create", selinux_mnt); - fd = open(path, O_RDWR); + fd = open(path, O_RDWR | O_CLOEXEC); if (fd < 0) return -1; diff --git a/libselinux/src/compute_member.c b/libselinux/src/compute_member.c index 1fc7e41a..4e2d221e 100644 --- a/libselinux/src/compute_member.c +++ b/libselinux/src/compute_member.c @@ -26,7 +26,7 @@ int security_compute_member_raw(const char * scon, } snprintf(path, sizeof path, "%s/member", selinux_mnt); - fd = open(path, O_RDWR); + fd = open(path, O_RDWR | O_CLOEXEC); if (fd < 0) return -1; diff --git a/libselinux/src/compute_relabel.c b/libselinux/src/compute_relabel.c index 4615aee4..49f77ef3 100644 --- a/libselinux/src/compute_relabel.c +++ b/libselinux/src/compute_relabel.c @@ -26,7 +26,7 @@ int security_compute_relabel_raw(const char * scon, } snprintf(path, sizeof path, "%s/relabel", selinux_mnt); - fd = open(path, O_RDWR); + fd = open(path, O_RDWR | O_CLOEXEC); if (fd < 0) return -1; diff --git a/libselinux/src/compute_user.c b/libselinux/src/compute_user.c index b37c5d33..7b881215 100644 --- a/libselinux/src/compute_user.c +++ b/libselinux/src/compute_user.c @@ -25,7 +25,7 @@ int security_compute_user_raw(const char * scon, } snprintf(path, sizeof path, "%s/user", selinux_mnt); - fd = open(path, O_RDWR); + fd = open(path, O_RDWR | O_CLOEXEC); if (fd < 0) return -1; diff --git a/libselinux/src/deny_unknown.c b/libselinux/src/deny_unknown.c index c93998a0..77d04e37 100644 --- a/libselinux/src/deny_unknown.c +++ b/libselinux/src/deny_unknown.c @@ -21,7 +21,7 @@ int security_deny_unknown(void) } snprintf(path, sizeof(path), "%s/deny_unknown", selinux_mnt); - fd = open(path, O_RDONLY); + fd = open(path, O_RDONLY | O_CLOEXEC); if (fd < 0) return -1; diff --git a/libselinux/src/disable.c b/libselinux/src/disable.c index dac0f5bd..8d66262a 100644 --- a/libselinux/src/disable.c +++ b/libselinux/src/disable.c @@ -21,7 +21,7 @@ int security_disable(void) } snprintf(path, sizeof path, "%s/disable", selinux_mnt); - fd = open(path, O_WRONLY); + fd = open(path, O_WRONLY | O_CLOEXEC); if (fd < 0) return -1; diff --git a/libselinux/src/enabled.c b/libselinux/src/enabled.c index 2ec6797a..dd628fba 100644 --- a/libselinux/src/enabled.c +++ b/libselinux/src/enabled.c @@ -36,7 +36,7 @@ int is_selinux_mls_enabled(void) return enabled; snprintf(path, sizeof path, "%s/mls", selinux_mnt); - fd = open(path, O_RDONLY); + fd = open(path, O_RDONLY | O_CLOEXEC); if (fd < 0) return enabled; diff --git a/libselinux/src/get_context_list.c b/libselinux/src/get_context_list.c index f3fa4a9b..689e4658 100644 --- a/libselinux/src/get_context_list.c +++ b/libselinux/src/get_context_list.c @@ -275,7 +275,7 @@ static int get_failsafe_context(const char *user, char ** newcon) size_t plen, nlen; int rc; - fp = fopen(selinux_failsafe_context_path(), "r"); + fp = fopen(selinux_failsafe_context_path(), "re"); if (!fp) return -1; @@ -437,7 +437,7 @@ int get_ordered_context_list(const char *user, if (!fname) goto failsafe; snprintf(fname, fname_len, "%s%s", user_contexts_path, user); - fp = fopen(fname, "r"); + fp = fopen(fname, "re"); if (fp) { __fsetlocking(fp, FSETLOCKING_BYCALLER); rc = get_context_order(fp, fromcon, reachable, nreach, ordering, @@ -451,7 +451,7 @@ int get_ordered_context_list(const char *user, } } free(fname); - fp = fopen(selinux_default_context_path(), "r"); + fp = fopen(selinux_default_context_path(), "re"); if (fp) { __fsetlocking(fp, FSETLOCKING_BYCALLER); rc = get_context_order(fp, fromcon, reachable, nreach, ordering, diff --git a/libselinux/src/get_default_type.c b/libselinux/src/get_default_type.c index 27f2ae52..dd7b5d79 100644 --- a/libselinux/src/get_default_type.c +++ b/libselinux/src/get_default_type.c @@ -11,7 +11,7 @@ int get_default_type(const char *role, char **type) { FILE *fp = NULL; - fp = fopen(selinux_default_type_path(), "r"); + fp = fopen(selinux_default_type_path(), "re"); if (!fp) return -1; diff --git a/libselinux/src/get_initial_context.c b/libselinux/src/get_initial_context.c index 522ed78f..5e919f47 100644 --- a/libselinux/src/get_initial_context.c +++ b/libselinux/src/get_initial_context.c @@ -25,7 +25,7 @@ int security_get_initial_context_raw(const char * name, char ** con) snprintf(path, sizeof path, "%s%s%s", selinux_mnt, SELINUX_INITCON_DIR, name); - fd = open(path, O_RDONLY); + fd = open(path, O_RDONLY | O_CLOEXEC); if (fd < 0) return -1; diff --git a/libselinux/src/getenforce.c b/libselinux/src/getenforce.c index 03d3abc5..d909dced 100644 --- a/libselinux/src/getenforce.c +++ b/libselinux/src/getenforce.c @@ -21,7 +21,7 @@ int security_getenforce(void) } snprintf(path, sizeof path, "%s/enforce", selinux_mnt); - fd = open(path, O_RDONLY); + fd = open(path, O_RDONLY | O_CLOEXEC); if (fd < 0) return -1; diff --git a/libselinux/src/init.c b/libselinux/src/init.c index ddf91f8d..2690a72f 100644 --- a/libselinux/src/init.c +++ b/libselinux/src/init.c @@ -61,7 +61,7 @@ int selinuxfs_exists(void) size_t len; ssize_t num; - fp = fopen("/proc/filesystems", "r"); + fp = fopen("/proc/filesystems", "re"); if (!fp) return 1; /* Fail as if it exists */ __fsetlocking(fp, FSETLOCKING_BYCALLER); @@ -101,7 +101,7 @@ static void init_selinuxmnt(void) /* At this point, the usual spot doesn't have an selinuxfs so * we look around for it */ - fp = fopen("/proc/mounts", "r"); + fp = fopen("/proc/mounts", "re"); if (!fp) goto out; diff --git a/libselinux/src/is_customizable_type.c b/libselinux/src/is_customizable_type.c index 0b33edc6..92876f4d 100644 --- a/libselinux/src/is_customizable_type.c +++ b/libselinux/src/is_customizable_type.c @@ -16,7 +16,7 @@ static int get_customizable_type_list(char *** retlist) unsigned int ctr = 0, i; char **list = NULL; - fp = fopen(selinux_customizable_types_path(), "r"); + fp = fopen(selinux_customizable_types_path(), "re"); if (!fp) return -1; diff --git a/libselinux/src/label.c b/libselinux/src/label.c index 951031e5..41937397 100644 --- a/libselinux/src/label.c +++ b/libselinux/src/label.c @@ -96,7 +96,7 @@ struct selabel_sub *selabel_subs_init(const char *path, struct selabel_digest *digest) { char buf[1024]; - FILE *cfg = fopen(path, "r"); + FILE *cfg = fopen(path, "re"); struct selabel_sub *sub = NULL; struct stat sb; @@ -191,9 +191,11 @@ static inline struct selabel_digest *selabel_is_digest_set return NULL; err: - free(digest->digest); - free(digest->specfile_list); - free(digest); + if (digest) { + free(digest->digest); + free(digest->specfile_list); + free(digest); + } return NULL; } diff --git a/libselinux/src/label_backends_android.c b/libselinux/src/label_backends_android.c index 6435df8c..f85ec6ff 100644 --- a/libselinux/src/label_backends_android.c +++ b/libselinux/src/label_backends_android.c @@ -149,7 +149,7 @@ static int process_file(struct selabel_handle *rec, const char *path) spec_t *spec_arr; /* Open the specification file. */ - if ((fp = fopen(path, "r")) == NULL) + if ((fp = fopen(path, "re")) == NULL) return -1; if (fstat(fileno(fp), &sb) < 0) diff --git a/libselinux/src/label_file.c b/libselinux/src/label_file.c index 18e26fb4..70f68382 100644 --- a/libselinux/src/label_file.c +++ b/libselinux/src/label_file.c @@ -520,7 +520,7 @@ static FILE *open_file(const char *path, const char *suffix, } memcpy(sb, &found->sb, sizeof(*sb)); - return fopen(save_path, "r"); + return fopen(save_path, "re"); } static int process_file(const char *path, const char *suffix, diff --git a/libselinux/src/label_media.c b/libselinux/src/label_media.c index 622741b2..d202e5d5 100644 --- a/libselinux/src/label_media.c +++ b/libselinux/src/label_media.c @@ -90,7 +90,7 @@ static int init(struct selabel_handle *rec, const struct selinux_opt *opts, /* Open the specification file. */ if (!path) path = selinux_media_context_path(); - if ((fp = fopen(path, "r")) == NULL) + if ((fp = fopen(path, "re")) == NULL) return -1; __fsetlocking(fp, FSETLOCKING_BYCALLER); diff --git a/libselinux/src/label_x.c b/libselinux/src/label_x.c index 700def17..96745299 100644 --- a/libselinux/src/label_x.c +++ b/libselinux/src/label_x.c @@ -117,7 +117,7 @@ static int init(struct selabel_handle *rec, const struct selinux_opt *opts, /* Open the specification file. */ if (!path) path = selinux_x_context_path(); - if ((fp = fopen(path, "r")) == NULL) + if ((fp = fopen(path, "re")) == NULL) return -1; __fsetlocking(fp, FSETLOCKING_BYCALLER); diff --git a/libselinux/src/load_policy.c b/libselinux/src/load_policy.c index e788c25c..7f083117 100644 --- a/libselinux/src/load_policy.c +++ b/libselinux/src/load_policy.c @@ -34,7 +34,7 @@ int security_load_policy(void *data, size_t len) } snprintf(path, sizeof path, "%s/load", selinux_mnt); - fd = open(path, O_RDWR); + fd = open(path, O_RDWR | O_CLOEXEC); if (fd < 0) return -1; @@ -173,13 +173,13 @@ checkbool: search: snprintf(path, sizeof(path), "%s.%d", selinux_binary_policy_path(), vers); - fd = open(path, O_RDONLY); + fd = open(path, O_RDONLY | O_CLOEXEC); while (fd < 0 && errno == ENOENT && --vers >= minvers) { /* Check prior versions to see if old policy is available */ snprintf(path, sizeof(path), "%s.%d", selinux_binary_policy_path(), vers); - fd = open(path, O_RDONLY); + fd = open(path, O_RDONLY | O_CLOEXEC); } if (fd < 0) { fprintf(stderr, @@ -334,7 +334,7 @@ int selinux_init_load_policy(int *enforce) /* Check for an override of the mode via the kernel command line. */ rc = mount("proc", "/proc", "proc", 0, 0); - cfg = fopen("/proc/cmdline", "r"); + cfg = fopen("/proc/cmdline", "re"); if (cfg) { char *tmp; buf = malloc(selinux_page_size); diff --git a/libselinux/src/matchmediacon.c b/libselinux/src/matchmediacon.c index 46cba468..23d01af4 100644 --- a/libselinux/src/matchmediacon.c +++ b/libselinux/src/matchmediacon.c @@ -18,7 +18,7 @@ int matchmediacon(const char *media, char ** con) char *ptr, *ptr2 = NULL; int found = 0; char current_line[PATH_MAX]; - if ((infile = fopen(path, "r")) == NULL) + if ((infile = fopen(path, "re")) == NULL) return -1; while (!feof_unlocked(infile)) { if (!fgets_unlocked(current_line, sizeof(current_line), infile)) { diff --git a/libselinux/src/policyvers.c b/libselinux/src/policyvers.c index 284a7f7f..c97dd9df 100644 --- a/libselinux/src/policyvers.c +++ b/libselinux/src/policyvers.c @@ -23,7 +23,7 @@ int security_policyvers(void) } snprintf(path, sizeof path, "%s/policyvers", selinux_mnt); - fd = open(path, O_RDONLY); + fd = open(path, O_RDONLY | O_CLOEXEC); if (fd < 0) { if (errno == ENOENT) return vers; diff --git a/libselinux/src/procattr.c b/libselinux/src/procattr.c index 8cd59af5..ebc0adec 100644 --- a/libselinux/src/procattr.c +++ b/libselinux/src/procattr.c @@ -143,7 +143,7 @@ static int getprocattrcon_raw(char ** context, return 0; } - fd = openattr(pid, attr, O_RDONLY); + fd = openattr(pid, attr, O_RDONLY | O_CLOEXEC); if (fd < 0) return -1; @@ -235,7 +235,7 @@ static int setprocattrcon_raw(const char * context, && !strcmp(context, *prev_context)) return 0; - fd = openattr(pid, attr, O_RDWR); + fd = openattr(pid, attr, O_RDWR | O_CLOEXEC); if (fd < 0) return -1; if (context) { diff --git a/libselinux/src/selinux_check_securetty_context.c b/libselinux/src/selinux_check_securetty_context.c index 24e5e2c0..55d4e039 100644 --- a/libselinux/src/selinux_check_securetty_context.c +++ b/libselinux/src/selinux_check_securetty_context.c @@ -14,7 +14,7 @@ int selinux_check_securetty_context(const char * tty_context) ssize_t len; int found = -1; FILE *fp; - fp = fopen(selinux_securetty_types_path(), "r"); + fp = fopen(selinux_securetty_types_path(), "re"); if (fp) { context_t con = context_new(tty_context); if (con) { diff --git a/libselinux/src/selinux_config.c b/libselinux/src/selinux_config.c index 88bcc856..d8e140c8 100644 --- a/libselinux/src/selinux_config.c +++ b/libselinux/src/selinux_config.c @@ -88,7 +88,7 @@ static const uint16_t file_path_suffixes_idx[NEL] = { int selinux_getenforcemode(int *enforce) { int ret = -1; - FILE *cfg = fopen(SELINUXCONFIG, "r"); + FILE *cfg = fopen(SELINUXCONFIG, "re"); if (cfg) { char *buf; int len = sizeof(SELINUXTAG) - 1; @@ -163,7 +163,7 @@ static void init_selinux_config(void) if (selinux_policyroot) return; - fp = fopen(SELINUXCONFIG, "r"); + fp = fopen(SELINUXCONFIG, "re"); if (fp) { __fsetlocking(fp, FSETLOCKING_BYCALLER); while ((len = getline(&line_buf, &line_len, fp)) > 0) { diff --git a/libselinux/src/selinux_restorecon.c b/libselinux/src/selinux_restorecon.c index 9fdafea1..ced41152 100644 --- a/libselinux/src/selinux_restorecon.c +++ b/libselinux/src/selinux_restorecon.c @@ -242,7 +242,7 @@ static int exclude_non_seclabel_mounts(void) if (uname(&uts) == 0 && strverscmp(uts.release, "2.6.30") < 0) return 0; - fp = fopen("/proc/mounts", "r"); + fp = fopen("/proc/mounts", "re"); if (!fp) return 0; @@ -252,12 +252,12 @@ static int exclude_non_seclabel_mounts(void) item = strtok(buf, " "); while (item != NULL) { mount_info[index] = item; - if (index == 3) - break; index++; + if (index == 4) + break; item = strtok(NULL, " "); } - if (index < 3) { + if (index < 4) { selinux_log(SELINUX_ERROR, "/proc/mounts record \"%s\" has incorrect format.\n", buf); @@ -664,7 +664,7 @@ static int restorecon_sb(const char *pathname, const struct stat *sb, curcon = NULL; } - if (strcmp(curcon, newcon) != 0) { + if (curcon == NULL || strcmp(curcon, newcon) != 0) { if (!flags->set_specctx && curcon && (is_context_customizable(curcon) > 0)) { if (flags->verbose) { diff --git a/libselinux/src/setenforce.c b/libselinux/src/setenforce.c index e5e7612f..09cad3ce 100644 --- a/libselinux/src/setenforce.c +++ b/libselinux/src/setenforce.c @@ -21,7 +21,7 @@ int security_setenforce(int value) } snprintf(path, sizeof path, "%s/enforce", selinux_mnt); - fd = open(path, O_RDWR); + fd = open(path, O_RDWR | O_CLOEXEC); if (fd < 0) return -1; diff --git a/libselinux/src/seusers.c b/libselinux/src/seusers.c index 09e704be..572a7b01 100644 --- a/libselinux/src/seusers.c +++ b/libselinux/src/seusers.c @@ -185,7 +185,7 @@ int getseuserbyname(const char *name, char **r_seuser, char **r_level) gid_t gid = get_default_gid(name); - cfg = fopen(selinux_usersconf_path(), "r"); + cfg = fopen(selinux_usersconf_path(), "re"); if (!cfg) goto nomatch; @@ -278,7 +278,7 @@ int getseuser(const char *username, const char *service, FILE *fp = NULL; if (asprintf(&path,"%s/logins/%s", selinux_policy_root(), username) < 0) goto err; - fp = fopen(path, "r"); + fp = fopen(path, "re"); free(path); if (fp == NULL) goto err; __fsetlocking(fp, FSETLOCKING_BYCALLER); diff --git a/libselinux/src/stringrep.c b/libselinux/src/stringrep.c index 2dbec2bf..2d83f960 100644 --- a/libselinux/src/stringrep.c +++ b/libselinux/src/stringrep.c @@ -80,7 +80,7 @@ static struct discover_class_node * discover_class(const char *s) /* load up class index */ snprintf(path, sizeof path, "%s/class/%s/index", selinux_mnt,s); - fd = open(path, O_RDONLY); + fd = open(path, O_RDONLY | O_CLOEXEC); if (fd < 0) goto err3; diff --git a/libselinux/utils/getsebool.c b/libselinux/utils/getsebool.c index 3c6eba55..36994536 100644 --- a/libselinux/utils/getsebool.c +++ b/libselinux/utils/getsebool.c @@ -15,7 +15,7 @@ static __attribute__ ((__noreturn__)) void usage(const char *progname) int main(int argc, char **argv) { int i, get_all = 0, rc = 0, active, pending, len = 0, opt; - char **names; + char **names = NULL; while ((opt = getopt(argc, argv, "a")) > 0) { switch (opt) { @@ -55,7 +55,7 @@ int main(int argc, char **argv) if (argc < 2) usage(argv[0]); len = argc - 1; - names = malloc(sizeof(char *) * len); + names = calloc(len, sizeof(char *)); if (!names) { fprintf(stderr, "%s: out of memory\n", argv[0]); return 2; @@ -65,7 +65,8 @@ int main(int argc, char **argv) if (!names[i]) { fprintf(stderr, "%s: out of memory\n", argv[0]); - return 2; + rc = 2; + goto out; } } } diff --git a/libsemanage/src/direct_api.c b/libsemanage/src/direct_api.c index 56873235..dc360be8 100644 --- a/libsemanage/src/direct_api.c +++ b/libsemanage/src/direct_api.c @@ -1104,8 +1104,7 @@ static int semanage_direct_commit(semanage_handle_t * sh) /* Declare some variables */ int modified = 0, fcontexts_modified, ports_modified, seusers_modified, users_extra_modified, dontaudit_modified, - preserve_tunables_modified, bools_modified = 0, - disable_dontaudit, preserve_tunables; + preserve_tunables_modified, disable_dontaudit, preserve_tunables; dbase_config_t *users = semanage_user_dbase_local(sh); dbase_config_t *users_base = semanage_user_base_dbase_local(sh); dbase_config_t *pusers_base = semanage_user_base_dbase_policy(sh); @@ -1186,13 +1185,13 @@ static int semanage_direct_commit(semanage_handle_t * sh) users_extra_modified = users_extra->dtable->is_modified(users_extra->dbase); ports_modified = ports->dtable->is_modified(ports->dbase); - bools_modified = bools->dtable->is_modified(bools->dbase); modified = sh->modules_modified; modified |= seusers_modified; modified |= users_extra_modified; modified |= ports_modified; modified |= users->dtable->is_modified(users_base->dbase); + modified |= bools->dtable->is_modified(bools->dbase); modified |= ifaces->dtable->is_modified(ifaces->dbase); modified |= nodes->dtable->is_modified(nodes->dbase); modified |= dontaudit_modified; @@ -1316,19 +1315,7 @@ static int semanage_direct_commit(semanage_handle_t * sh) goto cleanup; cil_db_destroy(&cildb); - - } else { - /* Load already linked policy */ - retval = sepol_policydb_create(&out); - if (retval < 0) - goto cleanup; - retval = semanage_read_policydb(sh, out); - if (retval < 0) - goto cleanup; - } - - if (sh->do_rebuild || modified || bools_modified) { /* Attach to policy databases that work with a policydb. */ dbase_policydb_attach((dbase_policydb_t *) pusers_base->dbase, out); dbase_policydb_attach((dbase_policydb_t *) pports->dbase, out); @@ -1350,6 +1337,15 @@ static int semanage_direct_commit(semanage_handle_t * sh) if (retval < 0) goto cleanup; } else { + /* Load already linked policy */ + retval = sepol_policydb_create(&out); + if (retval < 0) + goto cleanup; + + retval = semanage_read_policydb(sh, out); + if (retval < 0) + goto cleanup; + retval = semanage_base_merge_components(sh); if (retval < 0) goto cleanup; @@ -1444,7 +1440,7 @@ static int semanage_direct_commit(semanage_handle_t * sh) sepol_policydb_free(out); out = NULL; - if (sh->do_rebuild || modified || bools_modified || fcontexts_modified) { + if (sh->do_rebuild || modified || fcontexts_modified) { retval = semanage_install_sandbox(sh); } @@ -1458,7 +1454,7 @@ cleanup: free(mod_filenames[i]); } - if (modified || bools_modified) { + if (modified) { /* Detach from policydb, so it can be freed */ dbase_policydb_detach((dbase_policydb_t *) pusers_base->dbase); dbase_policydb_detach((dbase_policydb_t *) pports->dbase); @@ -2499,11 +2495,7 @@ static int semanage_direct_list_all(semanage_handle_t *sh, goto cleanup; } - ret = semanage_module_info_destroy(sh, modinfo_tmp); - if (ret != 0) { - status = -1; - goto cleanup; - } + semanage_module_info_destroy(sh, modinfo_tmp); free(modinfo_tmp); modinfo_tmp = NULL; @@ -2528,11 +2520,7 @@ cleanup: free(modules); } - ret = semanage_module_info_destroy(sh, modinfo_tmp); - if (ret != 0) { - status = -1; - goto cleanup; - } + semanage_module_info_destroy(sh, modinfo_tmp); free(modinfo_tmp); modinfo_tmp = NULL; diff --git a/libsepol/cil/include/cil/cil.h b/libsepol/cil/include/cil/cil.h index c4a6fb9a..4507892c 100644 --- a/libsepol/cil/include/cil/cil.h +++ b/libsepol/cil/include/cil/cil.h @@ -50,6 +50,8 @@ extern void cil_set_disable_neverallow(cil_db_t *db, int disable_neverallow); extern void cil_set_preserve_tunables(cil_db_t *db, int preserve_tunables); extern int cil_set_handle_unknown(cil_db_t *db, int handle_unknown); extern void cil_set_mls(cil_db_t *db, int mls); +extern void cil_set_attrs_expand_generated(struct cil_db *db, int attrs_expand_generated); +extern void cil_set_attrs_expand_size(struct cil_db *db, unsigned attrs_expand_size); extern void cil_set_target_platform(cil_db_t *db, int target_platform); extern void cil_set_policy_version(cil_db_t *db, int policy_version); extern void cil_write_policy_conf(FILE *out, struct cil_db *db); diff --git a/libsepol/cil/src/cil.c b/libsepol/cil/src/cil.c index 7c40ad0c..a64c5284 100644 --- a/libsepol/cil/src/cil.c +++ b/libsepol/cil/src/cil.c @@ -282,6 +282,8 @@ void cil_db_init(struct cil_db **db) (*db)->disable_dontaudit = CIL_FALSE; (*db)->disable_neverallow = CIL_FALSE; + (*db)->attrs_expand_generated = CIL_FALSE; + (*db)->attrs_expand_size = 1; (*db)->preserve_tunables = CIL_FALSE; (*db)->handle_unknown = -1; (*db)->mls = -1; @@ -1629,6 +1631,16 @@ void cil_set_disable_neverallow(struct cil_db *db, int disable_neverallow) db->disable_neverallow = disable_neverallow; } +void cil_set_attrs_expand_generated(struct cil_db *db, int attrs_expand_generated) +{ + db->attrs_expand_generated = attrs_expand_generated; +} + +void cil_set_attrs_expand_size(struct cil_db *db, unsigned attrs_expand_size) +{ + db->attrs_expand_size = attrs_expand_size; +} + void cil_set_preserve_tunables(struct cil_db *db, int preserve_tunables) { db->preserve_tunables = preserve_tunables; diff --git a/libsepol/cil/src/cil_binary.c b/libsepol/cil/src/cil_binary.c index ac18c4e2..e1481a43 100644 --- a/libsepol/cil/src/cil_binary.c +++ b/libsepol/cil/src/cil_binary.c @@ -567,7 +567,7 @@ int cil_typeattribute_to_policydb(policydb_t *pdb, struct cil_typeattribute *cil char *key = NULL; type_datum_t *sepol_attr = NULL; - if (cil_attr->used == CIL_FALSE) { + if (!cil_attr->used) { return SEPOL_OK; } @@ -632,7 +632,7 @@ int cil_typeattribute_to_bitmap(policydb_t *pdb, const struct cil_db *db, struct ebitmap_node_t *tnode; unsigned int i; - if (cil_attr->used == CIL_FALSE) { + if (!cil_attr->used) { return SEPOL_OK; } @@ -1429,46 +1429,20 @@ exit: return rc; } -static int __cil_type_datum_is_unused_attrib(struct cil_symtab_datum *src) +static int __cil_should_expand_attribute( const struct cil_db *db, struct cil_symtab_datum *datum) { - struct cil_tree_node *node = NULL; - struct cil_typeattribute *attrib = NULL; + struct cil_tree_node *node; + struct cil_typeattribute *attr; - if (src->fqn == CIL_KEY_SELF) { - return CIL_FALSE; - } - - node = NODE(src); + node = NODE(datum); if (node->flavor != CIL_TYPEATTRIBUTE) { return CIL_FALSE; } - attrib = (struct cil_typeattribute *) src; - return ebitmap_cardinality(attrib->types) == 0; -} - -static int __cil_avrule_can_remove(struct cil_avrule *cil_avrule) -{ - struct cil_symtab_datum *src = cil_avrule->src; - struct cil_symtab_datum *tgt = cil_avrule->tgt; - - // Don't remove neverallow rules so they are written to - // the resulting policy and can be checked by tools in - // AOSP. - if (cil_avrule->rule_kind == CIL_AVRULE_NEVERALLOW) { - return CIL_FALSE; - } - - if (__cil_type_datum_is_unused_attrib(src)) { - return CIL_TRUE; - } - - if (__cil_type_datum_is_unused_attrib(tgt)) { - return CIL_TRUE; - } + attr = (struct cil_typeattribute *)datum; - return CIL_FALSE; + return !attr->used || (ebitmap_cardinality(attr->types) < db->attrs_expand_size); } int __cil_avrule_to_avtab(policydb_t *pdb, const struct cil_db *db, struct cil_avrule *cil_avrule, cond_node_t *cond_node, enum cil_flavor cond_flavor) @@ -1478,6 +1452,9 @@ int __cil_avrule_to_avtab(policydb_t *pdb, const struct cil_db *db, struct cil_a struct cil_symtab_datum *src = NULL; struct cil_symtab_datum *tgt = NULL; struct cil_list *classperms = cil_avrule->perms.classperms; + ebitmap_t src_bitmap, tgt_bitmap; + ebitmap_node_t *snode, *tnode; + unsigned int s,t; if (cil_avrule->rule_kind == CIL_AVRULE_DONTAUDIT && db->disable_dontaudit == CIL_TRUE) { // Do not add dontaudit rules to binary @@ -1485,36 +1462,98 @@ int __cil_avrule_to_avtab(policydb_t *pdb, const struct cil_db *db, struct cil_a goto exit; } - if (__cil_avrule_can_remove(cil_avrule)) { - rc = SEPOL_OK; - goto exit; - } - src = cil_avrule->src; tgt = cil_avrule->tgt; if (tgt->fqn == CIL_KEY_SELF) { - ebitmap_t type_bitmap; - ebitmap_node_t *tnode; - unsigned int i; - - rc = __cil_expand_type(src, &type_bitmap); - if (rc != SEPOL_OK) goto exit; + rc = __cil_expand_type(src, &src_bitmap); + if (rc != SEPOL_OK) { + goto exit; + } - ebitmap_for_each_bit(&type_bitmap, tnode, i) { - if (!ebitmap_get_bit(&type_bitmap, i)) continue; + ebitmap_for_each_bit(&src_bitmap, snode, s) { + if (!ebitmap_get_bit(&src_bitmap, s)) continue; - src = DATUM(db->val_to_type[i]); + src = DATUM(db->val_to_type[s]); rc = __cil_avrule_expand(pdb, kind, src, src, classperms, cond_node, cond_flavor); if (rc != SEPOL_OK) { - ebitmap_destroy(&type_bitmap); + ebitmap_destroy(&src_bitmap); goto exit; } } - ebitmap_destroy(&type_bitmap); + ebitmap_destroy(&src_bitmap); } else { - rc = __cil_avrule_expand(pdb, kind, src, tgt, classperms, cond_node, cond_flavor); - if (rc != SEPOL_OK) goto exit; + int expand_src = __cil_should_expand_attribute(db, src); + int expand_tgt = __cil_should_expand_attribute(db, tgt); + if (!expand_src && !expand_tgt) { + rc = __cil_avrule_expand(pdb, kind, src, tgt, classperms, cond_node, cond_flavor); + if (rc != SEPOL_OK) { + goto exit; + } + } else if (expand_src && expand_tgt) { + rc = __cil_expand_type(src, &src_bitmap); + if (rc != SEPOL_OK) { + goto exit; + } + + rc = __cil_expand_type(tgt, &tgt_bitmap); + if (rc != SEPOL_OK) { + ebitmap_destroy(&src_bitmap); + goto exit; + } + + ebitmap_for_each_bit(&src_bitmap, snode, s) { + if (!ebitmap_get_bit(&src_bitmap, s)) continue; + src = DATUM(db->val_to_type[s]); + ebitmap_for_each_bit(&tgt_bitmap, tnode, t) { + if (!ebitmap_get_bit(&tgt_bitmap, t)) continue; + tgt = DATUM(db->val_to_type[t]); + + rc = __cil_avrule_expand(pdb, kind, src, tgt, classperms, cond_node, cond_flavor); + if (rc != SEPOL_OK) { + ebitmap_destroy(&src_bitmap); + ebitmap_destroy(&tgt_bitmap); + goto exit; + } + } + } + ebitmap_destroy(&src_bitmap); + ebitmap_destroy(&tgt_bitmap); + } else if (expand_src) { + rc = __cil_expand_type(src, &src_bitmap); + if (rc != SEPOL_OK) { + goto exit; + } + + ebitmap_for_each_bit(&src_bitmap, snode, s) { + if (!ebitmap_get_bit(&src_bitmap, s)) continue; + src = DATUM(db->val_to_type[s]); + + rc = __cil_avrule_expand(pdb, kind, src, tgt, classperms, cond_node, cond_flavor); + if (rc != SEPOL_OK) { + ebitmap_destroy(&src_bitmap); + goto exit; + } + } + ebitmap_destroy(&src_bitmap); + } else { /* expand_tgt */ + rc = __cil_expand_type(tgt, &tgt_bitmap); + if (rc != SEPOL_OK) { + goto exit; + } + + ebitmap_for_each_bit(&tgt_bitmap, tnode, t) { + if (!ebitmap_get_bit(&tgt_bitmap, t)) continue; + tgt = DATUM(db->val_to_type[t]); + + rc = __cil_avrule_expand(pdb, kind, src, tgt, classperms, cond_node, cond_flavor); + if (rc != SEPOL_OK) { + ebitmap_destroy(&tgt_bitmap); + goto exit; + } + } + ebitmap_destroy(&tgt_bitmap); + } } return SEPOL_OK; @@ -1789,11 +1828,9 @@ int cil_avrulex_to_hashtable(policydb_t *pdb, const struct cil_db *db, struct ci uint16_t kind; struct cil_symtab_datum *src = NULL; struct cil_symtab_datum *tgt = NULL; - ebitmap_t type_bitmap; - ebitmap_node_t *tnode; - unsigned int i; - - ebitmap_init(&type_bitmap); + ebitmap_t src_bitmap, tgt_bitmap; + ebitmap_node_t *snode, *tnode; + unsigned int s,t; if (cil_avrulex->rule_kind == CIL_AVRULE_DONTAUDIT && db->disable_dontaudit == CIL_TRUE) { // Do not add dontaudit rules to binary @@ -1806,28 +1843,97 @@ int cil_avrulex_to_hashtable(policydb_t *pdb, const struct cil_db *db, struct ci tgt = cil_avrulex->tgt; if (tgt->fqn == CIL_KEY_SELF) { - rc = __cil_expand_type(src, &type_bitmap); + rc = __cil_expand_type(src, &src_bitmap); if (rc != SEPOL_OK) goto exit; - ebitmap_for_each_bit(&type_bitmap, tnode, i) { - if (!ebitmap_get_bit(&type_bitmap, i)) continue; + ebitmap_for_each_bit(&src_bitmap, snode, s) { + if (!ebitmap_get_bit(&src_bitmap, s)) continue; - src = DATUM(db->val_to_type[i]); + src = DATUM(db->val_to_type[s]); rc = __cil_avrulex_to_hashtable_helper(pdb, kind, src, src, cil_avrulex->perms.x.permx, args); if (rc != SEPOL_OK) { goto exit; } } + ebitmap_destroy(&src_bitmap); } else { - rc = __cil_avrulex_to_hashtable_helper(pdb, kind, src, tgt, cil_avrulex->perms.x.permx, args); - if (rc != SEPOL_OK) goto exit; + int expand_src = __cil_should_expand_attribute(db, src); + int expand_tgt = __cil_should_expand_attribute(db, tgt); + + if (!expand_src && !expand_tgt) { + rc = __cil_avrulex_to_hashtable_helper(pdb, kind, src, tgt, cil_avrulex->perms.x.permx, args); + if (rc != SEPOL_OK) { + goto exit; + } + } else if (expand_src && expand_tgt) { + rc = __cil_expand_type(src, &src_bitmap); + if (rc != SEPOL_OK) { + goto exit; + } + + rc = __cil_expand_type(tgt, &tgt_bitmap); + if (rc != SEPOL_OK) { + ebitmap_destroy(&src_bitmap); + goto exit; + } + + ebitmap_for_each_bit(&src_bitmap, snode, s) { + if (!ebitmap_get_bit(&src_bitmap, s)) continue; + src = DATUM(db->val_to_type[s]); + ebitmap_for_each_bit(&tgt_bitmap, tnode, t) { + if (!ebitmap_get_bit(&tgt_bitmap, t)) continue; + tgt = DATUM(db->val_to_type[t]); + + rc = __cil_avrulex_to_hashtable_helper(pdb, kind, src, tgt, cil_avrulex->perms.x.permx, args); + if (rc != SEPOL_OK) { + ebitmap_destroy(&src_bitmap); + ebitmap_destroy(&tgt_bitmap); + goto exit; + } + } + } + ebitmap_destroy(&src_bitmap); + ebitmap_destroy(&tgt_bitmap); + } else if (expand_src) { + rc = __cil_expand_type(src, &src_bitmap); + if (rc != SEPOL_OK) { + goto exit; + } + + ebitmap_for_each_bit(&src_bitmap, snode, s) { + if (!ebitmap_get_bit(&src_bitmap, s)) continue; + src = DATUM(db->val_to_type[s]); + + rc = __cil_avrulex_to_hashtable_helper(pdb, kind, src, tgt, cil_avrulex->perms.x.permx, args); + if (rc != SEPOL_OK) { + ebitmap_destroy(&src_bitmap); + goto exit; + } + } + ebitmap_destroy(&src_bitmap); + } else { /* expand_tgt */ + rc = __cil_expand_type(tgt, &tgt_bitmap); + if (rc != SEPOL_OK) { + goto exit; + } + + ebitmap_for_each_bit(&tgt_bitmap, tnode, t) { + if (!ebitmap_get_bit(&tgt_bitmap, t)) continue; + tgt = DATUM(db->val_to_type[t]); + + rc = __cil_avrulex_to_hashtable_helper(pdb, kind, src, tgt, cil_avrulex->perms.x.permx, args); + if (rc != SEPOL_OK) { + ebitmap_destroy(&tgt_bitmap); + goto exit; + } + } + ebitmap_destroy(&tgt_bitmap); + } } - rc = SEPOL_OK; + return SEPOL_OK; exit: - ebitmap_destroy(&type_bitmap); - return rc; } @@ -2417,12 +2523,19 @@ int __cil_constrain_expr_datum_to_sepol_expr(policydb_t *pdb, const struct cil_d if (pdb->policyvers >= POLICYDB_VERSION_CONSTRAINT_NAMES) { rc = __cil_get_sepol_type_datum(pdb, item->data, &sepol_type); if (rc != SEPOL_OK) { - ebitmap_destroy(&type_bitmap); - goto exit; + if (FLAVOR(item->data) == CIL_TYPEATTRIBUTE) { + struct cil_typeattribute *attr = item->data; + if (!attr->used) { + rc = 0; + } + } } - if (ebitmap_set_bit(&expr->type_names->types, sepol_type->s.value - 1, 1)) { - ebitmap_destroy(&type_bitmap); + if (sepol_type) { + rc = ebitmap_set_bit(&expr->type_names->types, sepol_type->s.value - 1, 1); + } + + if (rc != SEPOL_OK) { goto exit; } } diff --git a/libsepol/cil/src/cil_build_ast.c b/libsepol/cil/src/cil_build_ast.c index 8a19df48..4b03dc35 100644 --- a/libsepol/cil/src/cil_build_ast.c +++ b/libsepol/cil/src/cil_build_ast.c @@ -5592,9 +5592,11 @@ int cil_gen_default(struct cil_tree_node *parse_current, struct cil_tree_node *a if (parse_current->next->cl_head == NULL) { cil_list_init(&def->class_strs, CIL_CLASS); cil_list_append(def->class_strs, CIL_STRING, parse_current->next->data); - rc = SEPOL_OK; } else { rc = cil_fill_list(parse_current->next->cl_head, CIL_CLASS, &def->class_strs); + if (rc != SEPOL_OK) { + goto exit; + } } object = parse_current->next->next->data; @@ -5657,9 +5659,11 @@ int cil_gen_defaultrange(struct cil_tree_node *parse_current, struct cil_tree_no if (parse_current->next->cl_head == NULL) { cil_list_init(&def->class_strs, CIL_CLASS); cil_list_append(def->class_strs, CIL_STRING, parse_current->next->data); - rc = SEPOL_OK; } else { rc = cil_fill_list(parse_current->next->cl_head, CIL_CLASS, &def->class_strs); + if (rc != SEPOL_OK) { + goto exit; + } } object = parse_current->next->next->data; diff --git a/libsepol/cil/src/cil_internal.h b/libsepol/cil/src/cil_internal.h index 03672bb6..efa2cd6e 100644 --- a/libsepol/cil/src/cil_internal.h +++ b/libsepol/cil/src/cil_internal.h @@ -306,6 +306,8 @@ struct cil_db { struct cil_user **val_to_user; int disable_dontaudit; int disable_neverallow; + int attrs_expand_generated; + unsigned attrs_expand_size; int preserve_tunables; int handle_unknown; int mls; @@ -513,11 +515,14 @@ struct cil_type { int value; }; +#define CIL_ATTR_AVRULE 0x01 +#define CIL_ATTR_NEVERALLOW 0x02 +#define CIL_ATTR_CONSTRAINT 0x04 struct cil_typeattribute { struct cil_symtab_datum datum; struct cil_list *expr_list; ebitmap_t *types; - int used; // whether or not this typeattribute was used and should be added to the binary + int used; // whether or not this attribute was used in a binary policy rule }; struct cil_typeattributeset { diff --git a/libsepol/cil/src/cil_post.c b/libsepol/cil/src/cil_post.c index 089c02f9..e32a8fc9 100644 --- a/libsepol/cil/src/cil_post.c +++ b/libsepol/cil/src/cil_post.c @@ -1188,22 +1188,32 @@ exit: return SEPOL_ERR; } -static int cil_typeattribute_used(struct cil_typeattribute *cil_attr) +static int cil_typeattribute_used(struct cil_typeattribute *attr, struct cil_db *db) { - if (cil_attr->used) { - return CIL_TRUE; + if (!attr->used) { + return CIL_FALSE; } - if (strcmp(DATUM(cil_attr)->name, GEN_REQUIRE_ATTR) == 0) { - return CIL_FALSE; + if (attr->used & CIL_ATTR_CONSTRAINT) { + return CIL_TRUE; } - if (strstr(DATUM(cil_attr)->name,TYPEATTR_INFIX) != NULL) { - return CIL_FALSE; + if (db->attrs_expand_generated || attr->used == CIL_ATTR_NEVERALLOW) { + if (strcmp(DATUM(attr)->name, GEN_REQUIRE_ATTR) == 0) { + return CIL_FALSE; + } else if (strstr(DATUM(attr)->name, TYPEATTR_INFIX) != NULL) { + return CIL_FALSE; + } + + if (attr->used == CIL_ATTR_NEVERALLOW) { + return CIL_TRUE; + } } - if (ebitmap_cardinality(cil_attr->types) == 0) { - return CIL_FALSE; + if (attr->used == CIL_ATTR_AVRULE) { + if (ebitmap_cardinality(attr->types) < db->attrs_expand_size) { + return CIL_FALSE; + } } return CIL_TRUE; @@ -1231,10 +1241,8 @@ static int __cil_post_db_attr_helper(struct cil_tree_node *node, uint32_t *finis if (attr->types == NULL) { rc = __evaluate_type_expression(attr, db); if (rc != SEPOL_OK) goto exit; - if (cil_typeattribute_used(attr)) { - attr->used = CIL_TRUE; - } } + attr->used = cil_typeattribute_used(attr, db); break; } case CIL_ROLEATTRIBUTE: { diff --git a/libsepol/cil/src/cil_resolve_ast.c b/libsepol/cil/src/cil_resolve_ast.c index 18705011..6da44ba1 100644 --- a/libsepol/cil/src/cil_resolve_ast.c +++ b/libsepol/cil/src/cil_resolve_ast.c @@ -269,13 +269,13 @@ exit: return rc; } -int cil_type_used(struct cil_symtab_datum *datum) +int cil_type_used(struct cil_symtab_datum *datum, int used) { struct cil_typeattribute *attr = NULL; if (FLAVOR(datum) == CIL_TYPEATTRIBUTE) { attr = (struct cil_typeattribute*)datum; - attr->used = CIL_TRUE; + attr->used |= used; } return 0; @@ -307,6 +307,7 @@ int cil_resolve_avrule(struct cil_tree_node *current, void *extra_args) struct cil_symtab_datum *src_datum = NULL; struct cil_symtab_datum *tgt_datum = NULL; struct cil_symtab_datum *permx_datum = NULL; + int used; int rc = SEPOL_ERR; if (args != NULL) { @@ -318,9 +319,6 @@ int cil_resolve_avrule(struct cil_tree_node *current, void *extra_args) goto exit; } rule->src = src_datum; - if (rule->rule_kind != CIL_AVRULE_NEVERALLOW) { - cil_type_used(src_datum); - } if (rule->tgt_str == CIL_KEY_SELF) { rule->tgt = db->selftype; @@ -330,9 +328,10 @@ int cil_resolve_avrule(struct cil_tree_node *current, void *extra_args) goto exit; } rule->tgt = tgt_datum; - if (rule->rule_kind != CIL_AVRULE_NEVERALLOW) { - cil_type_used(tgt_datum); - } + used = (rule->rule_kind == CIL_AVRULE_NEVERALLOW) ? + CIL_ATTR_NEVERALLOW : CIL_ATTR_AVRULE; + cil_type_used(src_datum, used); /* src not used if tgt is self */ + cil_type_used(tgt_datum, used); } if (!rule->is_extended) { @@ -376,14 +375,12 @@ int cil_resolve_type_rule(struct cil_tree_node *current, void *extra_args) goto exit; } rule->src = src_datum; - cil_type_used(src_datum); rc = cil_resolve_name(current, rule->tgt_str, CIL_SYM_TYPES, extra_args, &tgt_datum); if (rc != SEPOL_OK) { goto exit; } rule->tgt = tgt_datum; - cil_type_used(tgt_datum); rc = cil_resolve_name(current, rule->obj_str, CIL_SYM_CLASSES, extra_args, &obj_datum); if (rc != SEPOL_OK) { @@ -589,14 +586,12 @@ int cil_resolve_nametypetransition(struct cil_tree_node *current, void *extra_ar goto exit; } nametypetrans->src = src_datum; - cil_type_used(src_datum); rc = cil_resolve_name(current, nametypetrans->tgt_str, CIL_SYM_TYPES, extra_args, &tgt_datum); if (rc != SEPOL_OK) { goto exit; } nametypetrans->tgt = tgt_datum; - cil_type_used(tgt_datum); rc = cil_resolve_name(current, nametypetrans->obj_str, CIL_SYM_CLASSES, extra_args, &obj_datum); if (rc != SEPOL_OK) { @@ -647,14 +642,12 @@ int cil_resolve_rangetransition(struct cil_tree_node *current, void *extra_args) goto exit; } rangetrans->src = src_datum; - cil_type_used(src_datum); rc = cil_resolve_name(current, rangetrans->exec_str, CIL_SYM_TYPES, extra_args, &exec_datum); if (rc != SEPOL_OK) { goto exit; } rangetrans->exec = exec_datum; - cil_type_used(exec_datum); rc = cil_resolve_name(current, rangetrans->obj_str, CIL_SYM_CLASSES, extra_args, &obj_datum); if (rc != SEPOL_OK) { @@ -1006,7 +999,6 @@ int cil_resolve_roletype(struct cil_tree_node *current, void *extra_args) goto exit; } roletype->type = (struct cil_type*)type_datum; - cil_type_used(type_datum); return SEPOL_OK; @@ -1035,7 +1027,6 @@ int cil_resolve_roletransition(struct cil_tree_node *current, void *extra_args) goto exit; } roletrans->tgt = tgt_datum; - cil_type_used(tgt_datum); rc = cil_resolve_name(current, roletrans->obj_str, CIL_SYM_CLASSES, extra_args, &obj_datum); if (rc != SEPOL_OK) { @@ -3108,7 +3099,7 @@ int cil_resolve_expr(enum cil_flavor expr_type, struct cil_list *str_expr, struc } if (sym_index == CIL_SYM_TYPES && (expr_type == CIL_CONSTRAIN || expr_type == CIL_VALIDATETRANS)) { - cil_type_used(res_datum); + cil_type_used(res_datum, CIL_ATTR_CONSTRAINT); } cil_list_append(*datum_expr, CIL_DATUM, res_datum); diff --git a/libsepol/src/boolean_record.c b/libsepol/src/boolean_record.c index ebef7f18..a194704e 100644 --- a/libsepol/src/boolean_record.c +++ b/libsepol/src/boolean_record.c @@ -67,6 +67,8 @@ int sepol_bool_key_extract(sepol_handle_t * handle, void sepol_bool_key_free(sepol_bool_key_t * key) { + if (!key) + return; free(key->name); free(key); } diff --git a/libsepol/src/expand.c b/libsepol/src/expand.c index 315fc65c..54bf781d 100644 --- a/libsepol/src/expand.c +++ b/libsepol/src/expand.c @@ -2527,7 +2527,7 @@ int type_set_expand(type_set_t * set, ebitmap_t * t, policydb_t * p, * invalid policies might have more types set in the ebitmap than * what's available in the type_val_to_struct mapping */ - if (i > p->p_types.nprim - 1) + if (i >= p->p_types.nprim) goto err_types; if (!p->type_val_to_struct[i]) { diff --git a/libsepol/src/iface_record.c b/libsepol/src/iface_record.c index c8b977c8..6d568355 100644 --- a/libsepol/src/iface_record.c +++ b/libsepol/src/iface_record.c @@ -73,6 +73,8 @@ int sepol_iface_key_extract(sepol_handle_t * handle, void sepol_iface_key_free(sepol_iface_key_t * key) { + if (!key) + return; free(key->name); free(key); } diff --git a/libsepol/src/libsepol.map.in b/libsepol/src/libsepol.map.in index 5e68fcbb..40426408 100644 --- a/libsepol/src/libsepol.map.in +++ b/libsepol/src/libsepol.map.in @@ -45,6 +45,8 @@ LIBSEPOL_1.1 { cil_set_target_platform; cil_set_policy_version; cil_set_mls; + cil_set_attrs_expand_generated; + cil_set_attrs_expand_size; cil_write_policy_conf; sepol_ppfile_to_module_package; sepol_module_package_to_cil; diff --git a/libsepol/src/module_to_cil.c b/libsepol/src/module_to_cil.c index 3f633fbb..ac095c30 100644 --- a/libsepol/src/module_to_cil.c +++ b/libsepol/src/module_to_cil.c @@ -791,8 +791,8 @@ static int cil_print_attr_strs(int indent, struct policydb *pdb, int is_type, vo // CIL doesn't support anonymous positive/negative/complemented sets. So // instead we create a CIL type/roleattributeset that matches the set. If // the set has a negative set, then convert it to is (P & !N), where P is - // the list of members in the positive set , and N is the list of members - // in the negative set. Additonally, if the set is complemented, then wrap + // the list of members in the positive set and N is the list of members + // in the negative set. Additionally, if the set is complemented, then wrap // the whole thing with a negation. struct ebitmap_node *node; @@ -962,7 +962,6 @@ static int set_to_names(struct policydb *pdb, int is_type, void *set, struct lis *names = malloc(sizeof(char *)); if (!*names) { log_err("Out of memory"); - free(attr_name); rc = -1; goto exit; } @@ -1154,6 +1153,7 @@ static int name_list_to_string(char **names, int num_names, char **string) return 0; exit: + free(str); return rc; } @@ -1698,7 +1698,7 @@ static int constraint_expr_to_string(struct policydb *pdb, struct constraint_exp const char *fmt_str; const char *attr1; const char *attr2; - char *names; + char *names = NULL; char **name_list = NULL; int num_names = 0; struct type_set *ts; @@ -1799,6 +1799,7 @@ static int constraint_expr_to_string(struct policydb *pdb, struct constraint_exp names_destroy(&name_list, &num_names); free(names); + names = NULL; } num_params = 0; @@ -1888,6 +1889,7 @@ static int constraint_expr_to_string(struct policydb *pdb, struct constraint_exp exit: names_destroy(&name_list, &num_names); + free(names); free(new_val); free(val1); @@ -2101,13 +2103,13 @@ static int role_to_cil(int indent, struct policydb *pdb, struct avrule_block *UN // the policy type, it would result in duplicate declarations, // which isn't allowed in CIL. Patches have been made to refpolicy // to remove these duplicate role declarations, but we need to be - // backwards compatable and support older policies. Since we know + // backwards compatible and support older policies. Since we know // these roles are always declared in base, only print them when we // see them in the base module. If the declarations appear in a // non-base module, ignore their declarations. // // Note that this is a hack, and if a policy author does not define - // one of these roles in base, the declaration will not appeaer in + // one of these roles in base, the declaration will not appear in // the resulting policy, likely resulting in a compilation error in // CIL. // @@ -2287,7 +2289,7 @@ static int user_to_cil(int indent, struct policydb *pdb, struct avrule_block *bl if (block->flags & AVRULE_OPTIONAL) { // sensitivites in user statements in optionals do not have the - // standard -1 offest + // standard -1 offset sens_offset = 0; } diff --git a/libsepol/src/policydb.c b/libsepol/src/policydb.c index 3cff6d27..7093b298 100644 --- a/libsepol/src/policydb.c +++ b/libsepol/src/policydb.c @@ -4044,6 +4044,10 @@ int policydb_read(policydb_t * p, struct policy_file *fp, unsigned verbose) if (avrule_block_read(p, &p->global, info->sym_num, fp) == -1) { goto bad; } + if (p->global == NULL) { + ERR(fp->handle, "no avrule block in policy"); + goto bad; + } for (i = 0; i < info->sym_num; i++) { if ((rc = next_entry(buf, fp, sizeof(uint32_t))) < 0) { goto bad; diff --git a/libsepol/src/user_record.c b/libsepol/src/user_record.c index ed5b0482..fa95f2d1 100644 --- a/libsepol/src/user_record.c +++ b/libsepol/src/user_record.c @@ -76,6 +76,8 @@ int sepol_user_key_extract(sepol_handle_t * handle, void sepol_user_key_free(sepol_user_key_t * key) { + if (!key) + return; free(key->name); free(key); } diff --git a/policycoreutils/load_policy/load_policy.c b/policycoreutils/load_policy/load_policy.c index 7c2c2a78..2707d6fe 100644 --- a/policycoreutils/load_policy/load_policy.c +++ b/policycoreutils/load_policy/load_policy.c @@ -65,13 +65,6 @@ int main(int argc, char **argv) argv[0], argv[optind++]); } if (init) { - if (is_selinux_enabled() == 1) { - /* SELinux is already enabled, we should not do an initial load again */ - fprintf(stderr, - _("%s: Policy is already loaded and initial load requested\n"), - argv[0]); - exit(2); - } ret = selinux_init_load_policy(&enforce); if (ret != 0 ) { if (enforce > 0) { diff --git a/policycoreutils/newrole/newrole.c b/policycoreutils/newrole/newrole.c index faf937b9..077496d3 100644 --- a/policycoreutils/newrole/newrole.c +++ b/policycoreutils/newrole/newrole.c @@ -412,7 +412,7 @@ static int verify_shell(const char *shell_name) * This function assigns malloc'd memory into the pw_copy struct. * Returns zero on success, non-zero otherwise */ -int extract_pw_data(struct passwd *pw_copy) +static int extract_pw_data(struct passwd *pw_copy) { uid_t uid; struct passwd *pw; @@ -456,6 +456,9 @@ int extract_pw_data(struct passwd *pw_copy) free(pw->pw_name); free(pw->pw_dir); free(pw->pw_shell); + pw->pw_name = NULL; + pw->pw_dir = NULL; + pw->pw_shell = NULL; return -1; } @@ -1110,6 +1113,7 @@ int main(int argc, char *argv[]) * malicious software), not to authorize the operation (which is covered * by policy). Trusted path mechanism would be preferred. */ + memset(&pw, 0, sizeof(pw)); if (extract_pw_data(&pw)) goto err_free; diff --git a/secilc/secil2conf.c b/secilc/secil2conf.c index 5d8fe870..4e97dd66 100644 --- a/secilc/secil2conf.c +++ b/secilc/secil2conf.c @@ -124,6 +124,8 @@ int main(int argc, char *argv[]) cil_db_init(&db); cil_set_preserve_tunables(db, preserve_tunables); cil_set_mls(db, mls); + cil_set_attrs_expand_generated(db, 0); + cil_set_attrs_expand_size(db, 0); for (i = optind; i < argc; i++) { file = fopen(argv[i], "r"); diff --git a/secilc/secilc.8.xml b/secilc/secilc.8.xml index 9e2670b1..4c779b64 100644 --- a/secilc/secilc.8.xml +++ b/secilc/secilc.8.xml @@ -81,6 +81,16 @@ </varlistentry> <varlistentry> + <term><option>-G, --expand-generated</option></term> + <listitem><para>Expand and remove auto-generated attributes</para></listitem> + </varlistentry> + + <varlistentry> + <term><option>-X, --attrs-size <size></option></term> + <listitem><para>Expand type attributes with fewer than <emphasis role="bold"><SIZE></emphasis> members.</para></listitem> + </varlistentry> + + <varlistentry> <term><option>-v, --verbose</option></term> <listitem><para>Increment verbosity level.</para></listitem> </varlistentry> diff --git a/secilc/secilc.c b/secilc/secilc.c index f4ecbeec..f2232e72 100644 --- a/secilc/secilc.c +++ b/secilc/secilc.c @@ -64,6 +64,9 @@ static __attribute__((__noreturn__)) void usage(const char *prog) printf(" -D, --disable-dontaudit do not add dontaudit rules to the binary policy\n"); printf(" -P, --preserve-tunables treat tunables as booleans\n"); printf(" -N, --disable-neverallow do not check neverallow rules\n"); + printf(" -G, --expand-generated Expand and remove auto-generated attributes\n"); + printf(" -X, --expand-size <SIZE> Expand type attributes with fewer than <SIZE>\n"); + printf(" members.\n"); printf(" -v, --verbose increment verbosity level\n"); printf(" -h, --help display usage information\n"); exit(1); @@ -90,6 +93,8 @@ int main(int argc, char *argv[]) int preserve_tunables = 0; int handle_unknown = -1; int policyvers = POLICYDB_VERSION_MAX; + int attrs_expand_generated = 0; + int attrs_expand_size = -1; int opt_char; int opt_index = 0; char *fc_buf = NULL; @@ -107,12 +112,14 @@ int main(int argc, char *argv[]) {"preserve-tunables", no_argument, 0, 'P'}, {"output", required_argument, 0, 'o'}, {"filecontexts", required_argument, 0, 'f'}, + {"expand-generated", no_argument, 0, 'G'}, + {"expand-size", required_argument, 0, 'X'}, {0, 0, 0, 0} }; int i; while (1) { - opt_char = getopt_long(argc, argv, "o:f:U:hvt:M:PDNc:", long_opts, &opt_index); + opt_char = getopt_long(argc, argv, "o:f:U:hvt:M:PDNc:GX:", long_opts, &opt_index); if (opt_char == -1) { break; } @@ -180,6 +187,24 @@ int main(int argc, char *argv[]) case 'f': filecontexts = strdup(optarg); break; + case 'G': + attrs_expand_generated = 1; + break; + case 'X': { + char *endptr = NULL; + errno = 0; + attrs_expand_size = strtol(optarg, &endptr, 10); + if (errno != 0 || endptr == optarg || *endptr != '\0') { + fprintf(stderr, "Bad attribute expand size: %s\n", optarg); + usage(argv[0]); + } + + if (attrs_expand_size < 0) { + fprintf(stderr, "Attribute expand size must be > 0\n"); + usage(argv[0]); + } + break; + } case 'h': usage(argv[0]); case '?': @@ -210,6 +235,10 @@ int main(int argc, char *argv[]) cil_set_mls(db, mls); cil_set_target_platform(db, target); cil_set_policy_version(db, policyvers); + cil_set_attrs_expand_generated(db, attrs_expand_generated); + if (attrs_expand_size >= 0) { + cil_set_attrs_expand_size(db, (unsigned)attrs_expand_size); + } for (i = optind; i < argc; i++) { file = fopen(argv[i], "r"); |