@@ -529,23 +529,31 @@ exit:
return rc;
}
-static int write_sids_to_cil(FILE *out, const char *const *sid_to_str, struct ocontext *isids)
+static int write_sids_to_cil(FILE *out, const char *const *sid_to_str,
+ unsigned num_sids, struct ocontext *isids)
{
struct ocontext *isid;
struct strs *strs;
char *sid;
char *prev;
+ char unknown[17];
unsigned i;
int rc;
- rc = strs_init(&strs, SECINITSID_NUM+1);
+ rc = strs_init(&strs, num_sids+1);
if (rc != 0) {
goto exit;
}
for (isid = isids; isid != NULL; isid = isid->next) {
i = isid->sid[0];
- rc = strs_add_at_index(strs, (char *)sid_to_str[i], i);
+ if (i < num_sids) {
+ sid = (char *)sid_to_str[i];
+ } else {
+ snprintf(unknown, 17, "%s%u", "UNKNOWN", i);
+ sid = strdup(unknown);
+ }
+ rc = strs_add_at_index(strs, sid, i);
if (rc != 0) {
goto exit;
}
@@ -577,6 +585,10 @@ static int write_sids_to_cil(FILE *out, const char *const *sid_to_str, struct oc
sepol_printf(out, "))\n");
exit:
+ for (i=num_sids; i<strs_num_items(strs); i++) {
+ sid = strs_read_at_index(strs, i);
+ free(sid);
+ }
strs_destroy(&strs);
if (rc != 0) {
sepol_log_err("Error writing sid rules to CIL\n");
@@ -590,9 +602,11 @@ static int write_sid_decl_rules_to_cil(FILE *out, struct policydb *pdb)
int rc = 0;
if (pdb->target_platform == SEPOL_TARGET_SELINUX) {
- rc = write_sids_to_cil(out, selinux_sid_to_str, pdb->ocontexts[0]);
+ rc = write_sids_to_cil(out, selinux_sid_to_str, SELINUX_SID_SZ,
+ pdb->ocontexts[0]);
} else if (pdb->target_platform == SEPOL_TARGET_XEN) {
- rc = write_sids_to_cil(out, xen_sid_to_str, pdb->ocontexts[0]);
+ rc = write_sids_to_cil(out, xen_sid_to_str, XEN_SID_SZ,
+ pdb->ocontexts[0]);
} else {
sepol_log_err("Unknown target platform: %i", pdb->target_platform);
rc = -1;
@@ -2479,11 +2493,12 @@ exit:
return ctx;
}
-static int write_sid_context_rules_to_cil(FILE *out, struct policydb *pdb, const char *const *sid_to_str)
+static int write_sid_context_rules_to_cil(FILE *out, struct policydb *pdb, const char *const *sid_to_str, unsigned num_sids)
{
struct ocontext *isid;
struct strs *strs;
- const char *sid;
+ char *sid;
+ char unknown[17];
char *ctx, *rule;
unsigned i;
int rc = -1;
@@ -2495,7 +2510,13 @@ static int write_sid_context_rules_to_cil(FILE *out, struct policydb *pdb, const
for (isid = pdb->ocontexts[0]; isid != NULL; isid = isid->next) {
i = isid->sid[0];
- sid = sid_to_str[i];
+ if (i < num_sids) {
+ sid = (char *)sid_to_str[i];
+ } else {
+ snprintf(unknown, 17, "%s%u", "UNKNOWN", i);
+ sid = unknown;
+ }
+
ctx = context_to_str(pdb, &isid->context[0]);
if (!ctx) {
rc = -1;
@@ -2531,7 +2552,8 @@ exit:
static int write_selinux_isid_rules_to_cil(FILE *out, struct policydb *pdb)
{
- return write_sid_context_rules_to_cil(out, pdb, selinux_sid_to_str);
+ return write_sid_context_rules_to_cil(out, pdb, selinux_sid_to_str,
+ SELINUX_SID_SZ);
}
static int write_selinux_fsuse_rules_to_cil(FILE *out, struct policydb *pdb)
@@ -2884,7 +2906,7 @@ exit:
static int write_xen_isid_rules_to_cil(FILE *out, struct policydb *pdb)
{
- return write_sid_context_rules_to_cil(out, pdb, xen_sid_to_str);
+ return write_sid_context_rules_to_cil(out, pdb, xen_sid_to_str, XEN_SID_SZ);
}
static int write_xen_pirq_rules_to_cil(FILE *out, struct policydb *pdb)
@@ -43,6 +43,8 @@ static const char * const selinux_sid_to_str[] = {
"devnull",
};
+#define SELINUX_SID_SZ (sizeof(selinux_sid_to_str)/sizeof(selinux_sid_to_str[0]))
+
static const char * const xen_sid_to_str[] = {
"null",
"xen",
@@ -57,6 +59,8 @@ static const char * const xen_sid_to_str[] = {
"device",
};
+#define XEN_SID_SZ (sizeof(xen_sid_to_str)/sizeof(xen_sid_to_str[0]))
+
static const uint32_t avtab_flavors[] = {
AVTAB_ALLOWED,
AVTAB_AUDITALLOW,
@@ -428,22 +428,30 @@ static int write_class_decl_rules_to_conf(FILE *out, struct policydb *pdb)
return 0;
}
-static int write_sids_to_conf(FILE *out, const char *const *sid_to_str, struct ocontext *isids)
+static int write_sids_to_conf(FILE *out, const char *const *sid_to_str,
+ unsigned num_sids, struct ocontext *isids)
{
struct ocontext *isid;
struct strs *strs;
char *sid;
+ char unknown[17];
unsigned i;
int rc;
- rc = strs_init(&strs, SECINITSID_NUM+1);
+ rc = strs_init(&strs, num_sids+1);
if (rc != 0) {
goto exit;
}
for (isid = isids; isid != NULL; isid = isid->next) {
i = isid->sid[0];
- rc = strs_add_at_index(strs, (char *)sid_to_str[i], i);
+ if (i < num_sids) {
+ sid = (char *)sid_to_str[i];
+ } else {
+ snprintf(unknown, 17, "%s%u", "UNKNOWN", i);
+ sid = strdup(unknown);
+ }
+ rc = strs_add_at_index(strs, sid, i);
if (rc != 0) {
goto exit;
}
@@ -458,6 +466,10 @@ static int write_sids_to_conf(FILE *out, const char *const *sid_to_str, struct o
}
exit:
+ for (i=num_sids; i<strs_num_items(strs); i++) {
+ sid = strs_read_at_index(strs, i);
+ free(sid);
+ }
strs_destroy(&strs);
if (rc != 0) {
sepol_log_err("Error writing sid rules to policy.conf\n");
@@ -471,9 +483,11 @@ static int write_sid_decl_rules_to_conf(FILE *out, struct policydb *pdb)
int rc = 0;
if (pdb->target_platform == SEPOL_TARGET_SELINUX) {
- rc = write_sids_to_conf(out, selinux_sid_to_str, pdb->ocontexts[0]);
+ rc = write_sids_to_conf(out, selinux_sid_to_str, SELINUX_SID_SZ,
+ pdb->ocontexts[0]);
} else if (pdb->target_platform == SEPOL_TARGET_XEN) {
- rc = write_sids_to_conf(out, xen_sid_to_str, pdb->ocontexts[0]);
+ rc = write_sids_to_conf(out, xen_sid_to_str, XEN_SID_SZ,
+ pdb->ocontexts[0]);
} else {
sepol_log_err("Unknown target platform: %i", pdb->target_platform);
rc = -1;
@@ -2339,11 +2353,12 @@ static char *context_to_str(struct policydb *pdb, struct context_struct *con)
return ctx;
}
-static int write_sid_context_rules_to_conf(FILE *out, struct policydb *pdb, const char *const *sid_to_str)
+static int write_sid_context_rules_to_conf(FILE *out, struct policydb *pdb, const char *const *sid_to_str, unsigned num_sids)
{
struct ocontext *isid;
struct strs *strs;
- const char *sid;
+ char *sid;
+ char unknown[17];
char *ctx, *rule;
unsigned i;
int rc;
@@ -2355,7 +2370,13 @@ static int write_sid_context_rules_to_conf(FILE *out, struct policydb *pdb, cons
for (isid = pdb->ocontexts[0]; isid != NULL; isid = isid->next) {
i = isid->sid[0];
- sid = sid_to_str[i];
+ if (i < num_sids) {
+ sid = (char *)sid_to_str[i];
+ } else {
+ snprintf(unknown, 17, "%s%u", "UNKNOWN", i);
+ sid = unknown;
+ }
+
ctx = context_to_str(pdb, &isid->context[0]);
if (!ctx) {
rc = -1;
@@ -2391,7 +2412,8 @@ exit:
static int write_selinux_isid_rules_to_conf(FILE *out, struct policydb *pdb)
{
- return write_sid_context_rules_to_conf(out, pdb, selinux_sid_to_str);
+ return write_sid_context_rules_to_conf(out, pdb, selinux_sid_to_str,
+ SELINUX_SID_SZ);
}
static int write_selinux_fsuse_rules_to_conf(FILE *out, struct policydb *pdb)
@@ -2745,7 +2767,7 @@ exit:
static int write_xen_isid_rules_to_conf(FILE *out, struct policydb *pdb)
{
- return write_sid_context_rules_to_conf(out, pdb, xen_sid_to_str);
+ return write_sid_context_rules_to_conf(out, pdb, xen_sid_to_str, XEN_SID_SZ);
}
@@ -2548,23 +2548,33 @@ static int context_to_cil(struct policydb *pdb, struct context_struct *con)
}
static int ocontext_isid_to_cil(struct policydb *pdb, const char *const *sid_to_string,
- struct ocontext *isids)
+ unsigned num_sids, struct ocontext *isids)
{
int rc = -1;
struct ocontext *isid;
struct sid_item {
- const char *sid_key;
+ char *sid_key;
struct sid_item *next;
};
struct sid_item *head = NULL;
struct sid_item *item = NULL;
+ char *sid;
+ char unknown[17];
+ unsigned i;
for (isid = isids; isid != NULL; isid = isid->next) {
- cil_println(0, "(sid %s)", sid_to_string[isid->sid[0]]);
- cil_printf("(sidcontext %s ", sid_to_string[isid->sid[0]]);
+ i = isid->sid[0];
+ if (i < num_sids) {
+ sid = (char*)sid_to_string[i];
+ } else {
+ snprintf(unknown, 17, "%s%u", "UNKNOWN", i);
+ sid = unknown;
+ }
+ cil_println(0, "(sid %s)", sid);
+ cil_printf("(sidcontext %s ", sid);
context_to_cil(pdb, &isid->context[0]);
cil_printf(")\n");
@@ -2576,7 +2586,7 @@ static int ocontext_isid_to_cil(struct policydb *pdb, const char *const *sid_to_
rc = -1;
goto exit;
}
- item->sid_key = sid_to_string[isid->sid[0]];
+ item->sid_key = strdup(sid);
item->next = head;
head = item;
}
@@ -2595,6 +2605,7 @@ exit:
while(head) {
item = head;
head = item->next;
+ free(item->sid_key);
free(item);
}
return rc;
@@ -2604,7 +2615,7 @@ static int ocontext_selinux_isid_to_cil(struct policydb *pdb, struct ocontext *i
{
int rc = -1;
- rc = ocontext_isid_to_cil(pdb, selinux_sid_to_str, isids);
+ rc = ocontext_isid_to_cil(pdb, selinux_sid_to_str, SELINUX_SID_SZ, isids);
if (rc != 0) {
goto exit;
}
@@ -2833,7 +2844,7 @@ static int ocontext_xen_isid_to_cil(struct policydb *pdb, struct ocontext *isids
{
int rc = -1;
- rc = ocontext_isid_to_cil(pdb, xen_sid_to_str, isids);
+ rc = ocontext_isid_to_cil(pdb, xen_sid_to_str, XEN_SID_SZ, isids);
if (rc != 0) {
goto exit;
}
When writing CIL from a policy module or when writing CIL or policy.conf from a kernel binary policy, check that the initial sid index is within the valid range of the selinux_sid_to_str[] array (or xen_sid_to_str[] array for a XEN policy). If it is not, then create a unique name ("UNKNOWN"+index) for the initial sid. Signed-off-by: James Carter <jwcart2@tycho.nsa.gov> --- libsepol/src/kernel_to_cil.c | 42 +++++++++++++++++++++++++-------- libsepol/src/kernel_to_common.h | 4 ++++ libsepol/src/kernel_to_conf.c | 42 +++++++++++++++++++++++++-------- libsepol/src/module_to_cil.c | 25 ++++++++++++++------ 4 files changed, 86 insertions(+), 27 deletions(-)