aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libselinux/src/audit2why.c4
-rw-r--r--libselinux/src/booleans.c72
-rw-r--r--libselinux/src/canonicalize_context.c2
-rw-r--r--libselinux/src/check_context.c2
-rw-r--r--libselinux/src/compute_av.c2
-rw-r--r--libselinux/src/compute_create.c2
-rw-r--r--libselinux/src/compute_member.c2
-rw-r--r--libselinux/src/compute_relabel.c2
-rw-r--r--libselinux/src/compute_user.c2
-rw-r--r--libselinux/src/deny_unknown.c2
-rw-r--r--libselinux/src/disable.c2
-rw-r--r--libselinux/src/enabled.c2
-rw-r--r--libselinux/src/get_context_list.c6
-rw-r--r--libselinux/src/get_default_type.c2
-rw-r--r--libselinux/src/get_initial_context.c2
-rw-r--r--libselinux/src/getenforce.c2
-rw-r--r--libselinux/src/init.c4
-rw-r--r--libselinux/src/is_customizable_type.c2
-rw-r--r--libselinux/src/label.c10
-rw-r--r--libselinux/src/label_backends_android.c2
-rw-r--r--libselinux/src/label_file.c2
-rw-r--r--libselinux/src/label_media.c2
-rw-r--r--libselinux/src/label_x.c2
-rw-r--r--libselinux/src/load_policy.c8
-rw-r--r--libselinux/src/matchmediacon.c2
-rw-r--r--libselinux/src/policyvers.c2
-rw-r--r--libselinux/src/procattr.c4
-rw-r--r--libselinux/src/selinux_check_securetty_context.c2
-rw-r--r--libselinux/src/selinux_config.c4
-rw-r--r--libselinux/src/selinux_restorecon.c10
-rw-r--r--libselinux/src/setenforce.c2
-rw-r--r--libselinux/src/seusers.c4
-rw-r--r--libselinux/src/stringrep.c2
-rw-r--r--libselinux/utils/getsebool.c7
-rw-r--r--libsemanage/src/direct_api.c42
-rw-r--r--libsepol/cil/include/cil/cil.h2
-rw-r--r--libsepol/cil/src/cil.c12
-rw-r--r--libsepol/cil/src/cil_binary.c253
-rw-r--r--libsepol/cil/src/cil_build_ast.c8
-rw-r--r--libsepol/cil/src/cil_internal.h7
-rw-r--r--libsepol/cil/src/cil_post.c32
-rw-r--r--libsepol/cil/src/cil_resolve_ast.c25
-rw-r--r--libsepol/src/boolean_record.c2
-rw-r--r--libsepol/src/expand.c2
-rw-r--r--libsepol/src/iface_record.c2
-rw-r--r--libsepol/src/libsepol.map.in2
-rw-r--r--libsepol/src/module_to_cil.c16
-rw-r--r--libsepol/src/policydb.c4
-rw-r--r--libsepol/src/user_record.c2
-rw-r--r--policycoreutils/load_policy/load_policy.c7
-rw-r--r--policycoreutils/newrole/newrole.c6
-rw-r--r--secilc/secil2conf.c2
-rw-r--r--secilc/secilc.8.xml10
-rw-r--r--secilc/secilc.c31
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 &lt;size></option></term>
+ <listitem><para>Expand type attributes with fewer than <emphasis role="bold">&lt;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");