With an optional file type being added to CIL genfscon rules, it should be used when writing out a kernel policy or module to CIL when a genfscon rule should only apply to a single security class. Signed-off-by: James Carter <jwcart2@xxxxxxxxx> --- v2: Reordered if else blocks to have consistent ordering. libsepol/src/kernel_to_cil.c | 35 +++++++++++++++++++++++++++++++++-- libsepol/src/module_to_cil.c | 27 ++++++++++++++++++++++++++- 2 files changed, 59 insertions(+), 3 deletions(-) diff --git a/libsepol/src/kernel_to_cil.c b/libsepol/src/kernel_to_cil.c index 305567a5..ad92a7bc 100644 --- a/libsepol/src/kernel_to_cil.c +++ b/libsepol/src/kernel_to_cil.c @@ -2640,6 +2640,8 @@ static int write_genfscon_rules_to_cil(FILE *out, struct policydb *pdb) struct ocontext *ocon; struct strs *strs; char *fstype, *name, *ctx; + uint32_t sclass; + const char *file_type; int rc; rc = strs_init(&strs, 32); @@ -2652,14 +2654,43 @@ static int write_genfscon_rules_to_cil(FILE *out, struct policydb *pdb) fstype = genfs->fstype; name = ocon->u.name; + sclass = ocon->v.sclass; + file_type = NULL; + if (sclass) { + const char *class_name = pdb->p_class_val_to_name[sclass-1]; + if (strcmp(class_name, "file") == 0) { + file_type = "file"; + } else if (strcmp(class_name, "dir") == 0) { + file_type = "dir"; + } else if (strcmp(class_name, "chr_file") == 0) { + file_type = "char"; + } else if (strcmp(class_name, "blk_file") == 0) { + file_type = "block"; + } else if (strcmp(class_name, "sock_file") == 0) { + file_type = "socket"; + } else if (strcmp(class_name, "fifo_file") == 0) { + file_type = "pipe"; + } else if (strcmp(class_name, "lnk_file") == 0) { + file_type = "symlink"; + } else { + rc = -1; + goto exit; + } + } + ctx = context_to_str(pdb, &ocon->context[0]); if (!ctx) { rc = -1; goto exit; } - rc = strs_create_and_add(strs, "(genfscon %s \"%s\" %s)", 3, - fstype, name, ctx); + if (file_type) { + rc = strs_create_and_add(strs, "(genfscon %s \"%s\" %s %s)", 4, + fstype, name, file_type, ctx); + } else { + rc = strs_create_and_add(strs, "(genfscon %s \"%s\" %s)", 3, + fstype, name, ctx); + } free(ctx); if (rc != 0) { goto exit; diff --git a/libsepol/src/module_to_cil.c b/libsepol/src/module_to_cil.c index 16e4004e..c80937e8 100644 --- a/libsepol/src/module_to_cil.c +++ b/libsepol/src/module_to_cil.c @@ -2961,10 +2961,35 @@ static int genfscon_to_cil(struct policydb *pdb) { struct genfs *genfs; struct ocontext *ocon; + uint32_t sclass; for (genfs = pdb->genfs; genfs != NULL; genfs = genfs->next) { for (ocon = genfs->head; ocon != NULL; ocon = ocon->next) { - cil_printf("(genfscon %s \"%s\" ", genfs->fstype, ocon->u.name); + sclass = ocon->v.sclass; + if (sclass) { + const char *file_type; + const char *class_name = pdb->p_class_val_to_name[sclass-1]; + if (strcmp(class_name, "file") == 0) { + file_type = "file"; + } else if (strcmp(class_name, "dir") == 0) { + file_type = "dir"; + } else if (strcmp(class_name, "chr_file") == 0) { + file_type = "char"; + } else if (strcmp(class_name, "blk_file") == 0) { + file_type = "block"; + } else if (strcmp(class_name, "sock_file") == 0) { + file_type = "socket"; + } else if (strcmp(class_name, "fifo_file") == 0) { + file_type = "pipe"; + } else if (strcmp(class_name, "lnk_file") == 0) { + file_type = "symlink"; + } else { + return -1; + } + cil_printf("(genfscon %s \"%s\" %s ", genfs->fstype, ocon->u.name, file_type); + } else { + cil_printf("(genfscon %s \"%s\" ", genfs->fstype, ocon->u.name); + } context_to_cil(pdb, &ocon->context[0]); cil_printf(")\n"); } -- 2.31.1