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 <[email protected]>
---
 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(-)

diff --git a/libsepol/src/kernel_to_cil.c b/libsepol/src/kernel_to_cil.c
index c2a733ee..d173144e 100644
--- a/libsepol/src/kernel_to_cil.c
+++ b/libsepol/src/kernel_to_cil.c
@@ -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)
diff --git a/libsepol/src/kernel_to_common.h b/libsepol/src/kernel_to_common.h
index 7c5edbd6..dacfe97e 100644
--- a/libsepol/src/kernel_to_common.h
+++ b/libsepol/src/kernel_to_common.h
@@ -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,
diff --git a/libsepol/src/kernel_to_conf.c b/libsepol/src/kernel_to_conf.c
index a98b5ca9..7e04a13b 100644
--- a/libsepol/src/kernel_to_conf.c
+++ b/libsepol/src/kernel_to_conf.c
@@ -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);
 }
 
 
diff --git a/libsepol/src/module_to_cil.c b/libsepol/src/module_to_cil.c
index 8ab0dfce..7fc29cbd 100644
--- a/libsepol/src/module_to_cil.c
+++ b/libsepol/src/module_to_cil.c
@@ -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;
        }
-- 
2.17.1

_______________________________________________
Selinux mailing list
[email protected]
To unsubscribe, send email to [email protected].
To get help, send an email containing "help" to [email protected].

Reply via email to