Skip to content

Commit ab28db8

Browse files
jwcart2stephensmalley
authored andcommitted
libsepol: Fix sid handling when writing out policy from binary
Initial sids are stored only as unsigned 32-bit numbers in a binary policy. When a binary kernel policy is converted to CIL or a policy.conf or a binary base module is converted to CIL, a mapping in kernel_to_common.h is used to determine the name of the initial sid. A problem can occur when policy converted from binary to text is once again compiled. The initial sids will not be the correct number if there are gaps in the list of initial sids. This will cause the effected initial sids to be interpreted by the kernel as a different initial sid. When writing out sid and sidorder statements in CIL, write out all the initial sids from kernel (which is initial sid SELinuxProject#1) to the initial sid with the highest number associated with it. In the same way, when writing out sid statements for a policy.conf, all the initial sids from the first to the highest numbered must be written out with no gaps. No changes are needed when writing out statements associating an initial sid with a security context. There can be gaps in these statements. The numbering is taken from the declarations. Signed-off-by: James Carter <[email protected]>
1 parent 78cf3cc commit ab28db8

File tree

5 files changed

+121
-122
lines changed

5 files changed

+121
-122
lines changed

libsepol/src/kernel_to_cil.c

Lines changed: 10 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -565,54 +565,31 @@ static int write_class_decl_rules_to_cil(FILE *out, struct policydb *pdb)
565565
static int write_sids_to_cil(FILE *out, const char *const *sid_to_str,
566566
unsigned num_sids, struct ocontext *isids)
567567
{
568-
struct ocontext *isid;
569568
struct strs *strs;
570569
char *sid;
571570
char *prev;
572-
char unknown[18];
573571
unsigned i;
574-
int rc;
575572

576-
rc = strs_init(&strs, num_sids+1);
577-
if (rc != 0) {
578-
goto exit;
573+
strs = isids_to_strs(sid_to_str, num_sids, isids);
574+
if (!strs) {
575+
ERR(NULL, "Error writing sid rules to CIL");
576+
return -1;
579577
}
580578

581-
for (isid = isids; isid != NULL; isid = isid->next) {
582-
i = isid->sid[0];
583-
if (i < num_sids && sid_to_str[i]) {
584-
sid = strdup(sid_to_str[i]);
585-
} else {
586-
snprintf(unknown, 18, "%s%u", "UNKNOWN", i);
587-
sid = strdup(unknown);
588-
}
589-
if (!sid) {
590-
ERR(NULL, "Out of memory");
591-
rc = -1;
592-
goto exit;
593-
}
594-
rc = strs_add_at_index(strs, sid, i);
595-
if (rc != 0) {
596-
free(sid);
597-
goto exit;
598-
}
579+
if (strs_num_items(strs) == 0) {
580+
strs_destroy(&strs);
581+
return 0;
599582
}
600583

601-
for (i=0; i<strs_num_items(strs); i++) {
584+
for (i=1; i < strs_num_items(strs); i++) {
602585
sid = strs_read_at_index(strs, i);
603-
if (!sid) {
604-
continue;
605-
}
606586
sepol_printf(out, "(sid %s)\n", sid);
607587
}
608588

609589
sepol_printf(out, "(sidorder (");
610590
prev = NULL;
611-
for (i=0; i<strs_num_items(strs); i++) {
591+
for (i=1; i < strs_num_items(strs); i++) {
612592
sid = strs_read_at_index(strs, i);
613-
if (!sid) {
614-
continue;
615-
}
616593
if (prev) {
617594
sepol_printf(out, "%s ", prev);
618595
}
@@ -623,14 +600,10 @@ static int write_sids_to_cil(FILE *out, const char *const *sid_to_str,
623600
}
624601
sepol_printf(out, "))\n");
625602

626-
exit:
627603
strs_free_all(strs);
628604
strs_destroy(&strs);
629-
if (rc != 0) {
630-
ERR(NULL, "Error writing sid rules to CIL");
631-
}
632605

633-
return rc;
606+
return 0;
634607
}
635608

636609
static int write_sid_decl_rules_to_cil(FILE *out, struct policydb *pdb)

libsepol/src/kernel_to_common.c

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,54 @@ int strs_stack_empty(const struct strs *stack)
382382
return strs_num_items(stack) == 0;
383383
}
384384

385+
struct strs *isids_to_strs(const char *const *sid_to_str, unsigned num_sids, struct ocontext *isids)
386+
{
387+
struct ocontext *isid;
388+
struct strs *strs;
389+
char *sid;
390+
char unknown[18];
391+
unsigned i, max;
392+
int rc;
393+
394+
rc = strs_init(&strs, num_sids+1);
395+
if (rc != 0) {
396+
goto exit;
397+
}
398+
399+
max = 0;
400+
for (isid = isids; isid != NULL; isid = isid->next) {
401+
i = isid->sid[0];
402+
if (i > max) {
403+
max = i;
404+
}
405+
}
406+
407+
for (i=1; i <= max; i++) {
408+
if (i < num_sids && sid_to_str[i]) {
409+
sid = strdup(sid_to_str[i]);
410+
} else {
411+
snprintf(unknown, 18, "%s%u", "UNKNOWN", i);
412+
sid = strdup(unknown);
413+
}
414+
if (!sid) {
415+
ERR(NULL, "Out of memory");
416+
goto exit;
417+
}
418+
rc = strs_add_at_index(strs, sid, i);
419+
if (rc != 0) {
420+
free(sid);
421+
goto exit;
422+
}
423+
}
424+
425+
return strs;
426+
427+
exit:
428+
strs_free_all(strs);
429+
strs_destroy(&strs);
430+
return NULL;
431+
}
432+
385433
static int compare_ranges(uint64_t l1, uint64_t h1, uint64_t l2, uint64_t h2)
386434
{
387435
uint64_t d1, d2;

libsepol/src/kernel_to_common.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,4 +115,5 @@ int strs_stack_push(struct strs *stack, char *s);
115115
char *strs_stack_pop(struct strs *stack);
116116
int strs_stack_empty(const struct strs *stack);
117117

118+
struct strs *isids_to_strs(const char *const *sid_to_str, unsigned num_sids, struct ocontext *isids);
118119
int sort_ocontexts(struct policydb *pdb);

libsepol/src/kernel_to_conf.c

Lines changed: 9 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -463,53 +463,30 @@ static int write_class_decl_rules_to_conf(FILE *out, struct policydb *pdb)
463463
static int write_sids_to_conf(FILE *out, const char *const *sid_to_str,
464464
unsigned num_sids, struct ocontext *isids)
465465
{
466-
struct ocontext *isid;
467466
struct strs *strs;
468467
char *sid;
469-
char unknown[18];
470468
unsigned i;
471-
int rc;
472469

473-
rc = strs_init(&strs, num_sids+1);
474-
if (rc != 0) {
475-
goto exit;
470+
strs = isids_to_strs(sid_to_str, num_sids, isids);
471+
if (!strs) {
472+
ERR(NULL, "Error writing sid rules to policy.conf");
473+
return -1;
476474
}
477475

478-
for (isid = isids; isid != NULL; isid = isid->next) {
479-
i = isid->sid[0];
480-
if (i < num_sids && sid_to_str[i]) {
481-
sid = strdup(sid_to_str[i]);
482-
} else {
483-
snprintf(unknown, sizeof(unknown), "%s%u", "UNKNOWN", i);
484-
sid = strdup(unknown);
485-
}
486-
if (!sid) {
487-
rc = -1;
488-
goto exit;
489-
}
490-
rc = strs_add_at_index(strs, sid, i);
491-
if (rc != 0) {
492-
free(sid);
493-
goto exit;
494-
}
476+
if (strs_num_items(strs) == 0) {
477+
strs_destroy(&strs);
478+
return 0;
495479
}
496480

497-
for (i=0; i<strs_num_items(strs); i++) {
481+
for (i=1; i < strs_num_items(strs); i++) {
498482
sid = strs_read_at_index(strs, i);
499-
if (!sid) {
500-
continue;
501-
}
502483
sepol_printf(out, "sid %s\n", sid);
503484
}
504485

505-
exit:
506486
strs_free_all(strs);
507487
strs_destroy(&strs);
508-
if (rc != 0) {
509-
ERR(NULL, "Error writing sid rules to policy.conf");
510-
}
511488

512-
return rc;
489+
return 0;
513490
}
514491

515492
static int write_sid_decl_rules_to_conf(FILE *out, struct policydb *pdb)

libsepol/src/module_to_cil.c

Lines changed: 53 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -2544,71 +2544,71 @@ static int context_to_cil(struct policydb *pdb, struct context_struct *con)
25442544
static int ocontext_isid_to_cil(struct policydb *pdb, const char *const *sid_to_string,
25452545
unsigned num_sids, struct ocontext *isids)
25462546
{
2547-
int rc = -1;
2548-
25492547
struct ocontext *isid;
2550-
2551-
struct sid_item {
2552-
char *sid_key;
2553-
struct sid_item *next;
2554-
};
2555-
2556-
struct sid_item *head = NULL;
2557-
struct sid_item *item = NULL;
2548+
struct ocontext **isid_array;
2549+
struct strs *strs;
25582550
char *sid;
2559-
char unknown[18];
2551+
char *prev;
25602552
unsigned i;
25612553

2562-
for (isid = isids; isid != NULL; isid = isid->next) {
2563-
i = isid->sid[0];
2564-
if (i < num_sids && sid_to_string[i]) {
2565-
sid = (char*)sid_to_string[i];
2566-
} else {
2567-
snprintf(unknown, 18, "%s%u", "UNKNOWN", i);
2568-
sid = unknown;
2569-
}
2570-
cil_println(0, "(sid %s)", sid);
2571-
cil_printf("(sidcontext %s ", sid);
2572-
context_to_cil(pdb, &isid->context[0]);
2573-
cil_printf(")\n");
2554+
strs = isids_to_strs(sid_to_string, num_sids, isids);
2555+
if (!strs) {
2556+
ERR(NULL, "Error writing sid rules to CIL");
2557+
return -1;
2558+
}
25742559

2575-
// get the sid names in the correct order (reverse from the isids
2576-
// ocontext) for sidorder statement
2577-
item = malloc(sizeof(*item));
2578-
if (item == NULL) {
2579-
ERR(NULL, "Out of memory");
2580-
rc = -1;
2581-
goto exit;
2582-
}
2583-
item->sid_key = strdup(sid);
2584-
if (!item->sid_key) {
2585-
ERR(NULL, "Out of memory");
2586-
free(item);
2587-
rc = -1;
2588-
goto exit;
2560+
if (strs_num_items(strs) == 0) {
2561+
strs_destroy(&strs);
2562+
return 0;
2563+
}
2564+
2565+
for (i=1; i < strs_num_items(strs); i++) {
2566+
sid = strs_read_at_index(strs, i);
2567+
cil_printf("(sid %s)\n", sid);
2568+
}
2569+
2570+
cil_printf("(sidorder (");
2571+
prev = NULL;
2572+
for (i=1; i < strs_num_items(strs); i++) {
2573+
sid = strs_read_at_index(strs, i);
2574+
if (prev) {
2575+
cil_printf("%s ", prev);
25892576
}
2590-
item->next = head;
2591-
head = item;
2577+
prev = sid;
2578+
}
2579+
if (prev) {
2580+
cil_printf("%s", prev);
25922581
}
2582+
cil_printf("))\n");
25932583

2594-
if (head != NULL) {
2595-
cil_printf("(sidorder (");
2596-
for (item = head; item != NULL; item = item->next) {
2597-
cil_printf("%s ", item->sid_key);
2584+
isid_array = calloc(strs_num_items(strs), sizeof(struct ocontext *));
2585+
if (!isid_array) {
2586+
ERR(NULL, "Out of memory");
2587+
strs_free_all(strs);
2588+
strs_destroy(&strs);
2589+
return -1;
2590+
}
2591+
for (isid = isids; isid != NULL; isid = isid->next) {
2592+
i = isid->sid[0];
2593+
if (i < strs_num_items(strs)) {
2594+
isid_array[i] = isid;
2595+
}
2596+
}
2597+
for (i=1; i < strs_num_items(strs); i++) {
2598+
if (isid_array[i]) {
2599+
sid = strs_read_at_index(strs, i);
2600+
cil_printf("(sidcontext %s ", sid);
2601+
isid = isid_array[i];
2602+
context_to_cil(pdb, &isid->context[0]);
2603+
cil_printf(")\n");
25982604
}
2599-
cil_printf("))\n");
26002605
}
2606+
free(isid_array);
26012607

2602-
rc = 0;
2608+
strs_free_all(strs);
2609+
strs_destroy(&strs);
26032610

2604-
exit:
2605-
while(head) {
2606-
item = head;
2607-
head = item->next;
2608-
free(item->sid_key);
2609-
free(item);
2610-
}
2611-
return rc;
2611+
return 0;
26122612
}
26132613

26142614
static int ocontext_selinux_isid_to_cil(struct policydb *pdb, struct ocontext *isids)

0 commit comments

Comments
 (0)