16cd6a6acSopenharmony_ci#include <stdarg.h> 26cd6a6acSopenharmony_ci#include <stdio.h> 36cd6a6acSopenharmony_ci#include <stdlib.h> 46cd6a6acSopenharmony_ci#include <string.h> 56cd6a6acSopenharmony_ci#include <inttypes.h> 66cd6a6acSopenharmony_ci#include <sys/types.h> 76cd6a6acSopenharmony_ci#include <unistd.h> 86cd6a6acSopenharmony_ci 96cd6a6acSopenharmony_ci#include <arpa/inet.h> 106cd6a6acSopenharmony_ci#include <errno.h> 116cd6a6acSopenharmony_ci#include <netinet/in.h> 126cd6a6acSopenharmony_ci#ifndef IPPROTO_DCCP 136cd6a6acSopenharmony_ci#define IPPROTO_DCCP 33 146cd6a6acSopenharmony_ci#endif 156cd6a6acSopenharmony_ci#ifndef IPPROTO_SCTP 166cd6a6acSopenharmony_ci#define IPPROTO_SCTP 132 176cd6a6acSopenharmony_ci#endif 186cd6a6acSopenharmony_ci 196cd6a6acSopenharmony_ci#include <sepol/kernel_to_cil.h> 206cd6a6acSopenharmony_ci#include <sepol/policydb/avtab.h> 216cd6a6acSopenharmony_ci#include <sepol/policydb/conditional.h> 226cd6a6acSopenharmony_ci#include <sepol/policydb/hashtab.h> 236cd6a6acSopenharmony_ci#include <sepol/policydb/polcaps.h> 246cd6a6acSopenharmony_ci#include <sepol/policydb/policydb.h> 256cd6a6acSopenharmony_ci#include <sepol/policydb/services.h> 266cd6a6acSopenharmony_ci#include <sepol/policydb/util.h> 276cd6a6acSopenharmony_ci 286cd6a6acSopenharmony_ci#include "kernel_to_common.h" 296cd6a6acSopenharmony_ci 306cd6a6acSopenharmony_ci 316cd6a6acSopenharmony_cistatic char *cond_expr_to_str(struct policydb *pdb, struct cond_expr *expr) 326cd6a6acSopenharmony_ci{ 336cd6a6acSopenharmony_ci struct cond_expr *curr; 346cd6a6acSopenharmony_ci struct strs *stack; 356cd6a6acSopenharmony_ci char *new_val; 366cd6a6acSopenharmony_ci char *str = NULL; 376cd6a6acSopenharmony_ci int rc; 386cd6a6acSopenharmony_ci 396cd6a6acSopenharmony_ci rc = strs_stack_init(&stack); 406cd6a6acSopenharmony_ci if (rc != 0) { 416cd6a6acSopenharmony_ci goto exit; 426cd6a6acSopenharmony_ci } 436cd6a6acSopenharmony_ci 446cd6a6acSopenharmony_ci for (curr = expr; curr != NULL; curr = curr->next) { 456cd6a6acSopenharmony_ci if (curr->expr_type == COND_BOOL) { 466cd6a6acSopenharmony_ci char *val1 = pdb->p_bool_val_to_name[curr->bool - 1]; 476cd6a6acSopenharmony_ci new_val = create_str("%s", 1, val1); 486cd6a6acSopenharmony_ci } else { 496cd6a6acSopenharmony_ci const char *op; 506cd6a6acSopenharmony_ci uint32_t num_params; 516cd6a6acSopenharmony_ci char *val1 = NULL; 526cd6a6acSopenharmony_ci char *val2 = NULL; 536cd6a6acSopenharmony_ci 546cd6a6acSopenharmony_ci switch(curr->expr_type) { 556cd6a6acSopenharmony_ci case COND_NOT: op = "not"; num_params = 1; break; 566cd6a6acSopenharmony_ci case COND_OR: op = "or"; num_params = 2; break; 576cd6a6acSopenharmony_ci case COND_AND: op = "and"; num_params = 2; break; 586cd6a6acSopenharmony_ci case COND_XOR: op = "xor"; num_params = 2; break; 596cd6a6acSopenharmony_ci case COND_EQ: op = "eq"; num_params = 2; break; 606cd6a6acSopenharmony_ci case COND_NEQ: op = "neq"; num_params = 2; break; 616cd6a6acSopenharmony_ci default: 626cd6a6acSopenharmony_ci sepol_log_err("Unknown conditional operator: %i", 636cd6a6acSopenharmony_ci curr->expr_type); 646cd6a6acSopenharmony_ci goto exit; 656cd6a6acSopenharmony_ci } 666cd6a6acSopenharmony_ci 676cd6a6acSopenharmony_ci if (num_params == 2) { 686cd6a6acSopenharmony_ci val2 = strs_stack_pop(stack); 696cd6a6acSopenharmony_ci if (!val2) { 706cd6a6acSopenharmony_ci sepol_log_err("Invalid conditional expression"); 716cd6a6acSopenharmony_ci goto exit; 726cd6a6acSopenharmony_ci } 736cd6a6acSopenharmony_ci } 746cd6a6acSopenharmony_ci val1 = strs_stack_pop(stack); 756cd6a6acSopenharmony_ci if (!val1) { 766cd6a6acSopenharmony_ci sepol_log_err("Invalid conditional expression"); 776cd6a6acSopenharmony_ci free(val2); 786cd6a6acSopenharmony_ci goto exit; 796cd6a6acSopenharmony_ci } 806cd6a6acSopenharmony_ci if (num_params == 2) { 816cd6a6acSopenharmony_ci new_val = create_str("(%s %s %s)", 3, op, val1, val2); 826cd6a6acSopenharmony_ci free(val2); 836cd6a6acSopenharmony_ci } else { 846cd6a6acSopenharmony_ci new_val = create_str("(%s %s)", 2, op, val1); 856cd6a6acSopenharmony_ci } 866cd6a6acSopenharmony_ci free(val1); 876cd6a6acSopenharmony_ci } 886cd6a6acSopenharmony_ci if (!new_val) { 896cd6a6acSopenharmony_ci sepol_log_err("Invalid conditional expression"); 906cd6a6acSopenharmony_ci goto exit; 916cd6a6acSopenharmony_ci } 926cd6a6acSopenharmony_ci rc = strs_stack_push(stack, new_val); 936cd6a6acSopenharmony_ci if (rc != 0) { 946cd6a6acSopenharmony_ci sepol_log_err("Out of memory"); 956cd6a6acSopenharmony_ci goto exit; 966cd6a6acSopenharmony_ci } 976cd6a6acSopenharmony_ci } 986cd6a6acSopenharmony_ci 996cd6a6acSopenharmony_ci new_val = strs_stack_pop(stack); 1006cd6a6acSopenharmony_ci if (!new_val || !strs_stack_empty(stack)) { 1016cd6a6acSopenharmony_ci sepol_log_err("Invalid conditional expression"); 1026cd6a6acSopenharmony_ci goto exit; 1036cd6a6acSopenharmony_ci } 1046cd6a6acSopenharmony_ci 1056cd6a6acSopenharmony_ci str = new_val; 1066cd6a6acSopenharmony_ci 1076cd6a6acSopenharmony_ci strs_stack_destroy(&stack); 1086cd6a6acSopenharmony_ci return str; 1096cd6a6acSopenharmony_ci 1106cd6a6acSopenharmony_ciexit: 1116cd6a6acSopenharmony_ci if (stack) { 1126cd6a6acSopenharmony_ci while ((new_val = strs_stack_pop(stack)) != NULL) { 1136cd6a6acSopenharmony_ci free(new_val); 1146cd6a6acSopenharmony_ci } 1156cd6a6acSopenharmony_ci strs_stack_destroy(&stack); 1166cd6a6acSopenharmony_ci } 1176cd6a6acSopenharmony_ci 1186cd6a6acSopenharmony_ci return NULL; 1196cd6a6acSopenharmony_ci} 1206cd6a6acSopenharmony_ci 1216cd6a6acSopenharmony_cistatic char *constraint_expr_to_str(struct policydb *pdb, struct constraint_expr *expr, int *use_mls) 1226cd6a6acSopenharmony_ci{ 1236cd6a6acSopenharmony_ci struct constraint_expr *curr; 1246cd6a6acSopenharmony_ci struct strs *stack = NULL; 1256cd6a6acSopenharmony_ci char *new_val = NULL; 1266cd6a6acSopenharmony_ci const char *op; 1276cd6a6acSopenharmony_ci char *str = NULL; 1286cd6a6acSopenharmony_ci int rc; 1296cd6a6acSopenharmony_ci 1306cd6a6acSopenharmony_ci *use_mls = 0; 1316cd6a6acSopenharmony_ci 1326cd6a6acSopenharmony_ci rc = strs_stack_init(&stack); 1336cd6a6acSopenharmony_ci if (rc != 0) { 1346cd6a6acSopenharmony_ci goto exit; 1356cd6a6acSopenharmony_ci } 1366cd6a6acSopenharmony_ci 1376cd6a6acSopenharmony_ci for (curr = expr; curr; curr = curr->next) { 1386cd6a6acSopenharmony_ci if (curr->expr_type == CEXPR_ATTR || curr->expr_type == CEXPR_NAMES) { 1396cd6a6acSopenharmony_ci const char *attr1 = NULL; 1406cd6a6acSopenharmony_ci const char *attr2 = NULL; 1416cd6a6acSopenharmony_ci 1426cd6a6acSopenharmony_ci switch (curr->op) { 1436cd6a6acSopenharmony_ci case CEXPR_EQ: op = "eq"; break; 1446cd6a6acSopenharmony_ci case CEXPR_NEQ: op = "neq"; break; 1456cd6a6acSopenharmony_ci case CEXPR_DOM: op = "dom"; break; 1466cd6a6acSopenharmony_ci case CEXPR_DOMBY: op = "domby"; break; 1476cd6a6acSopenharmony_ci case CEXPR_INCOMP: op = "incomp"; break; 1486cd6a6acSopenharmony_ci default: 1496cd6a6acSopenharmony_ci sepol_log_err("Unknown constraint operator: %i", curr->op); 1506cd6a6acSopenharmony_ci goto exit; 1516cd6a6acSopenharmony_ci } 1526cd6a6acSopenharmony_ci 1536cd6a6acSopenharmony_ci switch (curr->attr) { 1546cd6a6acSopenharmony_ci case CEXPR_USER: attr1 ="u1"; attr2 ="u2"; break; 1556cd6a6acSopenharmony_ci case CEXPR_USER | CEXPR_TARGET: attr1 ="u2"; attr2 =""; break; 1566cd6a6acSopenharmony_ci case CEXPR_USER | CEXPR_XTARGET: attr1 ="u3"; attr2 =""; break; 1576cd6a6acSopenharmony_ci case CEXPR_ROLE: attr1 ="r1"; attr2 ="r2"; break; 1586cd6a6acSopenharmony_ci case CEXPR_ROLE | CEXPR_TARGET: attr1 ="r2"; attr2 =""; break; 1596cd6a6acSopenharmony_ci case CEXPR_ROLE | CEXPR_XTARGET: attr1 ="r3"; attr2 =""; break; 1606cd6a6acSopenharmony_ci case CEXPR_TYPE: attr1 ="t1"; attr2 ="t2"; break; 1616cd6a6acSopenharmony_ci case CEXPR_TYPE | CEXPR_TARGET: attr1 ="t2"; attr2 =""; break; 1626cd6a6acSopenharmony_ci case CEXPR_TYPE | CEXPR_XTARGET: attr1 ="t3"; attr2 =""; break; 1636cd6a6acSopenharmony_ci case CEXPR_L1L2: attr1 ="l1"; attr2 ="l2"; break; 1646cd6a6acSopenharmony_ci case CEXPR_L1H2: attr1 ="l1"; attr2 ="h2"; break; 1656cd6a6acSopenharmony_ci case CEXPR_H1L2: attr1 ="h1"; attr2 ="l2"; break; 1666cd6a6acSopenharmony_ci case CEXPR_H1H2: attr1 ="h1"; attr2 ="h2"; break; 1676cd6a6acSopenharmony_ci case CEXPR_L1H1: attr1 ="l1"; attr2 ="h1"; break; 1686cd6a6acSopenharmony_ci case CEXPR_L2H2: attr1 ="l2"; attr2 ="h2"; break; 1696cd6a6acSopenharmony_ci default: 1706cd6a6acSopenharmony_ci sepol_log_err("Unknown constraint attribute: %i", 1716cd6a6acSopenharmony_ci curr->attr); 1726cd6a6acSopenharmony_ci goto exit; 1736cd6a6acSopenharmony_ci } 1746cd6a6acSopenharmony_ci 1756cd6a6acSopenharmony_ci if (curr->attr >= CEXPR_XTARGET) { 1766cd6a6acSopenharmony_ci *use_mls = 1; 1776cd6a6acSopenharmony_ci } 1786cd6a6acSopenharmony_ci 1796cd6a6acSopenharmony_ci if (curr->expr_type == CEXPR_ATTR) { 1806cd6a6acSopenharmony_ci new_val = create_str("(%s %s %s)", 3, op, attr1, attr2); 1816cd6a6acSopenharmony_ci } else { 1826cd6a6acSopenharmony_ci char *names = NULL; 1836cd6a6acSopenharmony_ci if (curr->attr & CEXPR_TYPE) { 1846cd6a6acSopenharmony_ci struct type_set *ts = curr->type_names; 1856cd6a6acSopenharmony_ci names = ebitmap_to_str(&ts->types, pdb->p_type_val_to_name, 1); 1866cd6a6acSopenharmony_ci } else if (curr->attr & CEXPR_USER) { 1876cd6a6acSopenharmony_ci names = ebitmap_to_str(&curr->names, pdb->p_user_val_to_name, 1); 1886cd6a6acSopenharmony_ci } else if (curr->attr & CEXPR_ROLE) { 1896cd6a6acSopenharmony_ci names = ebitmap_to_str(&curr->names, pdb->p_role_val_to_name, 1); 1906cd6a6acSopenharmony_ci } 1916cd6a6acSopenharmony_ci if (!names) { 1926cd6a6acSopenharmony_ci names = strdup("NO_IDENTIFIER"); 1936cd6a6acSopenharmony_ci if (!names) { 1946cd6a6acSopenharmony_ci sepol_log_err("Out of memory"); 1956cd6a6acSopenharmony_ci goto exit; 1966cd6a6acSopenharmony_ci } 1976cd6a6acSopenharmony_ci } 1986cd6a6acSopenharmony_ci if (strchr(names, ' ')) { 1996cd6a6acSopenharmony_ci new_val = create_str("(%s %s (%s))", 3, op, attr1, names); 2006cd6a6acSopenharmony_ci } else { 2016cd6a6acSopenharmony_ci new_val = create_str("(%s %s %s)", 3, op, attr1, names); 2026cd6a6acSopenharmony_ci } 2036cd6a6acSopenharmony_ci free(names); 2046cd6a6acSopenharmony_ci } 2056cd6a6acSopenharmony_ci } else { 2066cd6a6acSopenharmony_ci uint32_t num_params; 2076cd6a6acSopenharmony_ci char *val1 = NULL; 2086cd6a6acSopenharmony_ci char *val2 = NULL; 2096cd6a6acSopenharmony_ci 2106cd6a6acSopenharmony_ci switch (curr->expr_type) { 2116cd6a6acSopenharmony_ci case CEXPR_NOT: op = "not"; num_params = 1; break; 2126cd6a6acSopenharmony_ci case CEXPR_AND: op = "and"; num_params = 2; break; 2136cd6a6acSopenharmony_ci case CEXPR_OR: op = "or"; num_params = 2; break; 2146cd6a6acSopenharmony_ci default: 2156cd6a6acSopenharmony_ci sepol_log_err("Unknown constraint expression type: %i", 2166cd6a6acSopenharmony_ci curr->expr_type); 2176cd6a6acSopenharmony_ci goto exit; 2186cd6a6acSopenharmony_ci } 2196cd6a6acSopenharmony_ci 2206cd6a6acSopenharmony_ci if (num_params == 2) { 2216cd6a6acSopenharmony_ci val2 = strs_stack_pop(stack); 2226cd6a6acSopenharmony_ci if (!val2) { 2236cd6a6acSopenharmony_ci sepol_log_err("Invalid constraint expression"); 2246cd6a6acSopenharmony_ci goto exit; 2256cd6a6acSopenharmony_ci } 2266cd6a6acSopenharmony_ci } 2276cd6a6acSopenharmony_ci val1 = strs_stack_pop(stack); 2286cd6a6acSopenharmony_ci if (!val1) { 2296cd6a6acSopenharmony_ci sepol_log_err("Invalid constraint expression"); 2306cd6a6acSopenharmony_ci goto exit; 2316cd6a6acSopenharmony_ci } 2326cd6a6acSopenharmony_ci 2336cd6a6acSopenharmony_ci if (num_params == 2) { 2346cd6a6acSopenharmony_ci new_val = create_str("(%s %s %s)", 3, op, val1, val2); 2356cd6a6acSopenharmony_ci free(val2); 2366cd6a6acSopenharmony_ci } else { 2376cd6a6acSopenharmony_ci new_val = create_str("(%s %s)", 2, op, val1); 2386cd6a6acSopenharmony_ci } 2396cd6a6acSopenharmony_ci free(val1); 2406cd6a6acSopenharmony_ci } 2416cd6a6acSopenharmony_ci if (!new_val) { 2426cd6a6acSopenharmony_ci goto exit; 2436cd6a6acSopenharmony_ci } 2446cd6a6acSopenharmony_ci rc = strs_stack_push(stack, new_val); 2456cd6a6acSopenharmony_ci if (rc != 0) { 2466cd6a6acSopenharmony_ci sepol_log_err("Out of memory"); 2476cd6a6acSopenharmony_ci goto exit; 2486cd6a6acSopenharmony_ci } 2496cd6a6acSopenharmony_ci } 2506cd6a6acSopenharmony_ci 2516cd6a6acSopenharmony_ci new_val = strs_stack_pop(stack); 2526cd6a6acSopenharmony_ci if (!new_val || !strs_stack_empty(stack)) { 2536cd6a6acSopenharmony_ci sepol_log_err("Invalid constraint expression"); 2546cd6a6acSopenharmony_ci goto exit; 2556cd6a6acSopenharmony_ci } 2566cd6a6acSopenharmony_ci 2576cd6a6acSopenharmony_ci str = new_val; 2586cd6a6acSopenharmony_ci 2596cd6a6acSopenharmony_ci strs_stack_destroy(&stack); 2606cd6a6acSopenharmony_ci 2616cd6a6acSopenharmony_ci return str; 2626cd6a6acSopenharmony_ci 2636cd6a6acSopenharmony_ciexit: 2646cd6a6acSopenharmony_ci if (stack) { 2656cd6a6acSopenharmony_ci while ((new_val = strs_stack_pop(stack)) != NULL) { 2666cd6a6acSopenharmony_ci free(new_val); 2676cd6a6acSopenharmony_ci } 2686cd6a6acSopenharmony_ci strs_stack_destroy(&stack); 2696cd6a6acSopenharmony_ci } 2706cd6a6acSopenharmony_ci 2716cd6a6acSopenharmony_ci return NULL; 2726cd6a6acSopenharmony_ci} 2736cd6a6acSopenharmony_ci 2746cd6a6acSopenharmony_cistatic int class_constraint_rules_to_strs(struct policydb *pdb, char *classkey, 2756cd6a6acSopenharmony_ci class_datum_t *class, 2766cd6a6acSopenharmony_ci struct constraint_node *constraint_rules, 2776cd6a6acSopenharmony_ci struct strs *mls_list, 2786cd6a6acSopenharmony_ci struct strs *non_mls_list) 2796cd6a6acSopenharmony_ci{ 2806cd6a6acSopenharmony_ci int rc = 0; 2816cd6a6acSopenharmony_ci struct constraint_node *curr; 2826cd6a6acSopenharmony_ci char *expr = NULL; 2836cd6a6acSopenharmony_ci int is_mls; 2846cd6a6acSopenharmony_ci char *perms; 2856cd6a6acSopenharmony_ci const char *key_word; 2866cd6a6acSopenharmony_ci struct strs *strs; 2876cd6a6acSopenharmony_ci 2886cd6a6acSopenharmony_ci for (curr = constraint_rules; curr != NULL; curr = curr->next) { 2896cd6a6acSopenharmony_ci if (curr->permissions == 0) { 2906cd6a6acSopenharmony_ci continue; 2916cd6a6acSopenharmony_ci } 2926cd6a6acSopenharmony_ci expr = constraint_expr_to_str(pdb, curr->expr, &is_mls); 2936cd6a6acSopenharmony_ci if (!expr) { 2946cd6a6acSopenharmony_ci rc = -1; 2956cd6a6acSopenharmony_ci goto exit; 2966cd6a6acSopenharmony_ci } 2976cd6a6acSopenharmony_ci 2986cd6a6acSopenharmony_ci perms = sepol_av_to_string(pdb, class->s.value, curr->permissions); 2996cd6a6acSopenharmony_ci 3006cd6a6acSopenharmony_ci if (is_mls) { 3016cd6a6acSopenharmony_ci key_word = "mlsconstrain"; 3026cd6a6acSopenharmony_ci strs = mls_list; 3036cd6a6acSopenharmony_ci } else { 3046cd6a6acSopenharmony_ci key_word = "constrain"; 3056cd6a6acSopenharmony_ci strs = non_mls_list; 3066cd6a6acSopenharmony_ci } 3076cd6a6acSopenharmony_ci 3086cd6a6acSopenharmony_ci rc = strs_create_and_add(strs, "(%s (%s (%s)) %s)", 4, key_word, classkey, perms+1, expr); 3096cd6a6acSopenharmony_ci free(expr); 3106cd6a6acSopenharmony_ci if (rc != 0) { 3116cd6a6acSopenharmony_ci goto exit; 3126cd6a6acSopenharmony_ci } 3136cd6a6acSopenharmony_ci } 3146cd6a6acSopenharmony_ci 3156cd6a6acSopenharmony_ci return 0; 3166cd6a6acSopenharmony_ciexit: 3176cd6a6acSopenharmony_ci sepol_log_err("Error gathering constraint rules\n"); 3186cd6a6acSopenharmony_ci return rc; 3196cd6a6acSopenharmony_ci} 3206cd6a6acSopenharmony_ci 3216cd6a6acSopenharmony_cistatic int class_validatetrans_rules_to_strs(struct policydb *pdb, char *classkey, 3226cd6a6acSopenharmony_ci struct constraint_node *validatetrans_rules, 3236cd6a6acSopenharmony_ci struct strs *mls_list, 3246cd6a6acSopenharmony_ci struct strs *non_mls_list) 3256cd6a6acSopenharmony_ci{ 3266cd6a6acSopenharmony_ci struct constraint_node *curr; 3276cd6a6acSopenharmony_ci char *expr = NULL; 3286cd6a6acSopenharmony_ci int is_mls; 3296cd6a6acSopenharmony_ci const char *key_word; 3306cd6a6acSopenharmony_ci struct strs *strs; 3316cd6a6acSopenharmony_ci int rc = 0; 3326cd6a6acSopenharmony_ci 3336cd6a6acSopenharmony_ci for (curr = validatetrans_rules; curr != NULL; curr = curr->next) { 3346cd6a6acSopenharmony_ci expr = constraint_expr_to_str(pdb, curr->expr, &is_mls); 3356cd6a6acSopenharmony_ci if (!expr) { 3366cd6a6acSopenharmony_ci rc = -1; 3376cd6a6acSopenharmony_ci goto exit; 3386cd6a6acSopenharmony_ci } 3396cd6a6acSopenharmony_ci 3406cd6a6acSopenharmony_ci if (is_mls) { 3416cd6a6acSopenharmony_ci key_word = "mlsvalidatetrans"; 3426cd6a6acSopenharmony_ci strs = mls_list; 3436cd6a6acSopenharmony_ci } else { 3446cd6a6acSopenharmony_ci key_word = "validatetrans"; 3456cd6a6acSopenharmony_ci strs = non_mls_list; 3466cd6a6acSopenharmony_ci } 3476cd6a6acSopenharmony_ci 3486cd6a6acSopenharmony_ci rc = strs_create_and_add(strs, "(%s %s %s)", 3, key_word, classkey, expr); 3496cd6a6acSopenharmony_ci free(expr); 3506cd6a6acSopenharmony_ci if (rc != 0) { 3516cd6a6acSopenharmony_ci goto exit; 3526cd6a6acSopenharmony_ci } 3536cd6a6acSopenharmony_ci } 3546cd6a6acSopenharmony_ci 3556cd6a6acSopenharmony_ciexit: 3566cd6a6acSopenharmony_ci return rc; 3576cd6a6acSopenharmony_ci} 3586cd6a6acSopenharmony_ci 3596cd6a6acSopenharmony_cistatic int constraint_rules_to_strs(struct policydb *pdb, struct strs *mls_strs, struct strs *non_mls_strs) 3606cd6a6acSopenharmony_ci{ 3616cd6a6acSopenharmony_ci class_datum_t *class; 3626cd6a6acSopenharmony_ci char *name; 3636cd6a6acSopenharmony_ci unsigned i; 3646cd6a6acSopenharmony_ci int rc = 0; 3656cd6a6acSopenharmony_ci 3666cd6a6acSopenharmony_ci for (i=0; i < pdb->p_classes.nprim; i++) { 3676cd6a6acSopenharmony_ci class = pdb->class_val_to_struct[i]; 3686cd6a6acSopenharmony_ci if (!class) continue; 3696cd6a6acSopenharmony_ci if (class->constraints) { 3706cd6a6acSopenharmony_ci name = pdb->p_class_val_to_name[i]; 3716cd6a6acSopenharmony_ci rc = class_constraint_rules_to_strs(pdb, name, class, class->constraints, mls_strs, non_mls_strs); 3726cd6a6acSopenharmony_ci if (rc != 0) { 3736cd6a6acSopenharmony_ci goto exit; 3746cd6a6acSopenharmony_ci } 3756cd6a6acSopenharmony_ci } 3766cd6a6acSopenharmony_ci } 3776cd6a6acSopenharmony_ci 3786cd6a6acSopenharmony_ci strs_sort(mls_strs); 3796cd6a6acSopenharmony_ci strs_sort(non_mls_strs); 3806cd6a6acSopenharmony_ci 3816cd6a6acSopenharmony_ciexit: 3826cd6a6acSopenharmony_ci return rc; 3836cd6a6acSopenharmony_ci} 3846cd6a6acSopenharmony_ci 3856cd6a6acSopenharmony_cistatic int validatetrans_rules_to_strs(struct policydb *pdb, struct strs *mls_strs, struct strs *non_mls_strs) 3866cd6a6acSopenharmony_ci{ 3876cd6a6acSopenharmony_ci class_datum_t *class; 3886cd6a6acSopenharmony_ci char *name; 3896cd6a6acSopenharmony_ci unsigned i; 3906cd6a6acSopenharmony_ci int rc = 0; 3916cd6a6acSopenharmony_ci 3926cd6a6acSopenharmony_ci for (i=0; i < pdb->p_classes.nprim; i++) { 3936cd6a6acSopenharmony_ci class = pdb->class_val_to_struct[i]; 3946cd6a6acSopenharmony_ci if (!class) continue; 3956cd6a6acSopenharmony_ci if (class->validatetrans) { 3966cd6a6acSopenharmony_ci name = pdb->p_class_val_to_name[i]; 3976cd6a6acSopenharmony_ci rc = class_validatetrans_rules_to_strs(pdb, name, class->validatetrans, mls_strs, non_mls_strs); 3986cd6a6acSopenharmony_ci if (rc != 0) { 3996cd6a6acSopenharmony_ci goto exit; 4006cd6a6acSopenharmony_ci } 4016cd6a6acSopenharmony_ci } 4026cd6a6acSopenharmony_ci } 4036cd6a6acSopenharmony_ci 4046cd6a6acSopenharmony_ci strs_sort(mls_strs); 4056cd6a6acSopenharmony_ci strs_sort(non_mls_strs); 4066cd6a6acSopenharmony_ci 4076cd6a6acSopenharmony_ciexit: 4086cd6a6acSopenharmony_ci return rc; 4096cd6a6acSopenharmony_ci} 4106cd6a6acSopenharmony_ci 4116cd6a6acSopenharmony_cistatic int write_handle_unknown_to_cil(FILE *out, struct policydb *pdb) 4126cd6a6acSopenharmony_ci{ 4136cd6a6acSopenharmony_ci const char *action; 4146cd6a6acSopenharmony_ci 4156cd6a6acSopenharmony_ci switch (pdb->handle_unknown) { 4166cd6a6acSopenharmony_ci case SEPOL_DENY_UNKNOWN: 4176cd6a6acSopenharmony_ci action = "deny"; 4186cd6a6acSopenharmony_ci break; 4196cd6a6acSopenharmony_ci case SEPOL_REJECT_UNKNOWN: 4206cd6a6acSopenharmony_ci action = "reject"; 4216cd6a6acSopenharmony_ci break; 4226cd6a6acSopenharmony_ci case SEPOL_ALLOW_UNKNOWN: 4236cd6a6acSopenharmony_ci action = "allow"; 4246cd6a6acSopenharmony_ci break; 4256cd6a6acSopenharmony_ci default: 4266cd6a6acSopenharmony_ci sepol_log_err("Unknown value for handle-unknown: %i", pdb->handle_unknown); 4276cd6a6acSopenharmony_ci return -1; 4286cd6a6acSopenharmony_ci } 4296cd6a6acSopenharmony_ci 4306cd6a6acSopenharmony_ci sepol_printf(out, "(handleunknown %s)\n", action); 4316cd6a6acSopenharmony_ci 4326cd6a6acSopenharmony_ci return 0; 4336cd6a6acSopenharmony_ci} 4346cd6a6acSopenharmony_ci 4356cd6a6acSopenharmony_cistatic char *class_or_common_perms_to_str(symtab_t *permtab) 4366cd6a6acSopenharmony_ci{ 4376cd6a6acSopenharmony_ci struct strs *strs; 4386cd6a6acSopenharmony_ci char *perms = NULL; 4396cd6a6acSopenharmony_ci int rc; 4406cd6a6acSopenharmony_ci 4416cd6a6acSopenharmony_ci rc = strs_init(&strs, permtab->nprim); 4426cd6a6acSopenharmony_ci if (rc != 0) { 4436cd6a6acSopenharmony_ci goto exit; 4446cd6a6acSopenharmony_ci } 4456cd6a6acSopenharmony_ci 4466cd6a6acSopenharmony_ci rc = hashtab_map(permtab->table, hashtab_ordered_to_strs, strs); 4476cd6a6acSopenharmony_ci if (rc != 0) { 4486cd6a6acSopenharmony_ci goto exit; 4496cd6a6acSopenharmony_ci } 4506cd6a6acSopenharmony_ci 4516cd6a6acSopenharmony_ci if (strs_num_items(strs) > 0) { 4526cd6a6acSopenharmony_ci perms = strs_to_str(strs); 4536cd6a6acSopenharmony_ci } 4546cd6a6acSopenharmony_ci 4556cd6a6acSopenharmony_ciexit: 4566cd6a6acSopenharmony_ci strs_destroy(&strs); 4576cd6a6acSopenharmony_ci 4586cd6a6acSopenharmony_ci return perms; 4596cd6a6acSopenharmony_ci} 4606cd6a6acSopenharmony_ci 4616cd6a6acSopenharmony_cistatic int write_class_decl_rules_to_cil(FILE *out, struct policydb *pdb) 4626cd6a6acSopenharmony_ci{ 4636cd6a6acSopenharmony_ci class_datum_t *class; 4646cd6a6acSopenharmony_ci common_datum_t *common; 4656cd6a6acSopenharmony_ci int *used; 4666cd6a6acSopenharmony_ci char *name, *perms; 4676cd6a6acSopenharmony_ci unsigned i; 4686cd6a6acSopenharmony_ci int rc = 0; 4696cd6a6acSopenharmony_ci 4706cd6a6acSopenharmony_ci /* class */ 4716cd6a6acSopenharmony_ci for (i=0; i < pdb->p_classes.nprim; i++) { 4726cd6a6acSopenharmony_ci class = pdb->class_val_to_struct[i]; 4736cd6a6acSopenharmony_ci if (!class) continue; 4746cd6a6acSopenharmony_ci name = pdb->p_class_val_to_name[i]; 4756cd6a6acSopenharmony_ci perms = class_or_common_perms_to_str(&class->permissions); 4766cd6a6acSopenharmony_ci if (perms) { 4776cd6a6acSopenharmony_ci sepol_printf(out, "(class %s (%s))\n", name, perms); 4786cd6a6acSopenharmony_ci free(perms); 4796cd6a6acSopenharmony_ci } else { 4806cd6a6acSopenharmony_ci sepol_printf(out, "(class %s ())\n", name); 4816cd6a6acSopenharmony_ci } 4826cd6a6acSopenharmony_ci } 4836cd6a6acSopenharmony_ci 4846cd6a6acSopenharmony_ci /* classorder */ 4856cd6a6acSopenharmony_ci sepol_printf(out, "(classorder ("); 4866cd6a6acSopenharmony_ci name = NULL; 4876cd6a6acSopenharmony_ci for (i=0; i < pdb->p_classes.nprim; i++) { 4886cd6a6acSopenharmony_ci if (name) { 4896cd6a6acSopenharmony_ci sepol_printf(out, "%s ", name); 4906cd6a6acSopenharmony_ci } 4916cd6a6acSopenharmony_ci name = pdb->p_class_val_to_name[i]; 4926cd6a6acSopenharmony_ci } 4936cd6a6acSopenharmony_ci if (name) { 4946cd6a6acSopenharmony_ci sepol_printf(out, "%s", name); 4956cd6a6acSopenharmony_ci } 4966cd6a6acSopenharmony_ci sepol_printf(out, "))\n"); 4976cd6a6acSopenharmony_ci 4986cd6a6acSopenharmony_ci /* classcommon */ 4996cd6a6acSopenharmony_ci for (i=0; i < pdb->p_classes.nprim; i++) { 5006cd6a6acSopenharmony_ci class = pdb->class_val_to_struct[i]; 5016cd6a6acSopenharmony_ci if (!class) continue; 5026cd6a6acSopenharmony_ci name = pdb->p_class_val_to_name[i]; 5036cd6a6acSopenharmony_ci if (class->comkey != NULL) { 5046cd6a6acSopenharmony_ci sepol_printf(out, "(classcommon %s %s)\n", name, class->comkey); 5056cd6a6acSopenharmony_ci } 5066cd6a6acSopenharmony_ci } 5076cd6a6acSopenharmony_ci 5086cd6a6acSopenharmony_ci /* common */ 5096cd6a6acSopenharmony_ci used = calloc(pdb->p_commons.nprim, sizeof(*used)); 5106cd6a6acSopenharmony_ci if (!used) { 5116cd6a6acSopenharmony_ci sepol_log_err("Out of memory"); 5126cd6a6acSopenharmony_ci rc = -1; 5136cd6a6acSopenharmony_ci goto exit; 5146cd6a6acSopenharmony_ci } 5156cd6a6acSopenharmony_ci for (i=0; i < pdb->p_classes.nprim; i++) { 5166cd6a6acSopenharmony_ci class = pdb->class_val_to_struct[i]; 5176cd6a6acSopenharmony_ci if (!class) continue; 5186cd6a6acSopenharmony_ci name = class->comkey; 5196cd6a6acSopenharmony_ci if (name != NULL) { 5206cd6a6acSopenharmony_ci common = hashtab_search(pdb->p_commons.table, name); 5216cd6a6acSopenharmony_ci if (!common) { 5226cd6a6acSopenharmony_ci rc = -1; 5236cd6a6acSopenharmony_ci free(used); 5246cd6a6acSopenharmony_ci goto exit; 5256cd6a6acSopenharmony_ci } 5266cd6a6acSopenharmony_ci /* Only write common rule once */ 5276cd6a6acSopenharmony_ci if (!used[common->s.value-1]) { 5286cd6a6acSopenharmony_ci perms = class_or_common_perms_to_str(&common->permissions); 5296cd6a6acSopenharmony_ci if (!perms) { 5306cd6a6acSopenharmony_ci rc = -1; 5316cd6a6acSopenharmony_ci free(perms); 5326cd6a6acSopenharmony_ci free(used); 5336cd6a6acSopenharmony_ci goto exit; 5346cd6a6acSopenharmony_ci } 5356cd6a6acSopenharmony_ci 5366cd6a6acSopenharmony_ci sepol_printf(out, "(common %s (%s))\n", name, perms); 5376cd6a6acSopenharmony_ci free(perms); 5386cd6a6acSopenharmony_ci used[common->s.value-1] = 1; 5396cd6a6acSopenharmony_ci } 5406cd6a6acSopenharmony_ci } 5416cd6a6acSopenharmony_ci } 5426cd6a6acSopenharmony_ci free(used); 5436cd6a6acSopenharmony_ci 5446cd6a6acSopenharmony_ciexit: 5456cd6a6acSopenharmony_ci if (rc != 0) { 5466cd6a6acSopenharmony_ci sepol_log_err("Error writing class rules to CIL\n"); 5476cd6a6acSopenharmony_ci } 5486cd6a6acSopenharmony_ci 5496cd6a6acSopenharmony_ci return rc; 5506cd6a6acSopenharmony_ci} 5516cd6a6acSopenharmony_ci 5526cd6a6acSopenharmony_cistatic int write_sids_to_cil(FILE *out, const char *const *sid_to_str, 5536cd6a6acSopenharmony_ci unsigned num_sids, struct ocontext *isids) 5546cd6a6acSopenharmony_ci{ 5556cd6a6acSopenharmony_ci struct ocontext *isid; 5566cd6a6acSopenharmony_ci struct strs *strs; 5576cd6a6acSopenharmony_ci char *sid; 5586cd6a6acSopenharmony_ci char *prev; 5596cd6a6acSopenharmony_ci char unknown[18]; 5606cd6a6acSopenharmony_ci unsigned i; 5616cd6a6acSopenharmony_ci int rc; 5626cd6a6acSopenharmony_ci 5636cd6a6acSopenharmony_ci rc = strs_init(&strs, num_sids+1); 5646cd6a6acSopenharmony_ci if (rc != 0) { 5656cd6a6acSopenharmony_ci goto exit; 5666cd6a6acSopenharmony_ci } 5676cd6a6acSopenharmony_ci 5686cd6a6acSopenharmony_ci for (isid = isids; isid != NULL; isid = isid->next) { 5696cd6a6acSopenharmony_ci i = isid->sid[0]; 5706cd6a6acSopenharmony_ci if (i < num_sids) { 5716cd6a6acSopenharmony_ci sid = (char *)sid_to_str[i]; 5726cd6a6acSopenharmony_ci } else { 5736cd6a6acSopenharmony_ci snprintf(unknown, 18, "%s%u", "UNKNOWN", i); 5746cd6a6acSopenharmony_ci sid = strdup(unknown); 5756cd6a6acSopenharmony_ci if (!sid) { 5766cd6a6acSopenharmony_ci sepol_log_err("Out of memory"); 5776cd6a6acSopenharmony_ci rc = -1; 5786cd6a6acSopenharmony_ci goto exit; 5796cd6a6acSopenharmony_ci } 5806cd6a6acSopenharmony_ci } 5816cd6a6acSopenharmony_ci rc = strs_add_at_index(strs, sid, i); 5826cd6a6acSopenharmony_ci if (rc != 0) { 5836cd6a6acSopenharmony_ci goto exit; 5846cd6a6acSopenharmony_ci } 5856cd6a6acSopenharmony_ci } 5866cd6a6acSopenharmony_ci 5876cd6a6acSopenharmony_ci for (i=0; i<strs_num_items(strs); i++) { 5886cd6a6acSopenharmony_ci sid = strs_read_at_index(strs, i); 5896cd6a6acSopenharmony_ci if (!sid) { 5906cd6a6acSopenharmony_ci continue; 5916cd6a6acSopenharmony_ci } 5926cd6a6acSopenharmony_ci sepol_printf(out, "(sid %s)\n", sid); 5936cd6a6acSopenharmony_ci } 5946cd6a6acSopenharmony_ci 5956cd6a6acSopenharmony_ci sepol_printf(out, "(sidorder ("); 5966cd6a6acSopenharmony_ci prev = NULL; 5976cd6a6acSopenharmony_ci for (i=0; i<strs_num_items(strs); i++) { 5986cd6a6acSopenharmony_ci sid = strs_read_at_index(strs, i); 5996cd6a6acSopenharmony_ci if (!sid) { 6006cd6a6acSopenharmony_ci continue; 6016cd6a6acSopenharmony_ci } 6026cd6a6acSopenharmony_ci if (prev) { 6036cd6a6acSopenharmony_ci sepol_printf(out, "%s ", prev); 6046cd6a6acSopenharmony_ci } 6056cd6a6acSopenharmony_ci prev = sid; 6066cd6a6acSopenharmony_ci } 6076cd6a6acSopenharmony_ci if (prev) { 6086cd6a6acSopenharmony_ci sepol_printf(out, "%s", prev); 6096cd6a6acSopenharmony_ci } 6106cd6a6acSopenharmony_ci sepol_printf(out, "))\n"); 6116cd6a6acSopenharmony_ci 6126cd6a6acSopenharmony_ciexit: 6136cd6a6acSopenharmony_ci for (i=num_sids; i<strs_num_items(strs); i++) { 6146cd6a6acSopenharmony_ci sid = strs_read_at_index(strs, i); 6156cd6a6acSopenharmony_ci free(sid); 6166cd6a6acSopenharmony_ci } 6176cd6a6acSopenharmony_ci strs_destroy(&strs); 6186cd6a6acSopenharmony_ci if (rc != 0) { 6196cd6a6acSopenharmony_ci sepol_log_err("Error writing sid rules to CIL\n"); 6206cd6a6acSopenharmony_ci } 6216cd6a6acSopenharmony_ci 6226cd6a6acSopenharmony_ci return rc; 6236cd6a6acSopenharmony_ci} 6246cd6a6acSopenharmony_ci 6256cd6a6acSopenharmony_cistatic int write_sid_decl_rules_to_cil(FILE *out, struct policydb *pdb) 6266cd6a6acSopenharmony_ci{ 6276cd6a6acSopenharmony_ci int rc = 0; 6286cd6a6acSopenharmony_ci 6296cd6a6acSopenharmony_ci if (pdb->target_platform == SEPOL_TARGET_SELINUX) { 6306cd6a6acSopenharmony_ci rc = write_sids_to_cil(out, selinux_sid_to_str, SELINUX_SID_SZ, 6316cd6a6acSopenharmony_ci pdb->ocontexts[0]); 6326cd6a6acSopenharmony_ci } else if (pdb->target_platform == SEPOL_TARGET_XEN) { 6336cd6a6acSopenharmony_ci rc = write_sids_to_cil(out, xen_sid_to_str, XEN_SID_SZ, 6346cd6a6acSopenharmony_ci pdb->ocontexts[0]); 6356cd6a6acSopenharmony_ci } else { 6366cd6a6acSopenharmony_ci sepol_log_err("Unknown target platform: %i", pdb->target_platform); 6376cd6a6acSopenharmony_ci rc = -1; 6386cd6a6acSopenharmony_ci } 6396cd6a6acSopenharmony_ci 6406cd6a6acSopenharmony_ci return rc; 6416cd6a6acSopenharmony_ci} 6426cd6a6acSopenharmony_ci 6436cd6a6acSopenharmony_cistatic int write_default_user_to_cil(FILE *out, char *class_name, class_datum_t *class) 6446cd6a6acSopenharmony_ci{ 6456cd6a6acSopenharmony_ci const char *dft; 6466cd6a6acSopenharmony_ci 6476cd6a6acSopenharmony_ci switch (class->default_user) { 6486cd6a6acSopenharmony_ci case DEFAULT_SOURCE: 6496cd6a6acSopenharmony_ci dft = "source"; 6506cd6a6acSopenharmony_ci break; 6516cd6a6acSopenharmony_ci case DEFAULT_TARGET: 6526cd6a6acSopenharmony_ci dft = "target"; 6536cd6a6acSopenharmony_ci break; 6546cd6a6acSopenharmony_ci default: 6556cd6a6acSopenharmony_ci sepol_log_err("Unknown default role value: %i", class->default_user); 6566cd6a6acSopenharmony_ci return -1; 6576cd6a6acSopenharmony_ci } 6586cd6a6acSopenharmony_ci sepol_printf(out, "(defaultuser %s %s)\n", class_name, dft); 6596cd6a6acSopenharmony_ci 6606cd6a6acSopenharmony_ci return 0; 6616cd6a6acSopenharmony_ci} 6626cd6a6acSopenharmony_ci 6636cd6a6acSopenharmony_cistatic int write_default_role_to_cil(FILE *out, char *class_name, class_datum_t *class) 6646cd6a6acSopenharmony_ci{ 6656cd6a6acSopenharmony_ci const char *dft; 6666cd6a6acSopenharmony_ci 6676cd6a6acSopenharmony_ci switch (class->default_role) { 6686cd6a6acSopenharmony_ci case DEFAULT_SOURCE: 6696cd6a6acSopenharmony_ci dft = "source"; 6706cd6a6acSopenharmony_ci break; 6716cd6a6acSopenharmony_ci case DEFAULT_TARGET: 6726cd6a6acSopenharmony_ci dft = "target"; 6736cd6a6acSopenharmony_ci break; 6746cd6a6acSopenharmony_ci default: 6756cd6a6acSopenharmony_ci sepol_log_err("Unknown default role value: %i", class->default_role); 6766cd6a6acSopenharmony_ci return -1; 6776cd6a6acSopenharmony_ci } 6786cd6a6acSopenharmony_ci sepol_printf(out, "(defaultrole %s %s)\n", class_name, dft); 6796cd6a6acSopenharmony_ci 6806cd6a6acSopenharmony_ci return 0; 6816cd6a6acSopenharmony_ci} 6826cd6a6acSopenharmony_ci 6836cd6a6acSopenharmony_cistatic int write_default_type_to_cil(FILE *out, char *class_name, class_datum_t *class) 6846cd6a6acSopenharmony_ci{ 6856cd6a6acSopenharmony_ci const char *dft; 6866cd6a6acSopenharmony_ci 6876cd6a6acSopenharmony_ci switch (class->default_type) { 6886cd6a6acSopenharmony_ci case DEFAULT_SOURCE: 6896cd6a6acSopenharmony_ci dft = "source"; 6906cd6a6acSopenharmony_ci break; 6916cd6a6acSopenharmony_ci case DEFAULT_TARGET: 6926cd6a6acSopenharmony_ci dft = "target"; 6936cd6a6acSopenharmony_ci break; 6946cd6a6acSopenharmony_ci default: 6956cd6a6acSopenharmony_ci sepol_log_err("Unknown default type value: %i", class->default_type); 6966cd6a6acSopenharmony_ci return -1; 6976cd6a6acSopenharmony_ci } 6986cd6a6acSopenharmony_ci sepol_printf(out, "(defaulttype %s %s)\n", class_name, dft); 6996cd6a6acSopenharmony_ci 7006cd6a6acSopenharmony_ci return 0; 7016cd6a6acSopenharmony_ci} 7026cd6a6acSopenharmony_ci 7036cd6a6acSopenharmony_cistatic int write_default_range_to_cil(FILE *out, char *class_name, class_datum_t *class) 7046cd6a6acSopenharmony_ci{ 7056cd6a6acSopenharmony_ci const char *dft; 7066cd6a6acSopenharmony_ci 7076cd6a6acSopenharmony_ci switch (class->default_range) { 7086cd6a6acSopenharmony_ci case DEFAULT_SOURCE_LOW: 7096cd6a6acSopenharmony_ci dft = "source low"; 7106cd6a6acSopenharmony_ci break; 7116cd6a6acSopenharmony_ci case DEFAULT_SOURCE_HIGH: 7126cd6a6acSopenharmony_ci dft = "source high"; 7136cd6a6acSopenharmony_ci break; 7146cd6a6acSopenharmony_ci case DEFAULT_SOURCE_LOW_HIGH: 7156cd6a6acSopenharmony_ci dft = "source low-high"; 7166cd6a6acSopenharmony_ci break; 7176cd6a6acSopenharmony_ci case DEFAULT_TARGET_LOW: 7186cd6a6acSopenharmony_ci dft = "target low"; 7196cd6a6acSopenharmony_ci break; 7206cd6a6acSopenharmony_ci case DEFAULT_TARGET_HIGH: 7216cd6a6acSopenharmony_ci dft = "target high"; 7226cd6a6acSopenharmony_ci break; 7236cd6a6acSopenharmony_ci case DEFAULT_TARGET_LOW_HIGH: 7246cd6a6acSopenharmony_ci dft = "target low-high"; 7256cd6a6acSopenharmony_ci break; 7266cd6a6acSopenharmony_ci case DEFAULT_GLBLUB: 7276cd6a6acSopenharmony_ci dft = "glblub"; 7286cd6a6acSopenharmony_ci break; 7296cd6a6acSopenharmony_ci default: 7306cd6a6acSopenharmony_ci sepol_log_err("Unknown default type value: %i", class->default_range); 7316cd6a6acSopenharmony_ci return -1; 7326cd6a6acSopenharmony_ci } 7336cd6a6acSopenharmony_ci sepol_printf(out, "(defaultrange %s %s)\n", class_name, dft); 7346cd6a6acSopenharmony_ci 7356cd6a6acSopenharmony_ci return 0; 7366cd6a6acSopenharmony_ci} 7376cd6a6acSopenharmony_ci 7386cd6a6acSopenharmony_cistatic int write_default_rules_to_cil(FILE *out, struct policydb *pdb) 7396cd6a6acSopenharmony_ci{ 7406cd6a6acSopenharmony_ci class_datum_t *class; 7416cd6a6acSopenharmony_ci unsigned i; 7426cd6a6acSopenharmony_ci int rc = 0; 7436cd6a6acSopenharmony_ci 7446cd6a6acSopenharmony_ci /* default_user */ 7456cd6a6acSopenharmony_ci for (i=0; i < pdb->p_classes.nprim; i++) { 7466cd6a6acSopenharmony_ci class = pdb->class_val_to_struct[i]; 7476cd6a6acSopenharmony_ci if (!class) continue; 7486cd6a6acSopenharmony_ci if (class->default_user != 0) { 7496cd6a6acSopenharmony_ci rc = write_default_user_to_cil(out, pdb->p_class_val_to_name[i], class); 7506cd6a6acSopenharmony_ci if (rc != 0) { 7516cd6a6acSopenharmony_ci goto exit; 7526cd6a6acSopenharmony_ci } 7536cd6a6acSopenharmony_ci } 7546cd6a6acSopenharmony_ci } 7556cd6a6acSopenharmony_ci 7566cd6a6acSopenharmony_ci /* default_role */ 7576cd6a6acSopenharmony_ci for (i=0; i < pdb->p_classes.nprim; i++) { 7586cd6a6acSopenharmony_ci class = pdb->class_val_to_struct[i]; 7596cd6a6acSopenharmony_ci if (!class) continue; 7606cd6a6acSopenharmony_ci if (class->default_role != 0) { 7616cd6a6acSopenharmony_ci rc = write_default_role_to_cil(out, pdb->p_class_val_to_name[i], class); 7626cd6a6acSopenharmony_ci if (rc != 0) { 7636cd6a6acSopenharmony_ci goto exit; 7646cd6a6acSopenharmony_ci } 7656cd6a6acSopenharmony_ci } 7666cd6a6acSopenharmony_ci } 7676cd6a6acSopenharmony_ci 7686cd6a6acSopenharmony_ci /* default_type */ 7696cd6a6acSopenharmony_ci for (i=0; i < pdb->p_classes.nprim; i++) { 7706cd6a6acSopenharmony_ci class = pdb->class_val_to_struct[i]; 7716cd6a6acSopenharmony_ci if (!class) continue; 7726cd6a6acSopenharmony_ci if (class->default_type != 0) { 7736cd6a6acSopenharmony_ci rc = write_default_type_to_cil(out, pdb->p_class_val_to_name[i], class); 7746cd6a6acSopenharmony_ci if (rc != 0) { 7756cd6a6acSopenharmony_ci goto exit; 7766cd6a6acSopenharmony_ci } 7776cd6a6acSopenharmony_ci } 7786cd6a6acSopenharmony_ci } 7796cd6a6acSopenharmony_ci 7806cd6a6acSopenharmony_ci if (!pdb->mls) { 7816cd6a6acSopenharmony_ci return 0; 7826cd6a6acSopenharmony_ci } 7836cd6a6acSopenharmony_ci 7846cd6a6acSopenharmony_ci /* default_range */ 7856cd6a6acSopenharmony_ci for (i=0; i < pdb->p_classes.nprim; i++) { 7866cd6a6acSopenharmony_ci class = pdb->class_val_to_struct[i]; 7876cd6a6acSopenharmony_ci if (!class) continue; 7886cd6a6acSopenharmony_ci if (class->default_range) { 7896cd6a6acSopenharmony_ci rc = write_default_range_to_cil(out, pdb->p_class_val_to_name[i], class); 7906cd6a6acSopenharmony_ci if (rc != 0) { 7916cd6a6acSopenharmony_ci goto exit; 7926cd6a6acSopenharmony_ci } 7936cd6a6acSopenharmony_ci } 7946cd6a6acSopenharmony_ci } 7956cd6a6acSopenharmony_ci 7966cd6a6acSopenharmony_ciexit: 7976cd6a6acSopenharmony_ci if (rc != 0) { 7986cd6a6acSopenharmony_ci sepol_log_err("Error writing default rules to CIL\n"); 7996cd6a6acSopenharmony_ci } 8006cd6a6acSopenharmony_ci 8016cd6a6acSopenharmony_ci return rc; 8026cd6a6acSopenharmony_ci} 8036cd6a6acSopenharmony_ci 8046cd6a6acSopenharmony_cistatic void write_default_mls_level(FILE *out) 8056cd6a6acSopenharmony_ci{ 8066cd6a6acSopenharmony_ci sepol_printf(out, "(sensitivity s0)\n"); 8076cd6a6acSopenharmony_ci sepol_printf(out, "(sensitivityorder (s0))\n"); 8086cd6a6acSopenharmony_ci sepol_printf(out, "(level %s (s0))\n", DEFAULT_LEVEL); 8096cd6a6acSopenharmony_ci} 8106cd6a6acSopenharmony_ci 8116cd6a6acSopenharmony_cistatic int map_count_sensitivity_aliases(__attribute__((unused)) char *key, void *data, void *args) 8126cd6a6acSopenharmony_ci{ 8136cd6a6acSopenharmony_ci level_datum_t *sens = data; 8146cd6a6acSopenharmony_ci unsigned *count = args; 8156cd6a6acSopenharmony_ci 8166cd6a6acSopenharmony_ci if (sens->isalias) 8176cd6a6acSopenharmony_ci (*count)++; 8186cd6a6acSopenharmony_ci 8196cd6a6acSopenharmony_ci return SEPOL_OK; 8206cd6a6acSopenharmony_ci} 8216cd6a6acSopenharmony_ci 8226cd6a6acSopenharmony_cistatic int map_sensitivity_aliases_to_strs(char *key, void *data, void *args) 8236cd6a6acSopenharmony_ci{ 8246cd6a6acSopenharmony_ci level_datum_t *sens = data; 8256cd6a6acSopenharmony_ci struct strs *strs = args; 8266cd6a6acSopenharmony_ci int rc = 0; 8276cd6a6acSopenharmony_ci 8286cd6a6acSopenharmony_ci if (sens->isalias) { 8296cd6a6acSopenharmony_ci rc = strs_add(strs, key); 8306cd6a6acSopenharmony_ci } 8316cd6a6acSopenharmony_ci 8326cd6a6acSopenharmony_ci return rc; 8336cd6a6acSopenharmony_ci} 8346cd6a6acSopenharmony_ci 8356cd6a6acSopenharmony_cistatic int write_sensitivity_rules_to_cil(FILE *out, struct policydb *pdb) 8366cd6a6acSopenharmony_ci{ 8376cd6a6acSopenharmony_ci level_datum_t *level; 8386cd6a6acSopenharmony_ci char *prev, *name, *actual; 8396cd6a6acSopenharmony_ci struct strs *strs = NULL; 8406cd6a6acSopenharmony_ci unsigned i, num = 0; 8416cd6a6acSopenharmony_ci int rc = 0; 8426cd6a6acSopenharmony_ci 8436cd6a6acSopenharmony_ci /* sensitivities */ 8446cd6a6acSopenharmony_ci for (i=0; i < pdb->p_levels.nprim; i++) { 8456cd6a6acSopenharmony_ci name = pdb->p_sens_val_to_name[i]; 8466cd6a6acSopenharmony_ci sepol_printf(out, "(sensitivity %s)\n", name); 8476cd6a6acSopenharmony_ci } 8486cd6a6acSopenharmony_ci 8496cd6a6acSopenharmony_ci /* sensitivityorder */ 8506cd6a6acSopenharmony_ci sepol_printf(out, "(sensitivityorder ("); 8516cd6a6acSopenharmony_ci prev = NULL; 8526cd6a6acSopenharmony_ci for (i=0; i < pdb->p_levels.nprim; i++) { 8536cd6a6acSopenharmony_ci name = pdb->p_sens_val_to_name[i]; 8546cd6a6acSopenharmony_ci if (prev) { 8556cd6a6acSopenharmony_ci sepol_printf(out, "%s ", prev); 8566cd6a6acSopenharmony_ci } 8576cd6a6acSopenharmony_ci prev = name; 8586cd6a6acSopenharmony_ci } 8596cd6a6acSopenharmony_ci if (prev) { 8606cd6a6acSopenharmony_ci sepol_printf(out, "%s", prev); 8616cd6a6acSopenharmony_ci } 8626cd6a6acSopenharmony_ci sepol_printf(out, "))\n"); 8636cd6a6acSopenharmony_ci 8646cd6a6acSopenharmony_ci rc = hashtab_map(pdb->p_levels.table, map_count_sensitivity_aliases, &num); 8656cd6a6acSopenharmony_ci if (rc != 0) { 8666cd6a6acSopenharmony_ci goto exit; 8676cd6a6acSopenharmony_ci } 8686cd6a6acSopenharmony_ci 8696cd6a6acSopenharmony_ci if (num == 0) { 8706cd6a6acSopenharmony_ci /* No aliases, so skip sensitivity alias rules */ 8716cd6a6acSopenharmony_ci rc = 0; 8726cd6a6acSopenharmony_ci goto exit; 8736cd6a6acSopenharmony_ci } 8746cd6a6acSopenharmony_ci 8756cd6a6acSopenharmony_ci rc = strs_init(&strs, num); 8766cd6a6acSopenharmony_ci if (rc != 0) { 8776cd6a6acSopenharmony_ci goto exit; 8786cd6a6acSopenharmony_ci } 8796cd6a6acSopenharmony_ci 8806cd6a6acSopenharmony_ci rc = hashtab_map(pdb->p_levels.table, map_sensitivity_aliases_to_strs, strs); 8816cd6a6acSopenharmony_ci if (rc != 0) { 8826cd6a6acSopenharmony_ci goto exit; 8836cd6a6acSopenharmony_ci } 8846cd6a6acSopenharmony_ci 8856cd6a6acSopenharmony_ci strs_sort(strs); 8866cd6a6acSopenharmony_ci 8876cd6a6acSopenharmony_ci /* sensitivity aliases */ 8886cd6a6acSopenharmony_ci for (i=0; i < num; i++) { 8896cd6a6acSopenharmony_ci name = strs_read_at_index(strs, i); 8906cd6a6acSopenharmony_ci sepol_printf(out, "(sensitivityalias %s)\n", name); 8916cd6a6acSopenharmony_ci } 8926cd6a6acSopenharmony_ci 8936cd6a6acSopenharmony_ci /* sensitivity aliases to actual */ 8946cd6a6acSopenharmony_ci for (i=0; i < num; i++) { 8956cd6a6acSopenharmony_ci name = strs_read_at_index(strs, i); 8966cd6a6acSopenharmony_ci level = hashtab_search(pdb->p_levels.table, name); 8976cd6a6acSopenharmony_ci if (!level) { 8986cd6a6acSopenharmony_ci rc = -1; 8996cd6a6acSopenharmony_ci goto exit; 9006cd6a6acSopenharmony_ci } 9016cd6a6acSopenharmony_ci actual = pdb->p_sens_val_to_name[level->level->sens - 1]; 9026cd6a6acSopenharmony_ci sepol_printf(out, "(sensitivityaliasactual %s %s)\n", name, actual); 9036cd6a6acSopenharmony_ci } 9046cd6a6acSopenharmony_ci 9056cd6a6acSopenharmony_ciexit: 9066cd6a6acSopenharmony_ci strs_destroy(&strs); 9076cd6a6acSopenharmony_ci 9086cd6a6acSopenharmony_ci if (rc != 0) { 9096cd6a6acSopenharmony_ci sepol_log_err("Error writing sensitivity rules to CIL\n"); 9106cd6a6acSopenharmony_ci } 9116cd6a6acSopenharmony_ci 9126cd6a6acSopenharmony_ci return rc; 9136cd6a6acSopenharmony_ci} 9146cd6a6acSopenharmony_ci 9156cd6a6acSopenharmony_cistatic int map_count_category_aliases(__attribute__((unused)) char *key, void *data, void *args) 9166cd6a6acSopenharmony_ci{ 9176cd6a6acSopenharmony_ci cat_datum_t *cat = data; 9186cd6a6acSopenharmony_ci unsigned *count = args; 9196cd6a6acSopenharmony_ci 9206cd6a6acSopenharmony_ci if (cat->isalias) 9216cd6a6acSopenharmony_ci (*count)++; 9226cd6a6acSopenharmony_ci 9236cd6a6acSopenharmony_ci return SEPOL_OK; 9246cd6a6acSopenharmony_ci} 9256cd6a6acSopenharmony_ci 9266cd6a6acSopenharmony_cistatic int map_category_aliases_to_strs(char *key, void *data, void *args) 9276cd6a6acSopenharmony_ci{ 9286cd6a6acSopenharmony_ci cat_datum_t *cat = data; 9296cd6a6acSopenharmony_ci struct strs *strs = args; 9306cd6a6acSopenharmony_ci int rc = 0; 9316cd6a6acSopenharmony_ci 9326cd6a6acSopenharmony_ci if (cat->isalias) { 9336cd6a6acSopenharmony_ci rc = strs_add(strs, key); 9346cd6a6acSopenharmony_ci } 9356cd6a6acSopenharmony_ci 9366cd6a6acSopenharmony_ci return rc; 9376cd6a6acSopenharmony_ci} 9386cd6a6acSopenharmony_ci 9396cd6a6acSopenharmony_cistatic int write_category_rules_to_cil(FILE *out, struct policydb *pdb) 9406cd6a6acSopenharmony_ci{ 9416cd6a6acSopenharmony_ci cat_datum_t *cat; 9426cd6a6acSopenharmony_ci char *prev, *name, *actual; 9436cd6a6acSopenharmony_ci struct strs *strs = NULL; 9446cd6a6acSopenharmony_ci unsigned i, num = 0; 9456cd6a6acSopenharmony_ci int rc = 0; 9466cd6a6acSopenharmony_ci 9476cd6a6acSopenharmony_ci /* categories */ 9486cd6a6acSopenharmony_ci for (i=0; i < pdb->p_cats.nprim; i++) { 9496cd6a6acSopenharmony_ci name = pdb->p_cat_val_to_name[i]; 9506cd6a6acSopenharmony_ci sepol_printf(out, "(category %s)\n", name); 9516cd6a6acSopenharmony_ci } 9526cd6a6acSopenharmony_ci 9536cd6a6acSopenharmony_ci /* categoryorder */ 9546cd6a6acSopenharmony_ci sepol_printf(out, "(categoryorder ("); 9556cd6a6acSopenharmony_ci prev = NULL; 9566cd6a6acSopenharmony_ci for (i=0; i < pdb->p_cats.nprim; i++) { 9576cd6a6acSopenharmony_ci name = pdb->p_cat_val_to_name[i]; 9586cd6a6acSopenharmony_ci if (prev) { 9596cd6a6acSopenharmony_ci sepol_printf(out, "%s ", prev); 9606cd6a6acSopenharmony_ci } 9616cd6a6acSopenharmony_ci prev = name; 9626cd6a6acSopenharmony_ci } 9636cd6a6acSopenharmony_ci if (prev) { 9646cd6a6acSopenharmony_ci sepol_printf(out, "%s", prev); 9656cd6a6acSopenharmony_ci } 9666cd6a6acSopenharmony_ci sepol_printf(out, "))\n"); 9676cd6a6acSopenharmony_ci 9686cd6a6acSopenharmony_ci rc = hashtab_map(pdb->p_cats.table, map_count_category_aliases, &num); 9696cd6a6acSopenharmony_ci if (rc != 0) { 9706cd6a6acSopenharmony_ci goto exit; 9716cd6a6acSopenharmony_ci } 9726cd6a6acSopenharmony_ci 9736cd6a6acSopenharmony_ci if (num == 0) { 9746cd6a6acSopenharmony_ci /* No aliases, so skip category alias rules */ 9756cd6a6acSopenharmony_ci rc = 0; 9766cd6a6acSopenharmony_ci goto exit; 9776cd6a6acSopenharmony_ci } 9786cd6a6acSopenharmony_ci 9796cd6a6acSopenharmony_ci rc = strs_init(&strs, num); 9806cd6a6acSopenharmony_ci if (rc != 0) { 9816cd6a6acSopenharmony_ci goto exit; 9826cd6a6acSopenharmony_ci } 9836cd6a6acSopenharmony_ci 9846cd6a6acSopenharmony_ci rc = hashtab_map(pdb->p_cats.table, map_category_aliases_to_strs, strs); 9856cd6a6acSopenharmony_ci if (rc != 0) { 9866cd6a6acSopenharmony_ci goto exit; 9876cd6a6acSopenharmony_ci } 9886cd6a6acSopenharmony_ci 9896cd6a6acSopenharmony_ci strs_sort(strs); 9906cd6a6acSopenharmony_ci 9916cd6a6acSopenharmony_ci /* category aliases */ 9926cd6a6acSopenharmony_ci for (i=0; i < num; i++) { 9936cd6a6acSopenharmony_ci name = strs_read_at_index(strs, i); 9946cd6a6acSopenharmony_ci sepol_printf(out, "(categoryalias %s)\n", name); 9956cd6a6acSopenharmony_ci } 9966cd6a6acSopenharmony_ci 9976cd6a6acSopenharmony_ci /* category aliases to actual */ 9986cd6a6acSopenharmony_ci for (i=0; i < num; i++) { 9996cd6a6acSopenharmony_ci name = strs_read_at_index(strs, i); 10006cd6a6acSopenharmony_ci cat = hashtab_search(pdb->p_cats.table, name); 10016cd6a6acSopenharmony_ci if (!cat) { 10026cd6a6acSopenharmony_ci rc = -1; 10036cd6a6acSopenharmony_ci goto exit; 10046cd6a6acSopenharmony_ci } 10056cd6a6acSopenharmony_ci actual = pdb->p_cat_val_to_name[cat->s.value - 1]; 10066cd6a6acSopenharmony_ci sepol_printf(out, "(categoryaliasactual %s %s)\n", name, actual); 10076cd6a6acSopenharmony_ci } 10086cd6a6acSopenharmony_ci 10096cd6a6acSopenharmony_ciexit: 10106cd6a6acSopenharmony_ci strs_destroy(&strs); 10116cd6a6acSopenharmony_ci 10126cd6a6acSopenharmony_ci if (rc != 0) { 10136cd6a6acSopenharmony_ci sepol_log_err("Error writing category rules to CIL\n"); 10146cd6a6acSopenharmony_ci } 10156cd6a6acSopenharmony_ci 10166cd6a6acSopenharmony_ci return rc; 10176cd6a6acSopenharmony_ci} 10186cd6a6acSopenharmony_ci 10196cd6a6acSopenharmony_cistatic size_t cats_ebitmap_len(struct ebitmap *cats, char **val_to_name) 10206cd6a6acSopenharmony_ci{ 10216cd6a6acSopenharmony_ci struct ebitmap_node *node; 10226cd6a6acSopenharmony_ci uint32_t i, start, range; 10236cd6a6acSopenharmony_ci size_t len = 0; 10246cd6a6acSopenharmony_ci 10256cd6a6acSopenharmony_ci range = 0; 10266cd6a6acSopenharmony_ci ebitmap_for_each_positive_bit(cats, node, i) { 10276cd6a6acSopenharmony_ci if (range == 0) 10286cd6a6acSopenharmony_ci start = i; 10296cd6a6acSopenharmony_ci 10306cd6a6acSopenharmony_ci range++; 10316cd6a6acSopenharmony_ci 10326cd6a6acSopenharmony_ci if (ebitmap_get_bit(cats, i+1)) 10336cd6a6acSopenharmony_ci continue; 10346cd6a6acSopenharmony_ci 10356cd6a6acSopenharmony_ci len += strlen(val_to_name[start]); 10366cd6a6acSopenharmony_ci if (range > 2) { 10376cd6a6acSopenharmony_ci len += strlen(val_to_name[i-1]) + strlen("(range ) "); 10386cd6a6acSopenharmony_ci } else if (range == 2) { 10396cd6a6acSopenharmony_ci len += strlen(val_to_name[i-1]) + 2; 10406cd6a6acSopenharmony_ci } else if (range == 1) { 10416cd6a6acSopenharmony_ci len += 1; 10426cd6a6acSopenharmony_ci } 10436cd6a6acSopenharmony_ci 10446cd6a6acSopenharmony_ci range = 0; 10456cd6a6acSopenharmony_ci } 10466cd6a6acSopenharmony_ci 10476cd6a6acSopenharmony_ci if (len > 0) { 10486cd6a6acSopenharmony_ci len += 2; /* For '(' and ')'. '\0' overwrites last ' ' */ 10496cd6a6acSopenharmony_ci } 10506cd6a6acSopenharmony_ci 10516cd6a6acSopenharmony_ci return len; 10526cd6a6acSopenharmony_ci} 10536cd6a6acSopenharmony_ci 10546cd6a6acSopenharmony_cistatic char *cats_ebitmap_to_str(struct ebitmap *cats, char **val_to_name) 10556cd6a6acSopenharmony_ci{ 10566cd6a6acSopenharmony_ci struct ebitmap_node *node; 10576cd6a6acSopenharmony_ci uint32_t i, start, range; 10586cd6a6acSopenharmony_ci char *catsbuf = NULL, *p; 10596cd6a6acSopenharmony_ci int len, remaining; 10606cd6a6acSopenharmony_ci 10616cd6a6acSopenharmony_ci remaining = (int)cats_ebitmap_len(cats, val_to_name); 10626cd6a6acSopenharmony_ci if (remaining == 0) { 10636cd6a6acSopenharmony_ci goto exit; 10646cd6a6acSopenharmony_ci } 10656cd6a6acSopenharmony_ci catsbuf = malloc(remaining); 10666cd6a6acSopenharmony_ci if (!catsbuf) { 10676cd6a6acSopenharmony_ci goto exit; 10686cd6a6acSopenharmony_ci } 10696cd6a6acSopenharmony_ci 10706cd6a6acSopenharmony_ci p = catsbuf; 10716cd6a6acSopenharmony_ci 10726cd6a6acSopenharmony_ci *p++ = '('; 10736cd6a6acSopenharmony_ci remaining--; 10746cd6a6acSopenharmony_ci 10756cd6a6acSopenharmony_ci range = 0; 10766cd6a6acSopenharmony_ci ebitmap_for_each_positive_bit(cats, node, i) { 10776cd6a6acSopenharmony_ci if (range == 0) 10786cd6a6acSopenharmony_ci start = i; 10796cd6a6acSopenharmony_ci 10806cd6a6acSopenharmony_ci range++; 10816cd6a6acSopenharmony_ci 10826cd6a6acSopenharmony_ci if (ebitmap_get_bit(cats, i+1)) 10836cd6a6acSopenharmony_ci continue; 10846cd6a6acSopenharmony_ci 10856cd6a6acSopenharmony_ci if (range > 1) { 10866cd6a6acSopenharmony_ci if (range == 2) { 10876cd6a6acSopenharmony_ci len = snprintf(p, remaining, "%s %s ", 10886cd6a6acSopenharmony_ci val_to_name[start], 10896cd6a6acSopenharmony_ci val_to_name[i]); 10906cd6a6acSopenharmony_ci } else { 10916cd6a6acSopenharmony_ci len = snprintf(p, remaining, "(range %s %s) ", 10926cd6a6acSopenharmony_ci val_to_name[start], 10936cd6a6acSopenharmony_ci val_to_name[i]); 10946cd6a6acSopenharmony_ci } 10956cd6a6acSopenharmony_ci } else { 10966cd6a6acSopenharmony_ci len = snprintf(p, remaining, "%s ", val_to_name[start]); 10976cd6a6acSopenharmony_ci } 10986cd6a6acSopenharmony_ci if (len < 0 || len >= remaining) { 10996cd6a6acSopenharmony_ci goto exit; 11006cd6a6acSopenharmony_ci } 11016cd6a6acSopenharmony_ci p += len; 11026cd6a6acSopenharmony_ci remaining -= len; 11036cd6a6acSopenharmony_ci 11046cd6a6acSopenharmony_ci range = 0; 11056cd6a6acSopenharmony_ci } 11066cd6a6acSopenharmony_ci 11076cd6a6acSopenharmony_ci *(p-1) = ')'; /* Remove trailing ' ' */ 11086cd6a6acSopenharmony_ci *p = '\0'; 11096cd6a6acSopenharmony_ci 11106cd6a6acSopenharmony_ci return catsbuf; 11116cd6a6acSopenharmony_ci 11126cd6a6acSopenharmony_ciexit: 11136cd6a6acSopenharmony_ci free(catsbuf); 11146cd6a6acSopenharmony_ci return NULL; 11156cd6a6acSopenharmony_ci} 11166cd6a6acSopenharmony_ci 11176cd6a6acSopenharmony_cistatic int write_sensitivitycategory_rules_to_cil(FILE *out, struct policydb *pdb) 11186cd6a6acSopenharmony_ci{ 11196cd6a6acSopenharmony_ci level_datum_t *level; 11206cd6a6acSopenharmony_ci char *name, *cats; 11216cd6a6acSopenharmony_ci unsigned i; 11226cd6a6acSopenharmony_ci int rc = 0; 11236cd6a6acSopenharmony_ci 11246cd6a6acSopenharmony_ci /* sensitivities */ 11256cd6a6acSopenharmony_ci for (i=0; i < pdb->p_levels.nprim; i++) { 11266cd6a6acSopenharmony_ci name = pdb->p_sens_val_to_name[i]; 11276cd6a6acSopenharmony_ci if (!name) continue; 11286cd6a6acSopenharmony_ci level = hashtab_search(pdb->p_levels.table, name); 11296cd6a6acSopenharmony_ci if (!level) { 11306cd6a6acSopenharmony_ci rc = -1; 11316cd6a6acSopenharmony_ci goto exit; 11326cd6a6acSopenharmony_ci } 11336cd6a6acSopenharmony_ci if (level->isalias) continue; 11346cd6a6acSopenharmony_ci 11356cd6a6acSopenharmony_ci if (!ebitmap_is_empty(&level->level->cat)) { 11366cd6a6acSopenharmony_ci cats = cats_ebitmap_to_str(&level->level->cat, pdb->p_cat_val_to_name); 11376cd6a6acSopenharmony_ci sepol_printf(out, "(sensitivitycategory %s %s)\n", name, cats); 11386cd6a6acSopenharmony_ci free(cats); 11396cd6a6acSopenharmony_ci } 11406cd6a6acSopenharmony_ci } 11416cd6a6acSopenharmony_ci 11426cd6a6acSopenharmony_ciexit: 11436cd6a6acSopenharmony_ci if (rc != 0) { 11446cd6a6acSopenharmony_ci sepol_log_err("Error writing sensitivitycategory rules to CIL\n"); 11456cd6a6acSopenharmony_ci } 11466cd6a6acSopenharmony_ci 11476cd6a6acSopenharmony_ci return rc; 11486cd6a6acSopenharmony_ci} 11496cd6a6acSopenharmony_ci 11506cd6a6acSopenharmony_cistatic int write_mls_rules_to_cil(FILE *out, struct policydb *pdb) 11516cd6a6acSopenharmony_ci{ 11526cd6a6acSopenharmony_ci int rc = 0; 11536cd6a6acSopenharmony_ci 11546cd6a6acSopenharmony_ci if (!pdb->mls) { 11556cd6a6acSopenharmony_ci sepol_printf(out, "(mls false)\n"); 11566cd6a6acSopenharmony_ci /* CIL requires MLS, even if the kernel binary won't have it */ 11576cd6a6acSopenharmony_ci write_default_mls_level(out); 11586cd6a6acSopenharmony_ci return 0; 11596cd6a6acSopenharmony_ci } 11606cd6a6acSopenharmony_ci 11616cd6a6acSopenharmony_ci sepol_printf(out, "(mls true)\n"); 11626cd6a6acSopenharmony_ci 11636cd6a6acSopenharmony_ci rc = write_sensitivity_rules_to_cil(out, pdb); 11646cd6a6acSopenharmony_ci if (rc != 0) { 11656cd6a6acSopenharmony_ci goto exit; 11666cd6a6acSopenharmony_ci } 11676cd6a6acSopenharmony_ci 11686cd6a6acSopenharmony_ci rc = write_category_rules_to_cil(out, pdb); 11696cd6a6acSopenharmony_ci if (rc != 0) { 11706cd6a6acSopenharmony_ci goto exit; 11716cd6a6acSopenharmony_ci } 11726cd6a6acSopenharmony_ci 11736cd6a6acSopenharmony_ci rc = write_sensitivitycategory_rules_to_cil(out, pdb); 11746cd6a6acSopenharmony_ci if (rc != 0) { 11756cd6a6acSopenharmony_ci goto exit; 11766cd6a6acSopenharmony_ci } 11776cd6a6acSopenharmony_ci 11786cd6a6acSopenharmony_ciexit: 11796cd6a6acSopenharmony_ci if (rc != 0) { 11806cd6a6acSopenharmony_ci sepol_log_err("Error writing mls rules to CIL\n"); 11816cd6a6acSopenharmony_ci } 11826cd6a6acSopenharmony_ci 11836cd6a6acSopenharmony_ci return rc; 11846cd6a6acSopenharmony_ci} 11856cd6a6acSopenharmony_ci 11866cd6a6acSopenharmony_cistatic int write_polcap_rules_to_cil(FILE *out, struct policydb *pdb) 11876cd6a6acSopenharmony_ci{ 11886cd6a6acSopenharmony_ci struct strs *strs; 11896cd6a6acSopenharmony_ci struct ebitmap_node *node; 11906cd6a6acSopenharmony_ci const char *name; 11916cd6a6acSopenharmony_ci uint32_t i; 11926cd6a6acSopenharmony_ci int rc = 0; 11936cd6a6acSopenharmony_ci 11946cd6a6acSopenharmony_ci rc = strs_init(&strs, 32); 11956cd6a6acSopenharmony_ci if (rc != 0) { 11966cd6a6acSopenharmony_ci goto exit; 11976cd6a6acSopenharmony_ci } 11986cd6a6acSopenharmony_ci 11996cd6a6acSopenharmony_ci ebitmap_for_each_positive_bit(&pdb->policycaps, node, i) { 12006cd6a6acSopenharmony_ci name = sepol_polcap_getname(i); 12016cd6a6acSopenharmony_ci if (name == NULL) { 12026cd6a6acSopenharmony_ci sepol_log_err("Unknown policy capability id: %i", i); 12036cd6a6acSopenharmony_ci rc = -1; 12046cd6a6acSopenharmony_ci goto exit; 12056cd6a6acSopenharmony_ci } 12066cd6a6acSopenharmony_ci 12076cd6a6acSopenharmony_ci rc = strs_create_and_add(strs, "(policycap %s)", 1, name); 12086cd6a6acSopenharmony_ci if (rc != 0) { 12096cd6a6acSopenharmony_ci goto exit; 12106cd6a6acSopenharmony_ci } 12116cd6a6acSopenharmony_ci } 12126cd6a6acSopenharmony_ci 12136cd6a6acSopenharmony_ci strs_sort(strs); 12146cd6a6acSopenharmony_ci strs_write_each(strs, out); 12156cd6a6acSopenharmony_ci 12166cd6a6acSopenharmony_ciexit: 12176cd6a6acSopenharmony_ci strs_free_all(strs); 12186cd6a6acSopenharmony_ci strs_destroy(&strs); 12196cd6a6acSopenharmony_ci 12206cd6a6acSopenharmony_ci if (rc != 0) { 12216cd6a6acSopenharmony_ci sepol_log_err("Error writing polcap rules to CIL\n"); 12226cd6a6acSopenharmony_ci } 12236cd6a6acSopenharmony_ci 12246cd6a6acSopenharmony_ci return rc; 12256cd6a6acSopenharmony_ci} 12266cd6a6acSopenharmony_ci 12276cd6a6acSopenharmony_cistatic int write_type_attributes_to_cil(FILE *out, struct policydb *pdb) 12286cd6a6acSopenharmony_ci{ 12296cd6a6acSopenharmony_ci type_datum_t *type; 12306cd6a6acSopenharmony_ci char *name; 12316cd6a6acSopenharmony_ci struct strs *strs; 12326cd6a6acSopenharmony_ci unsigned i, num; 12336cd6a6acSopenharmony_ci int rc = 0; 12346cd6a6acSopenharmony_ci 12356cd6a6acSopenharmony_ci rc = strs_init(&strs, pdb->p_types.nprim); 12366cd6a6acSopenharmony_ci if (rc != 0) { 12376cd6a6acSopenharmony_ci goto exit; 12386cd6a6acSopenharmony_ci } 12396cd6a6acSopenharmony_ci 12406cd6a6acSopenharmony_ci for (i=0; i < pdb->p_types.nprim; i++) { 12416cd6a6acSopenharmony_ci type = pdb->type_val_to_struct[i]; 12426cd6a6acSopenharmony_ci if (type && type->flavor == TYPE_ATTRIB) { 12436cd6a6acSopenharmony_ci rc = strs_add(strs, pdb->p_type_val_to_name[i]); 12446cd6a6acSopenharmony_ci if (rc != 0) { 12456cd6a6acSopenharmony_ci goto exit; 12466cd6a6acSopenharmony_ci } 12476cd6a6acSopenharmony_ci } 12486cd6a6acSopenharmony_ci } 12496cd6a6acSopenharmony_ci 12506cd6a6acSopenharmony_ci strs_sort(strs); 12516cd6a6acSopenharmony_ci 12526cd6a6acSopenharmony_ci num = strs_num_items(strs); 12536cd6a6acSopenharmony_ci for (i = 0; i < num; i++) { 12546cd6a6acSopenharmony_ci name = strs_read_at_index(strs, i); 12556cd6a6acSopenharmony_ci if (!name) { 12566cd6a6acSopenharmony_ci rc = -1; 12576cd6a6acSopenharmony_ci goto exit; 12586cd6a6acSopenharmony_ci } 12596cd6a6acSopenharmony_ci sepol_printf(out, "(typeattribute %s)\n", name); 12606cd6a6acSopenharmony_ci } 12616cd6a6acSopenharmony_ci 12626cd6a6acSopenharmony_ciexit: 12636cd6a6acSopenharmony_ci strs_destroy(&strs); 12646cd6a6acSopenharmony_ci 12656cd6a6acSopenharmony_ci if (rc != 0) { 12666cd6a6acSopenharmony_ci sepol_log_err("Error writing typeattribute rules to CIL\n"); 12676cd6a6acSopenharmony_ci } 12686cd6a6acSopenharmony_ci 12696cd6a6acSopenharmony_ci return rc; 12706cd6a6acSopenharmony_ci} 12716cd6a6acSopenharmony_ci 12726cd6a6acSopenharmony_cistatic int write_role_attributes_to_cil(FILE *out, struct policydb *pdb) 12736cd6a6acSopenharmony_ci{ 12746cd6a6acSopenharmony_ci role_datum_t *role; 12756cd6a6acSopenharmony_ci char *name; 12766cd6a6acSopenharmony_ci struct strs *strs; 12776cd6a6acSopenharmony_ci unsigned i, num; 12786cd6a6acSopenharmony_ci int rc = 0; 12796cd6a6acSopenharmony_ci 12806cd6a6acSopenharmony_ci rc = strs_init(&strs, pdb->p_roles.nprim); 12816cd6a6acSopenharmony_ci if (rc != 0) { 12826cd6a6acSopenharmony_ci goto exit; 12836cd6a6acSopenharmony_ci } 12846cd6a6acSopenharmony_ci 12856cd6a6acSopenharmony_ci for (i=0; i < pdb->p_roles.nprim; i++) { 12866cd6a6acSopenharmony_ci role = pdb->role_val_to_struct[i]; 12876cd6a6acSopenharmony_ci if (role && role->flavor == ROLE_ATTRIB) { 12886cd6a6acSopenharmony_ci rc = strs_add(strs, pdb->p_role_val_to_name[i]); 12896cd6a6acSopenharmony_ci if (rc != 0) { 12906cd6a6acSopenharmony_ci goto exit; 12916cd6a6acSopenharmony_ci } 12926cd6a6acSopenharmony_ci } 12936cd6a6acSopenharmony_ci } 12946cd6a6acSopenharmony_ci 12956cd6a6acSopenharmony_ci strs_sort(strs); 12966cd6a6acSopenharmony_ci 12976cd6a6acSopenharmony_ci num = strs_num_items(strs); 12986cd6a6acSopenharmony_ci for (i=0; i<num; i++) { 12996cd6a6acSopenharmony_ci name = strs_read_at_index(strs, i); 13006cd6a6acSopenharmony_ci if (!name) { 13016cd6a6acSopenharmony_ci rc = -1; 13026cd6a6acSopenharmony_ci goto exit; 13036cd6a6acSopenharmony_ci } 13046cd6a6acSopenharmony_ci sepol_printf(out, "(roleattribute %s)\n", name); 13056cd6a6acSopenharmony_ci } 13066cd6a6acSopenharmony_ci 13076cd6a6acSopenharmony_ciexit: 13086cd6a6acSopenharmony_ci strs_destroy(&strs); 13096cd6a6acSopenharmony_ci 13106cd6a6acSopenharmony_ci if (rc != 0) { 13116cd6a6acSopenharmony_ci sepol_log_err("Error writing roleattribute rules to CIL\n"); 13126cd6a6acSopenharmony_ci } 13136cd6a6acSopenharmony_ci 13146cd6a6acSopenharmony_ci return rc; 13156cd6a6acSopenharmony_ci} 13166cd6a6acSopenharmony_ci 13176cd6a6acSopenharmony_cistatic int map_boolean_to_strs(char *key, void *data, void *args) 13186cd6a6acSopenharmony_ci{ 13196cd6a6acSopenharmony_ci struct strs *strs = (struct strs *)args; 13206cd6a6acSopenharmony_ci struct cond_bool_datum *boolean = data; 13216cd6a6acSopenharmony_ci const char *value; 13226cd6a6acSopenharmony_ci 13236cd6a6acSopenharmony_ci value = boolean->state ? "true" : "false"; 13246cd6a6acSopenharmony_ci 13256cd6a6acSopenharmony_ci return strs_create_and_add(strs, "(boolean %s %s)", 2, key, value); 13266cd6a6acSopenharmony_ci} 13276cd6a6acSopenharmony_ci 13286cd6a6acSopenharmony_cistatic int write_boolean_decl_rules_to_cil(FILE *out, struct policydb *pdb) 13296cd6a6acSopenharmony_ci{ 13306cd6a6acSopenharmony_ci struct strs *strs; 13316cd6a6acSopenharmony_ci int rc = 0; 13326cd6a6acSopenharmony_ci 13336cd6a6acSopenharmony_ci rc = strs_init(&strs, 32); 13346cd6a6acSopenharmony_ci if (rc != 0) { 13356cd6a6acSopenharmony_ci goto exit; 13366cd6a6acSopenharmony_ci } 13376cd6a6acSopenharmony_ci 13386cd6a6acSopenharmony_ci rc = hashtab_map(pdb->p_bools.table, map_boolean_to_strs, strs); 13396cd6a6acSopenharmony_ci if (rc != 0) { 13406cd6a6acSopenharmony_ci goto exit; 13416cd6a6acSopenharmony_ci } 13426cd6a6acSopenharmony_ci 13436cd6a6acSopenharmony_ci strs_sort(strs); 13446cd6a6acSopenharmony_ci strs_write_each(strs, out); 13456cd6a6acSopenharmony_ci 13466cd6a6acSopenharmony_ciexit: 13476cd6a6acSopenharmony_ci strs_free_all(strs); 13486cd6a6acSopenharmony_ci strs_destroy(&strs); 13496cd6a6acSopenharmony_ci 13506cd6a6acSopenharmony_ci if (rc != 0) { 13516cd6a6acSopenharmony_ci sepol_log_err("Error writing boolean declarations to CIL\n"); 13526cd6a6acSopenharmony_ci } 13536cd6a6acSopenharmony_ci 13546cd6a6acSopenharmony_ci return rc; 13556cd6a6acSopenharmony_ci} 13566cd6a6acSopenharmony_ci 13576cd6a6acSopenharmony_cistatic int write_type_decl_rules_to_cil(FILE *out, struct policydb *pdb) 13586cd6a6acSopenharmony_ci{ 13596cd6a6acSopenharmony_ci type_datum_t *type; 13606cd6a6acSopenharmony_ci struct strs *strs; 13616cd6a6acSopenharmony_ci char *name; 13626cd6a6acSopenharmony_ci unsigned i, num; 13636cd6a6acSopenharmony_ci int rc = 0; 13646cd6a6acSopenharmony_ci 13656cd6a6acSopenharmony_ci rc = strs_init(&strs, pdb->p_types.nprim); 13666cd6a6acSopenharmony_ci if (rc != 0) { 13676cd6a6acSopenharmony_ci goto exit; 13686cd6a6acSopenharmony_ci } 13696cd6a6acSopenharmony_ci 13706cd6a6acSopenharmony_ci for (i=0; i < pdb->p_types.nprim; i++) { 13716cd6a6acSopenharmony_ci type = pdb->type_val_to_struct[i]; 13726cd6a6acSopenharmony_ci if (type && type->flavor == TYPE_TYPE && type->primary) { 13736cd6a6acSopenharmony_ci rc = strs_add(strs, pdb->p_type_val_to_name[i]); 13746cd6a6acSopenharmony_ci if (rc != 0) { 13756cd6a6acSopenharmony_ci goto exit; 13766cd6a6acSopenharmony_ci } 13776cd6a6acSopenharmony_ci } 13786cd6a6acSopenharmony_ci } 13796cd6a6acSopenharmony_ci 13806cd6a6acSopenharmony_ci strs_sort(strs); 13816cd6a6acSopenharmony_ci 13826cd6a6acSopenharmony_ci num = strs_num_items(strs); 13836cd6a6acSopenharmony_ci for (i=0; i<num; i++) { 13846cd6a6acSopenharmony_ci name = strs_read_at_index(strs, i); 13856cd6a6acSopenharmony_ci if (!name) { 13866cd6a6acSopenharmony_ci rc = -1; 13876cd6a6acSopenharmony_ci goto exit; 13886cd6a6acSopenharmony_ci } 13896cd6a6acSopenharmony_ci sepol_printf(out, "(type %s)\n", name); 13906cd6a6acSopenharmony_ci } 13916cd6a6acSopenharmony_ci 13926cd6a6acSopenharmony_ciexit: 13936cd6a6acSopenharmony_ci strs_destroy(&strs); 13946cd6a6acSopenharmony_ci 13956cd6a6acSopenharmony_ci if (rc != 0) { 13966cd6a6acSopenharmony_ci sepol_log_err("Error writing type declarations to CIL\n"); 13976cd6a6acSopenharmony_ci } 13986cd6a6acSopenharmony_ci 13996cd6a6acSopenharmony_ci return rc; 14006cd6a6acSopenharmony_ci} 14016cd6a6acSopenharmony_ci 14026cd6a6acSopenharmony_cistatic int map_count_type_aliases(__attribute__((unused)) char *key, void *data, void *args) 14036cd6a6acSopenharmony_ci{ 14046cd6a6acSopenharmony_ci type_datum_t *datum = data; 14056cd6a6acSopenharmony_ci unsigned *count = args; 14066cd6a6acSopenharmony_ci 14076cd6a6acSopenharmony_ci if (datum->primary == 0 && datum->flavor == TYPE_TYPE) 14086cd6a6acSopenharmony_ci (*count)++; 14096cd6a6acSopenharmony_ci 14106cd6a6acSopenharmony_ci return SEPOL_OK; 14116cd6a6acSopenharmony_ci} 14126cd6a6acSopenharmony_ci 14136cd6a6acSopenharmony_cistatic int map_type_aliases_to_strs(char *key, void *data, void *args) 14146cd6a6acSopenharmony_ci{ 14156cd6a6acSopenharmony_ci type_datum_t *datum = data; 14166cd6a6acSopenharmony_ci struct strs *strs = args; 14176cd6a6acSopenharmony_ci int rc = 0; 14186cd6a6acSopenharmony_ci 14196cd6a6acSopenharmony_ci if (datum->primary == 0 && datum->flavor == TYPE_TYPE) 14206cd6a6acSopenharmony_ci rc = strs_add(strs, key); 14216cd6a6acSopenharmony_ci 14226cd6a6acSopenharmony_ci return rc; 14236cd6a6acSopenharmony_ci} 14246cd6a6acSopenharmony_ci 14256cd6a6acSopenharmony_cistatic int write_type_alias_rules_to_cil(FILE *out, struct policydb *pdb) 14266cd6a6acSopenharmony_ci{ 14276cd6a6acSopenharmony_ci type_datum_t *alias; 14286cd6a6acSopenharmony_ci struct strs *strs; 14296cd6a6acSopenharmony_ci char *name; 14306cd6a6acSopenharmony_ci char *type; 14316cd6a6acSopenharmony_ci unsigned i, num = 0; 14326cd6a6acSopenharmony_ci int rc = 0; 14336cd6a6acSopenharmony_ci 14346cd6a6acSopenharmony_ci rc = hashtab_map(pdb->p_types.table, map_count_type_aliases, &num); 14356cd6a6acSopenharmony_ci if (rc != 0) { 14366cd6a6acSopenharmony_ci goto exit; 14376cd6a6acSopenharmony_ci } 14386cd6a6acSopenharmony_ci 14396cd6a6acSopenharmony_ci rc = strs_init(&strs, num); 14406cd6a6acSopenharmony_ci if (rc != 0) { 14416cd6a6acSopenharmony_ci goto exit; 14426cd6a6acSopenharmony_ci } 14436cd6a6acSopenharmony_ci 14446cd6a6acSopenharmony_ci rc = hashtab_map(pdb->p_types.table, map_type_aliases_to_strs, strs); 14456cd6a6acSopenharmony_ci if (rc != 0) { 14466cd6a6acSopenharmony_ci goto exit; 14476cd6a6acSopenharmony_ci } 14486cd6a6acSopenharmony_ci 14496cd6a6acSopenharmony_ci strs_sort(strs); 14506cd6a6acSopenharmony_ci 14516cd6a6acSopenharmony_ci for (i=0; i<num; i++) { 14526cd6a6acSopenharmony_ci name = strs_read_at_index(strs, i); 14536cd6a6acSopenharmony_ci if (!name) { 14546cd6a6acSopenharmony_ci rc = -1; 14556cd6a6acSopenharmony_ci goto exit; 14566cd6a6acSopenharmony_ci } 14576cd6a6acSopenharmony_ci sepol_printf(out, "(typealias %s)\n", name); 14586cd6a6acSopenharmony_ci } 14596cd6a6acSopenharmony_ci 14606cd6a6acSopenharmony_ci for (i=0; i<num; i++) { 14616cd6a6acSopenharmony_ci name = strs_read_at_index(strs, i); 14626cd6a6acSopenharmony_ci if (!name) { 14636cd6a6acSopenharmony_ci rc = -1; 14646cd6a6acSopenharmony_ci goto exit; 14656cd6a6acSopenharmony_ci } 14666cd6a6acSopenharmony_ci alias = hashtab_search(pdb->p_types.table, name); 14676cd6a6acSopenharmony_ci if (!alias) { 14686cd6a6acSopenharmony_ci rc = -1; 14696cd6a6acSopenharmony_ci goto exit; 14706cd6a6acSopenharmony_ci } 14716cd6a6acSopenharmony_ci type = pdb->p_type_val_to_name[alias->s.value - 1]; 14726cd6a6acSopenharmony_ci sepol_printf(out, "(typealiasactual %s %s)\n", name, type); 14736cd6a6acSopenharmony_ci } 14746cd6a6acSopenharmony_ci 14756cd6a6acSopenharmony_ciexit: 14766cd6a6acSopenharmony_ci strs_destroy(&strs); 14776cd6a6acSopenharmony_ci 14786cd6a6acSopenharmony_ci if (rc != 0) { 14796cd6a6acSopenharmony_ci sepol_log_err("Error writing type alias rules to CIL\n"); 14806cd6a6acSopenharmony_ci } 14816cd6a6acSopenharmony_ci 14826cd6a6acSopenharmony_ci return rc; 14836cd6a6acSopenharmony_ci} 14846cd6a6acSopenharmony_ci 14856cd6a6acSopenharmony_cistatic int write_type_bounds_rules_to_cil(FILE *out, struct policydb *pdb) 14866cd6a6acSopenharmony_ci{ 14876cd6a6acSopenharmony_ci type_datum_t *type; 14886cd6a6acSopenharmony_ci struct strs *strs; 14896cd6a6acSopenharmony_ci char *parent; 14906cd6a6acSopenharmony_ci char *child; 14916cd6a6acSopenharmony_ci unsigned i, num; 14926cd6a6acSopenharmony_ci int rc = 0; 14936cd6a6acSopenharmony_ci 14946cd6a6acSopenharmony_ci rc = strs_init(&strs, pdb->p_types.nprim); 14956cd6a6acSopenharmony_ci if (rc != 0) { 14966cd6a6acSopenharmony_ci goto exit; 14976cd6a6acSopenharmony_ci } 14986cd6a6acSopenharmony_ci 14996cd6a6acSopenharmony_ci for (i=0; i < pdb->p_types.nprim; i++) { 15006cd6a6acSopenharmony_ci type = pdb->type_val_to_struct[i]; 15016cd6a6acSopenharmony_ci if (type && type->flavor == TYPE_TYPE) { 15026cd6a6acSopenharmony_ci if (type->bounds > 0) { 15036cd6a6acSopenharmony_ci rc = strs_add(strs, pdb->p_type_val_to_name[i]); 15046cd6a6acSopenharmony_ci if (rc != 0) { 15056cd6a6acSopenharmony_ci goto exit; 15066cd6a6acSopenharmony_ci } 15076cd6a6acSopenharmony_ci } 15086cd6a6acSopenharmony_ci } 15096cd6a6acSopenharmony_ci } 15106cd6a6acSopenharmony_ci 15116cd6a6acSopenharmony_ci strs_sort(strs); 15126cd6a6acSopenharmony_ci 15136cd6a6acSopenharmony_ci num = strs_num_items(strs); 15146cd6a6acSopenharmony_ci for (i=0; i<num; i++) { 15156cd6a6acSopenharmony_ci child = strs_read_at_index(strs, i); 15166cd6a6acSopenharmony_ci if (!child) { 15176cd6a6acSopenharmony_ci rc = -1; 15186cd6a6acSopenharmony_ci goto exit; 15196cd6a6acSopenharmony_ci } 15206cd6a6acSopenharmony_ci type = hashtab_search(pdb->p_types.table, child); 15216cd6a6acSopenharmony_ci if (!type) { 15226cd6a6acSopenharmony_ci rc = -1; 15236cd6a6acSopenharmony_ci goto exit; 15246cd6a6acSopenharmony_ci } 15256cd6a6acSopenharmony_ci parent = pdb->p_type_val_to_name[type->bounds - 1]; 15266cd6a6acSopenharmony_ci sepol_printf(out, "(typebounds %s %s)\n", parent, child); 15276cd6a6acSopenharmony_ci } 15286cd6a6acSopenharmony_ci 15296cd6a6acSopenharmony_ciexit: 15306cd6a6acSopenharmony_ci strs_destroy(&strs); 15316cd6a6acSopenharmony_ci 15326cd6a6acSopenharmony_ci if (rc != 0) { 15336cd6a6acSopenharmony_ci sepol_log_err("Error writing type bounds rules to CIL\n"); 15346cd6a6acSopenharmony_ci } 15356cd6a6acSopenharmony_ci 15366cd6a6acSopenharmony_ci return rc; 15376cd6a6acSopenharmony_ci} 15386cd6a6acSopenharmony_ci 15396cd6a6acSopenharmony_cistatic int write_type_attribute_sets_to_cil(FILE *out, struct policydb *pdb) 15406cd6a6acSopenharmony_ci{ 15416cd6a6acSopenharmony_ci type_datum_t *attr; 15426cd6a6acSopenharmony_ci struct strs *strs; 15436cd6a6acSopenharmony_ci ebitmap_t *typemap; 15446cd6a6acSopenharmony_ci char *name, *types; 15456cd6a6acSopenharmony_ci unsigned i; 15466cd6a6acSopenharmony_ci int rc; 15476cd6a6acSopenharmony_ci 15486cd6a6acSopenharmony_ci rc = strs_init(&strs, pdb->p_types.nprim); 15496cd6a6acSopenharmony_ci if (rc != 0) { 15506cd6a6acSopenharmony_ci goto exit; 15516cd6a6acSopenharmony_ci } 15526cd6a6acSopenharmony_ci 15536cd6a6acSopenharmony_ci for (i=0; i < pdb->p_types.nprim; i++) { 15546cd6a6acSopenharmony_ci attr = pdb->type_val_to_struct[i]; 15556cd6a6acSopenharmony_ci if (!attr || attr->flavor != TYPE_ATTRIB) continue; 15566cd6a6acSopenharmony_ci name = pdb->p_type_val_to_name[i]; 15576cd6a6acSopenharmony_ci typemap = &pdb->attr_type_map[i]; 15586cd6a6acSopenharmony_ci if (ebitmap_is_empty(typemap)) continue; 15596cd6a6acSopenharmony_ci types = ebitmap_to_str(typemap, pdb->p_type_val_to_name, 1); 15606cd6a6acSopenharmony_ci if (!types) { 15616cd6a6acSopenharmony_ci rc = -1; 15626cd6a6acSopenharmony_ci goto exit; 15636cd6a6acSopenharmony_ci } 15646cd6a6acSopenharmony_ci 15656cd6a6acSopenharmony_ci rc = strs_create_and_add(strs, "(typeattributeset %s (%s))", 15666cd6a6acSopenharmony_ci 2, name, types); 15676cd6a6acSopenharmony_ci free(types); 15686cd6a6acSopenharmony_ci if (rc != 0) { 15696cd6a6acSopenharmony_ci goto exit; 15706cd6a6acSopenharmony_ci } 15716cd6a6acSopenharmony_ci } 15726cd6a6acSopenharmony_ci 15736cd6a6acSopenharmony_ci strs_sort(strs); 15746cd6a6acSopenharmony_ci strs_write_each(strs, out); 15756cd6a6acSopenharmony_ci 15766cd6a6acSopenharmony_ciexit: 15776cd6a6acSopenharmony_ci strs_free_all(strs); 15786cd6a6acSopenharmony_ci strs_destroy(&strs); 15796cd6a6acSopenharmony_ci 15806cd6a6acSopenharmony_ci if (rc != 0) { 15816cd6a6acSopenharmony_ci sepol_log_err("Error writing typeattributeset rules to CIL\n"); 15826cd6a6acSopenharmony_ci } 15836cd6a6acSopenharmony_ci 15846cd6a6acSopenharmony_ci return rc; 15856cd6a6acSopenharmony_ci} 15866cd6a6acSopenharmony_ci 15876cd6a6acSopenharmony_cistatic int write_type_permissive_rules_to_cil(FILE *out, struct policydb *pdb) 15886cd6a6acSopenharmony_ci{ 15896cd6a6acSopenharmony_ci struct strs *strs; 15906cd6a6acSopenharmony_ci char *name; 15916cd6a6acSopenharmony_ci struct ebitmap_node *node; 15926cd6a6acSopenharmony_ci unsigned i, num; 15936cd6a6acSopenharmony_ci int rc = 0; 15946cd6a6acSopenharmony_ci 15956cd6a6acSopenharmony_ci rc = strs_init(&strs, pdb->p_types.nprim); 15966cd6a6acSopenharmony_ci if (rc != 0) { 15976cd6a6acSopenharmony_ci goto exit; 15986cd6a6acSopenharmony_ci } 15996cd6a6acSopenharmony_ci 16006cd6a6acSopenharmony_ci ebitmap_for_each_positive_bit(&pdb->permissive_map, node, i) { 16016cd6a6acSopenharmony_ci rc = strs_add(strs, pdb->p_type_val_to_name[i-1]); 16026cd6a6acSopenharmony_ci if (rc != 0) { 16036cd6a6acSopenharmony_ci goto exit; 16046cd6a6acSopenharmony_ci } 16056cd6a6acSopenharmony_ci } 16066cd6a6acSopenharmony_ci 16076cd6a6acSopenharmony_ci strs_sort(strs); 16086cd6a6acSopenharmony_ci 16096cd6a6acSopenharmony_ci num = strs_num_items(strs); 16106cd6a6acSopenharmony_ci for (i=0; i<num; i++) { 16116cd6a6acSopenharmony_ci name = strs_read_at_index(strs, i); 16126cd6a6acSopenharmony_ci if (!name) { 16136cd6a6acSopenharmony_ci rc = -1; 16146cd6a6acSopenharmony_ci goto exit; 16156cd6a6acSopenharmony_ci } 16166cd6a6acSopenharmony_ci sepol_printf(out, "(typepermissive %s)\n", name); 16176cd6a6acSopenharmony_ci } 16186cd6a6acSopenharmony_ci 16196cd6a6acSopenharmony_ciexit: 16206cd6a6acSopenharmony_ci strs_destroy(&strs); 16216cd6a6acSopenharmony_ci 16226cd6a6acSopenharmony_ci if (rc != 0) { 16236cd6a6acSopenharmony_ci sepol_log_err("Error writing typepermissive rules to CIL\n"); 16246cd6a6acSopenharmony_ci } 16256cd6a6acSopenharmony_ci 16266cd6a6acSopenharmony_ci return rc; 16276cd6a6acSopenharmony_ci} 16286cd6a6acSopenharmony_ci 16296cd6a6acSopenharmony_ci#define next_bit_in_range(i, p) (((i) + 1 < sizeof(p)*8) && xperm_test(((i) + 1), p)) 16306cd6a6acSopenharmony_ci 16316cd6a6acSopenharmony_cistatic char *xperms_to_str(avtab_extended_perms_t *xperms) 16326cd6a6acSopenharmony_ci{ 16336cd6a6acSopenharmony_ci uint16_t value; 16346cd6a6acSopenharmony_ci uint16_t low_bit; 16356cd6a6acSopenharmony_ci uint16_t low_value; 16366cd6a6acSopenharmony_ci unsigned int bit; 16376cd6a6acSopenharmony_ci unsigned int in_range = 0; 16386cd6a6acSopenharmony_ci static char xpermsbuf[2048]; 16396cd6a6acSopenharmony_ci char *p; 16406cd6a6acSopenharmony_ci int len, remaining; 16416cd6a6acSopenharmony_ci 16426cd6a6acSopenharmony_ci p = xpermsbuf; 16436cd6a6acSopenharmony_ci remaining = sizeof(xpermsbuf); 16446cd6a6acSopenharmony_ci 16456cd6a6acSopenharmony_ci if ((xperms->specified != AVTAB_XPERMS_IOCTLFUNCTION) 16466cd6a6acSopenharmony_ci && (xperms->specified != AVTAB_XPERMS_IOCTLDRIVER)) { 16476cd6a6acSopenharmony_ci return NULL; 16486cd6a6acSopenharmony_ci } 16496cd6a6acSopenharmony_ci 16506cd6a6acSopenharmony_ci for (bit = 0; bit < sizeof(xperms->perms)*8; bit++) { 16516cd6a6acSopenharmony_ci len = 0; 16526cd6a6acSopenharmony_ci 16536cd6a6acSopenharmony_ci if (!xperm_test(bit, xperms->perms)) 16546cd6a6acSopenharmony_ci continue; 16556cd6a6acSopenharmony_ci 16566cd6a6acSopenharmony_ci if (in_range && next_bit_in_range(bit, xperms->perms)) { 16576cd6a6acSopenharmony_ci /* continue until high value found */ 16586cd6a6acSopenharmony_ci continue; 16596cd6a6acSopenharmony_ci } else if (next_bit_in_range(bit, xperms->perms)) { 16606cd6a6acSopenharmony_ci /* low value */ 16616cd6a6acSopenharmony_ci low_bit = bit; 16626cd6a6acSopenharmony_ci in_range = 1; 16636cd6a6acSopenharmony_ci continue; 16646cd6a6acSopenharmony_ci } 16656cd6a6acSopenharmony_ci 16666cd6a6acSopenharmony_ci if (xperms->specified & AVTAB_XPERMS_IOCTLFUNCTION) { 16676cd6a6acSopenharmony_ci value = xperms->driver<<8 | bit; 16686cd6a6acSopenharmony_ci if (in_range) { 16696cd6a6acSopenharmony_ci low_value = xperms->driver<<8 | low_bit; 16706cd6a6acSopenharmony_ci len = snprintf(p, remaining, " (range 0x%hx 0x%hx)", low_value, value); 16716cd6a6acSopenharmony_ci in_range = 0; 16726cd6a6acSopenharmony_ci } else { 16736cd6a6acSopenharmony_ci len = snprintf(p, remaining, " 0x%hx", value); 16746cd6a6acSopenharmony_ci } 16756cd6a6acSopenharmony_ci } else if (xperms->specified & AVTAB_XPERMS_IOCTLDRIVER) { 16766cd6a6acSopenharmony_ci value = bit << 8; 16776cd6a6acSopenharmony_ci if (in_range) { 16786cd6a6acSopenharmony_ci low_value = low_bit << 8; 16796cd6a6acSopenharmony_ci len = snprintf(p, remaining, " (range 0x%hx 0x%hx)", low_value, (uint16_t) (value|0xff)); 16806cd6a6acSopenharmony_ci in_range = 0; 16816cd6a6acSopenharmony_ci } else { 16826cd6a6acSopenharmony_ci len = snprintf(p, remaining, " (range 0x%hx 0x%hx)", value, (uint16_t) (value|0xff)); 16836cd6a6acSopenharmony_ci } 16846cd6a6acSopenharmony_ci 16856cd6a6acSopenharmony_ci } 16866cd6a6acSopenharmony_ci if (len < 0 || len >= remaining) { 16876cd6a6acSopenharmony_ci return NULL; 16886cd6a6acSopenharmony_ci } 16896cd6a6acSopenharmony_ci p += len; 16906cd6a6acSopenharmony_ci remaining -= len; 16916cd6a6acSopenharmony_ci } 16926cd6a6acSopenharmony_ci 16936cd6a6acSopenharmony_ci if (remaining < 2) { 16946cd6a6acSopenharmony_ci return NULL; 16956cd6a6acSopenharmony_ci } 16966cd6a6acSopenharmony_ci 16976cd6a6acSopenharmony_ci xpermsbuf[0] = '('; 16986cd6a6acSopenharmony_ci *p++ = ')'; 16996cd6a6acSopenharmony_ci *p = '\0'; 17006cd6a6acSopenharmony_ci 17016cd6a6acSopenharmony_ci return xpermsbuf; 17026cd6a6acSopenharmony_ci} 17036cd6a6acSopenharmony_ci 17046cd6a6acSopenharmony_cistatic char *avtab_node_to_str(struct policydb *pdb, avtab_key_t *key, avtab_datum_t *datum) 17056cd6a6acSopenharmony_ci{ 17066cd6a6acSopenharmony_ci uint32_t data = datum->data; 17076cd6a6acSopenharmony_ci type_datum_t *type; 17086cd6a6acSopenharmony_ci const char *flavor, *tgt; 17096cd6a6acSopenharmony_ci char *src, *class, *perms, *new; 17106cd6a6acSopenharmony_ci char *rule = NULL; 17116cd6a6acSopenharmony_ci 17126cd6a6acSopenharmony_ci switch (0xFFF & key->specified) { 17136cd6a6acSopenharmony_ci case AVTAB_ALLOWED: 17146cd6a6acSopenharmony_ci flavor = "allow"; 17156cd6a6acSopenharmony_ci break; 17166cd6a6acSopenharmony_ci case AVTAB_AUDITALLOW: 17176cd6a6acSopenharmony_ci flavor = "auditallow"; 17186cd6a6acSopenharmony_ci break; 17196cd6a6acSopenharmony_ci case AVTAB_AUDITDENY: 17206cd6a6acSopenharmony_ci flavor = "dontaudit"; 17216cd6a6acSopenharmony_ci data = ~data; 17226cd6a6acSopenharmony_ci break; 17236cd6a6acSopenharmony_ci case AVTAB_XPERMS_ALLOWED: 17246cd6a6acSopenharmony_ci flavor = "allowx"; 17256cd6a6acSopenharmony_ci break; 17266cd6a6acSopenharmony_ci case AVTAB_XPERMS_AUDITALLOW: 17276cd6a6acSopenharmony_ci flavor = "auditallowx"; 17286cd6a6acSopenharmony_ci break; 17296cd6a6acSopenharmony_ci case AVTAB_XPERMS_DONTAUDIT: 17306cd6a6acSopenharmony_ci flavor = "dontauditx"; 17316cd6a6acSopenharmony_ci break; 17326cd6a6acSopenharmony_ci case AVTAB_TRANSITION: 17336cd6a6acSopenharmony_ci flavor = "typetransition"; 17346cd6a6acSopenharmony_ci break; 17356cd6a6acSopenharmony_ci case AVTAB_MEMBER: 17366cd6a6acSopenharmony_ci flavor = "typemember"; 17376cd6a6acSopenharmony_ci break; 17386cd6a6acSopenharmony_ci case AVTAB_CHANGE: 17396cd6a6acSopenharmony_ci flavor = "typechange"; 17406cd6a6acSopenharmony_ci break; 17416cd6a6acSopenharmony_ci default: 17426cd6a6acSopenharmony_ci sepol_log_err("Unknown avtab type: %i", key->specified); 17436cd6a6acSopenharmony_ci goto exit; 17446cd6a6acSopenharmony_ci } 17456cd6a6acSopenharmony_ci 17466cd6a6acSopenharmony_ci src = pdb->p_type_val_to_name[key->source_type - 1]; 17476cd6a6acSopenharmony_ci tgt = pdb->p_type_val_to_name[key->target_type - 1]; 17486cd6a6acSopenharmony_ci if (key->source_type == key->target_type && !(key->specified & AVTAB_TYPE)) { 17496cd6a6acSopenharmony_ci type = pdb->type_val_to_struct[key->source_type - 1]; 17506cd6a6acSopenharmony_ci if (type->flavor != TYPE_ATTRIB) { 17516cd6a6acSopenharmony_ci tgt = "self"; 17526cd6a6acSopenharmony_ci } 17536cd6a6acSopenharmony_ci } 17546cd6a6acSopenharmony_ci class = pdb->p_class_val_to_name[key->target_class - 1]; 17556cd6a6acSopenharmony_ci 17566cd6a6acSopenharmony_ci if (key->specified & AVTAB_AV) { 17576cd6a6acSopenharmony_ci perms = sepol_av_to_string(pdb, key->target_class, data); 17586cd6a6acSopenharmony_ci if (perms == NULL) { 17596cd6a6acSopenharmony_ci sepol_log_err("Failed to generate permission string"); 17606cd6a6acSopenharmony_ci goto exit; 17616cd6a6acSopenharmony_ci } 17626cd6a6acSopenharmony_ci rule = create_str("(%s %s %s (%s (%s)))", 5, 17636cd6a6acSopenharmony_ci flavor, src, tgt, class, perms+1); 17646cd6a6acSopenharmony_ci } else if (key->specified & AVTAB_XPERMS) { 17656cd6a6acSopenharmony_ci perms = xperms_to_str(datum->xperms); 17666cd6a6acSopenharmony_ci if (perms == NULL) { 17676cd6a6acSopenharmony_ci sepol_log_err("Failed to generate extended permission string"); 17686cd6a6acSopenharmony_ci goto exit; 17696cd6a6acSopenharmony_ci } 17706cd6a6acSopenharmony_ci 17716cd6a6acSopenharmony_ci rule = create_str("(%s %s %s (%s %s (%s)))", 6, 17726cd6a6acSopenharmony_ci flavor, src, tgt, "ioctl", class, perms); 17736cd6a6acSopenharmony_ci } else { 17746cd6a6acSopenharmony_ci new = pdb->p_type_val_to_name[data - 1]; 17756cd6a6acSopenharmony_ci 17766cd6a6acSopenharmony_ci rule = create_str("(%s %s %s %s %s)", 5, flavor, src, tgt, class, new); 17776cd6a6acSopenharmony_ci } 17786cd6a6acSopenharmony_ci 17796cd6a6acSopenharmony_ci if (!rule) { 17806cd6a6acSopenharmony_ci goto exit; 17816cd6a6acSopenharmony_ci } 17826cd6a6acSopenharmony_ci 17836cd6a6acSopenharmony_ci return rule; 17846cd6a6acSopenharmony_ci 17856cd6a6acSopenharmony_ciexit: 17866cd6a6acSopenharmony_ci return NULL; 17876cd6a6acSopenharmony_ci} 17886cd6a6acSopenharmony_ci 17896cd6a6acSopenharmony_cistruct map_avtab_args { 17906cd6a6acSopenharmony_ci struct policydb *pdb; 17916cd6a6acSopenharmony_ci uint32_t flavor; 17926cd6a6acSopenharmony_ci struct strs *strs; 17936cd6a6acSopenharmony_ci}; 17946cd6a6acSopenharmony_ci 17956cd6a6acSopenharmony_cistatic int map_avtab_write_helper(avtab_key_t *key, avtab_datum_t *datum, void *args) 17966cd6a6acSopenharmony_ci{ 17976cd6a6acSopenharmony_ci struct map_avtab_args *map_args = args; 17986cd6a6acSopenharmony_ci uint32_t flavor = map_args->flavor; 17996cd6a6acSopenharmony_ci struct policydb *pdb = map_args->pdb; 18006cd6a6acSopenharmony_ci struct strs *strs = map_args->strs; 18016cd6a6acSopenharmony_ci char *rule; 18026cd6a6acSopenharmony_ci int rc = 0; 18036cd6a6acSopenharmony_ci 18046cd6a6acSopenharmony_ci if (key->specified & flavor) { 18056cd6a6acSopenharmony_ci rule = avtab_node_to_str(pdb, key, datum); 18066cd6a6acSopenharmony_ci if (!rule) { 18076cd6a6acSopenharmony_ci rc = -1; 18086cd6a6acSopenharmony_ci goto exit; 18096cd6a6acSopenharmony_ci } 18106cd6a6acSopenharmony_ci rc = strs_add(strs, rule); 18116cd6a6acSopenharmony_ci if (rc != 0) { 18126cd6a6acSopenharmony_ci free(rule); 18136cd6a6acSopenharmony_ci goto exit; 18146cd6a6acSopenharmony_ci } 18156cd6a6acSopenharmony_ci } 18166cd6a6acSopenharmony_ci 18176cd6a6acSopenharmony_ciexit: 18186cd6a6acSopenharmony_ci return rc; 18196cd6a6acSopenharmony_ci} 18206cd6a6acSopenharmony_ci 18216cd6a6acSopenharmony_cistatic int write_avtab_flavor_to_cil(FILE *out, struct policydb *pdb, uint32_t flavor, int indent) 18226cd6a6acSopenharmony_ci{ 18236cd6a6acSopenharmony_ci struct map_avtab_args args; 18246cd6a6acSopenharmony_ci struct strs *strs; 18256cd6a6acSopenharmony_ci int rc = 0; 18266cd6a6acSopenharmony_ci 18276cd6a6acSopenharmony_ci rc = strs_init(&strs, 1000); 18286cd6a6acSopenharmony_ci if (rc != 0) { 18296cd6a6acSopenharmony_ci goto exit; 18306cd6a6acSopenharmony_ci } 18316cd6a6acSopenharmony_ci 18326cd6a6acSopenharmony_ci args.pdb = pdb; 18336cd6a6acSopenharmony_ci args.flavor = flavor; 18346cd6a6acSopenharmony_ci args.strs = strs; 18356cd6a6acSopenharmony_ci 18366cd6a6acSopenharmony_ci rc = avtab_map(&pdb->te_avtab, map_avtab_write_helper, &args); 18376cd6a6acSopenharmony_ci if (rc != 0) { 18386cd6a6acSopenharmony_ci goto exit; 18396cd6a6acSopenharmony_ci } 18406cd6a6acSopenharmony_ci 18416cd6a6acSopenharmony_ci strs_sort(strs); 18426cd6a6acSopenharmony_ci strs_write_each_indented(strs, out, indent); 18436cd6a6acSopenharmony_ci 18446cd6a6acSopenharmony_ciexit: 18456cd6a6acSopenharmony_ci strs_free_all(strs); 18466cd6a6acSopenharmony_ci strs_destroy(&strs); 18476cd6a6acSopenharmony_ci 18486cd6a6acSopenharmony_ci return rc; 18496cd6a6acSopenharmony_ci} 18506cd6a6acSopenharmony_ci 18516cd6a6acSopenharmony_cistatic int write_avtab_to_cil(FILE *out, struct policydb *pdb, int indent) 18526cd6a6acSopenharmony_ci{ 18536cd6a6acSopenharmony_ci unsigned i; 18546cd6a6acSopenharmony_ci int rc = 0; 18556cd6a6acSopenharmony_ci 18566cd6a6acSopenharmony_ci for (i = 0; i < AVTAB_FLAVORS_SZ; i++) { 18576cd6a6acSopenharmony_ci rc = write_avtab_flavor_to_cil(out, pdb, avtab_flavors[i], indent); 18586cd6a6acSopenharmony_ci if (rc != 0) { 18596cd6a6acSopenharmony_ci goto exit; 18606cd6a6acSopenharmony_ci } 18616cd6a6acSopenharmony_ci } 18626cd6a6acSopenharmony_ci 18636cd6a6acSopenharmony_ciexit: 18646cd6a6acSopenharmony_ci if (rc != 0) { 18656cd6a6acSopenharmony_ci sepol_log_err("Error writing avtab rules to CIL\n"); 18666cd6a6acSopenharmony_ci } 18676cd6a6acSopenharmony_ci 18686cd6a6acSopenharmony_ci return rc; 18696cd6a6acSopenharmony_ci} 18706cd6a6acSopenharmony_ci 18716cd6a6acSopenharmony_cistruct map_filename_trans_args { 18726cd6a6acSopenharmony_ci struct policydb *pdb; 18736cd6a6acSopenharmony_ci struct strs *strs; 18746cd6a6acSopenharmony_ci}; 18756cd6a6acSopenharmony_ci 18766cd6a6acSopenharmony_cistatic int map_filename_trans_to_str(hashtab_key_t key, void *data, void *arg) 18776cd6a6acSopenharmony_ci{ 18786cd6a6acSopenharmony_ci filename_trans_key_t *ft = (filename_trans_key_t *)key; 18796cd6a6acSopenharmony_ci filename_trans_datum_t *datum = data; 18806cd6a6acSopenharmony_ci struct map_filename_trans_args *map_args = arg; 18816cd6a6acSopenharmony_ci struct policydb *pdb = map_args->pdb; 18826cd6a6acSopenharmony_ci struct strs *strs = map_args->strs; 18836cd6a6acSopenharmony_ci char *src, *tgt, *class, *filename, *new; 18846cd6a6acSopenharmony_ci struct ebitmap_node *node; 18856cd6a6acSopenharmony_ci uint32_t bit; 18866cd6a6acSopenharmony_ci int rc; 18876cd6a6acSopenharmony_ci 18886cd6a6acSopenharmony_ci tgt = pdb->p_type_val_to_name[ft->ttype - 1]; 18896cd6a6acSopenharmony_ci class = pdb->p_class_val_to_name[ft->tclass - 1]; 18906cd6a6acSopenharmony_ci filename = ft->name; 18916cd6a6acSopenharmony_ci do { 18926cd6a6acSopenharmony_ci new = pdb->p_type_val_to_name[datum->otype - 1]; 18936cd6a6acSopenharmony_ci 18946cd6a6acSopenharmony_ci ebitmap_for_each_positive_bit(&datum->stypes, node, bit) { 18956cd6a6acSopenharmony_ci src = pdb->p_type_val_to_name[bit]; 18966cd6a6acSopenharmony_ci rc = strs_create_and_add(strs, 18976cd6a6acSopenharmony_ci "(typetransition %s %s %s \"%s\" %s)", 18986cd6a6acSopenharmony_ci 5, src, tgt, class, filename, new); 18996cd6a6acSopenharmony_ci if (rc) 19006cd6a6acSopenharmony_ci return rc; 19016cd6a6acSopenharmony_ci } 19026cd6a6acSopenharmony_ci 19036cd6a6acSopenharmony_ci datum = datum->next; 19046cd6a6acSopenharmony_ci } while (datum); 19056cd6a6acSopenharmony_ci 19066cd6a6acSopenharmony_ci return 0; 19076cd6a6acSopenharmony_ci} 19086cd6a6acSopenharmony_ci 19096cd6a6acSopenharmony_cistatic int write_filename_trans_rules_to_cil(FILE *out, struct policydb *pdb) 19106cd6a6acSopenharmony_ci{ 19116cd6a6acSopenharmony_ci struct map_filename_trans_args args; 19126cd6a6acSopenharmony_ci struct strs *strs; 19136cd6a6acSopenharmony_ci int rc = 0; 19146cd6a6acSopenharmony_ci 19156cd6a6acSopenharmony_ci rc = strs_init(&strs, 100); 19166cd6a6acSopenharmony_ci if (rc != 0) { 19176cd6a6acSopenharmony_ci goto exit; 19186cd6a6acSopenharmony_ci } 19196cd6a6acSopenharmony_ci 19206cd6a6acSopenharmony_ci args.pdb = pdb; 19216cd6a6acSopenharmony_ci args.strs = strs; 19226cd6a6acSopenharmony_ci 19236cd6a6acSopenharmony_ci rc = hashtab_map(pdb->filename_trans, map_filename_trans_to_str, &args); 19246cd6a6acSopenharmony_ci if (rc != 0) { 19256cd6a6acSopenharmony_ci goto exit; 19266cd6a6acSopenharmony_ci } 19276cd6a6acSopenharmony_ci 19286cd6a6acSopenharmony_ci strs_sort(strs); 19296cd6a6acSopenharmony_ci strs_write_each(strs, out); 19306cd6a6acSopenharmony_ci 19316cd6a6acSopenharmony_ciexit: 19326cd6a6acSopenharmony_ci strs_free_all(strs); 19336cd6a6acSopenharmony_ci strs_destroy(&strs); 19346cd6a6acSopenharmony_ci 19356cd6a6acSopenharmony_ci if (rc != 0) { 19366cd6a6acSopenharmony_ci sepol_log_err("Error writing filename typetransition rules to CIL\n"); 19376cd6a6acSopenharmony_ci } 19386cd6a6acSopenharmony_ci 19396cd6a6acSopenharmony_ci return rc; 19406cd6a6acSopenharmony_ci} 19416cd6a6acSopenharmony_ci 19426cd6a6acSopenharmony_cistatic char *level_to_str(struct policydb *pdb, struct mls_level *level) 19436cd6a6acSopenharmony_ci{ 19446cd6a6acSopenharmony_ci ebitmap_t *cats = &level->cat; 19456cd6a6acSopenharmony_ci char *level_str = NULL; 19466cd6a6acSopenharmony_ci char *sens_str = pdb->p_sens_val_to_name[level->sens - 1]; 19476cd6a6acSopenharmony_ci char *cats_str; 19486cd6a6acSopenharmony_ci 19496cd6a6acSopenharmony_ci if (!ebitmap_is_empty(cats)) { 19506cd6a6acSopenharmony_ci cats_str = cats_ebitmap_to_str(cats, pdb->p_cat_val_to_name); 19516cd6a6acSopenharmony_ci level_str = create_str("(%s %s)", 2, sens_str, cats_str); 19526cd6a6acSopenharmony_ci free(cats_str); 19536cd6a6acSopenharmony_ci } else { 19546cd6a6acSopenharmony_ci level_str = create_str("(%s)", 1, sens_str); 19556cd6a6acSopenharmony_ci } 19566cd6a6acSopenharmony_ci 19576cd6a6acSopenharmony_ci return level_str; 19586cd6a6acSopenharmony_ci} 19596cd6a6acSopenharmony_ci 19606cd6a6acSopenharmony_cistatic char *range_to_str(struct policydb *pdb, mls_range_t *range) 19616cd6a6acSopenharmony_ci{ 19626cd6a6acSopenharmony_ci char *low = NULL; 19636cd6a6acSopenharmony_ci char *high = NULL; 19646cd6a6acSopenharmony_ci char *range_str = NULL; 19656cd6a6acSopenharmony_ci 19666cd6a6acSopenharmony_ci low = level_to_str(pdb, &range->level[0]); 19676cd6a6acSopenharmony_ci if (!low) { 19686cd6a6acSopenharmony_ci goto exit; 19696cd6a6acSopenharmony_ci } 19706cd6a6acSopenharmony_ci 19716cd6a6acSopenharmony_ci high = level_to_str(pdb, &range->level[1]); 19726cd6a6acSopenharmony_ci if (!high) { 19736cd6a6acSopenharmony_ci goto exit; 19746cd6a6acSopenharmony_ci } 19756cd6a6acSopenharmony_ci 19766cd6a6acSopenharmony_ci range_str = create_str("(%s %s)", 2, low, high); 19776cd6a6acSopenharmony_ci 19786cd6a6acSopenharmony_ciexit: 19796cd6a6acSopenharmony_ci free(low); 19806cd6a6acSopenharmony_ci free(high); 19816cd6a6acSopenharmony_ci 19826cd6a6acSopenharmony_ci return range_str; 19836cd6a6acSopenharmony_ci} 19846cd6a6acSopenharmony_ci 19856cd6a6acSopenharmony_cistruct map_range_trans_args { 19866cd6a6acSopenharmony_ci struct policydb *pdb; 19876cd6a6acSopenharmony_ci struct strs *strs; 19886cd6a6acSopenharmony_ci}; 19896cd6a6acSopenharmony_ci 19906cd6a6acSopenharmony_cistatic int map_range_trans_to_str(hashtab_key_t key, void *data, void *arg) 19916cd6a6acSopenharmony_ci{ 19926cd6a6acSopenharmony_ci range_trans_t *rt = (range_trans_t *)key; 19936cd6a6acSopenharmony_ci mls_range_t *mls_range = data; 19946cd6a6acSopenharmony_ci struct map_range_trans_args *map_args = arg; 19956cd6a6acSopenharmony_ci struct policydb *pdb = map_args->pdb; 19966cd6a6acSopenharmony_ci struct strs *strs = map_args->strs; 19976cd6a6acSopenharmony_ci char *src, *tgt, *class, *range; 19986cd6a6acSopenharmony_ci int rc; 19996cd6a6acSopenharmony_ci 20006cd6a6acSopenharmony_ci src = pdb->p_type_val_to_name[rt->source_type - 1]; 20016cd6a6acSopenharmony_ci tgt = pdb->p_type_val_to_name[rt->target_type - 1]; 20026cd6a6acSopenharmony_ci class = pdb->p_class_val_to_name[rt->target_class - 1]; 20036cd6a6acSopenharmony_ci range = range_to_str(pdb, mls_range); 20046cd6a6acSopenharmony_ci if (!range) { 20056cd6a6acSopenharmony_ci rc = -1; 20066cd6a6acSopenharmony_ci goto exit; 20076cd6a6acSopenharmony_ci } 20086cd6a6acSopenharmony_ci 20096cd6a6acSopenharmony_ci rc = strs_create_and_add(strs, "(rangetransition %s %s %s %s)", 4, 20106cd6a6acSopenharmony_ci src, tgt, class, range); 20116cd6a6acSopenharmony_ci free(range); 20126cd6a6acSopenharmony_ci if (rc != 0) { 20136cd6a6acSopenharmony_ci goto exit; 20146cd6a6acSopenharmony_ci } 20156cd6a6acSopenharmony_ci 20166cd6a6acSopenharmony_ciexit: 20176cd6a6acSopenharmony_ci return rc; 20186cd6a6acSopenharmony_ci} 20196cd6a6acSopenharmony_ci 20206cd6a6acSopenharmony_cistatic int write_range_trans_rules_to_cil(FILE *out, struct policydb *pdb) 20216cd6a6acSopenharmony_ci{ 20226cd6a6acSopenharmony_ci struct map_range_trans_args args; 20236cd6a6acSopenharmony_ci struct strs *strs; 20246cd6a6acSopenharmony_ci int rc = 0; 20256cd6a6acSopenharmony_ci 20266cd6a6acSopenharmony_ci rc = strs_init(&strs, 100); 20276cd6a6acSopenharmony_ci if (rc != 0) { 20286cd6a6acSopenharmony_ci goto exit; 20296cd6a6acSopenharmony_ci } 20306cd6a6acSopenharmony_ci 20316cd6a6acSopenharmony_ci args.pdb = pdb; 20326cd6a6acSopenharmony_ci args.strs = strs; 20336cd6a6acSopenharmony_ci 20346cd6a6acSopenharmony_ci rc = hashtab_map(pdb->range_tr, map_range_trans_to_str, &args); 20356cd6a6acSopenharmony_ci if (rc != 0) { 20366cd6a6acSopenharmony_ci goto exit; 20376cd6a6acSopenharmony_ci } 20386cd6a6acSopenharmony_ci 20396cd6a6acSopenharmony_ci strs_sort(strs); 20406cd6a6acSopenharmony_ci strs_write_each(strs, out); 20416cd6a6acSopenharmony_ci 20426cd6a6acSopenharmony_ciexit: 20436cd6a6acSopenharmony_ci strs_free_all(strs); 20446cd6a6acSopenharmony_ci strs_destroy(&strs); 20456cd6a6acSopenharmony_ci 20466cd6a6acSopenharmony_ci if (rc != 0) { 20476cd6a6acSopenharmony_ci sepol_log_err("Error writing range transition rules to CIL\n"); 20486cd6a6acSopenharmony_ci } 20496cd6a6acSopenharmony_ci 20506cd6a6acSopenharmony_ci return rc; 20516cd6a6acSopenharmony_ci} 20526cd6a6acSopenharmony_ci 20536cd6a6acSopenharmony_cistatic int write_cond_av_list_to_cil(FILE *out, struct policydb *pdb, cond_av_list_t *cond_list, int indent) 20546cd6a6acSopenharmony_ci{ 20556cd6a6acSopenharmony_ci cond_av_list_t *cond_av; 20566cd6a6acSopenharmony_ci avtab_ptr_t node; 20576cd6a6acSopenharmony_ci uint32_t flavor; 20586cd6a6acSopenharmony_ci avtab_key_t *key; 20596cd6a6acSopenharmony_ci avtab_datum_t *datum; 20606cd6a6acSopenharmony_ci struct strs *strs; 20616cd6a6acSopenharmony_ci char *rule; 20626cd6a6acSopenharmony_ci unsigned i; 20636cd6a6acSopenharmony_ci int rc; 20646cd6a6acSopenharmony_ci 20656cd6a6acSopenharmony_ci for (i = 0; i < AVTAB_FLAVORS_SZ; i++) { 20666cd6a6acSopenharmony_ci flavor = avtab_flavors[i]; 20676cd6a6acSopenharmony_ci rc = strs_init(&strs, 64); 20686cd6a6acSopenharmony_ci if (rc != 0) { 20696cd6a6acSopenharmony_ci goto exit; 20706cd6a6acSopenharmony_ci } 20716cd6a6acSopenharmony_ci 20726cd6a6acSopenharmony_ci for (cond_av = cond_list; cond_av != NULL; cond_av = cond_av->next) { 20736cd6a6acSopenharmony_ci node = cond_av->node; 20746cd6a6acSopenharmony_ci key = &node->key; 20756cd6a6acSopenharmony_ci datum = &node->datum; 20766cd6a6acSopenharmony_ci if (key->specified & flavor) { 20776cd6a6acSopenharmony_ci rule = avtab_node_to_str(pdb, key, datum); 20786cd6a6acSopenharmony_ci if (!rule) { 20796cd6a6acSopenharmony_ci rc = -1; 20806cd6a6acSopenharmony_ci goto exit; 20816cd6a6acSopenharmony_ci } 20826cd6a6acSopenharmony_ci rc = strs_add(strs, rule); 20836cd6a6acSopenharmony_ci if (rc != 0) { 20846cd6a6acSopenharmony_ci free(rule); 20856cd6a6acSopenharmony_ci goto exit; 20866cd6a6acSopenharmony_ci } 20876cd6a6acSopenharmony_ci } 20886cd6a6acSopenharmony_ci } 20896cd6a6acSopenharmony_ci 20906cd6a6acSopenharmony_ci strs_sort(strs); 20916cd6a6acSopenharmony_ci strs_write_each_indented(strs, out, indent); 20926cd6a6acSopenharmony_ci strs_free_all(strs); 20936cd6a6acSopenharmony_ci strs_destroy(&strs); 20946cd6a6acSopenharmony_ci } 20956cd6a6acSopenharmony_ci 20966cd6a6acSopenharmony_ci return 0; 20976cd6a6acSopenharmony_ci 20986cd6a6acSopenharmony_ciexit: 20996cd6a6acSopenharmony_ci strs_free_all(strs); 21006cd6a6acSopenharmony_ci strs_destroy(&strs); 21016cd6a6acSopenharmony_ci return rc; 21026cd6a6acSopenharmony_ci} 21036cd6a6acSopenharmony_ci 21046cd6a6acSopenharmony_cistruct cond_data { 21056cd6a6acSopenharmony_ci char *expr; 21066cd6a6acSopenharmony_ci struct cond_node *cond; 21076cd6a6acSopenharmony_ci}; 21086cd6a6acSopenharmony_ci 21096cd6a6acSopenharmony_cistatic int cond_node_cmp(const void *a, const void *b) 21106cd6a6acSopenharmony_ci{ 21116cd6a6acSopenharmony_ci const struct cond_data *aa = a; 21126cd6a6acSopenharmony_ci const struct cond_data *bb = b; 21136cd6a6acSopenharmony_ci return strcmp(aa->expr, bb->expr); 21146cd6a6acSopenharmony_ci} 21156cd6a6acSopenharmony_ci 21166cd6a6acSopenharmony_cistatic int write_cond_nodes_to_cil(FILE *out, struct policydb *pdb) 21176cd6a6acSopenharmony_ci{ 21186cd6a6acSopenharmony_ci struct cond_data *cond_data; 21196cd6a6acSopenharmony_ci char *expr; 21206cd6a6acSopenharmony_ci struct cond_node *cond; 21216cd6a6acSopenharmony_ci unsigned i, num = 0; 21226cd6a6acSopenharmony_ci int rc = 0; 21236cd6a6acSopenharmony_ci 21246cd6a6acSopenharmony_ci for (cond = pdb->cond_list; cond != NULL; cond = cond->next) { 21256cd6a6acSopenharmony_ci num++; 21266cd6a6acSopenharmony_ci } 21276cd6a6acSopenharmony_ci 21286cd6a6acSopenharmony_ci cond_data = calloc(num, sizeof(struct cond_data)); 21296cd6a6acSopenharmony_ci if (!cond_data) { 21306cd6a6acSopenharmony_ci rc = -1; 21316cd6a6acSopenharmony_ci goto exit; 21326cd6a6acSopenharmony_ci } 21336cd6a6acSopenharmony_ci 21346cd6a6acSopenharmony_ci i = 0; 21356cd6a6acSopenharmony_ci for (cond = pdb->cond_list; cond != NULL; cond = cond->next) { 21366cd6a6acSopenharmony_ci cond_data[i].cond = cond; 21376cd6a6acSopenharmony_ci expr = cond_expr_to_str(pdb, cond->expr); 21386cd6a6acSopenharmony_ci if (!expr) { 21396cd6a6acSopenharmony_ci num = i; 21406cd6a6acSopenharmony_ci goto exit; 21416cd6a6acSopenharmony_ci } 21426cd6a6acSopenharmony_ci cond_data[i].expr = expr; 21436cd6a6acSopenharmony_ci i++; 21446cd6a6acSopenharmony_ci } 21456cd6a6acSopenharmony_ci 21466cd6a6acSopenharmony_ci qsort(cond_data, num, sizeof(*cond_data), cond_node_cmp); 21476cd6a6acSopenharmony_ci 21486cd6a6acSopenharmony_ci for (i=0; i<num; i++) { 21496cd6a6acSopenharmony_ci expr = cond_data[i].expr; 21506cd6a6acSopenharmony_ci cond = cond_data[i].cond; 21516cd6a6acSopenharmony_ci 21526cd6a6acSopenharmony_ci sepol_printf(out, "(booleanif %s\n", expr); 21536cd6a6acSopenharmony_ci 21546cd6a6acSopenharmony_ci if (cond->true_list != NULL) { 21556cd6a6acSopenharmony_ci sepol_indent(out, 1); 21566cd6a6acSopenharmony_ci sepol_printf(out, "(true\n"); 21576cd6a6acSopenharmony_ci rc = write_cond_av_list_to_cil(out, pdb, cond->true_list, 2); 21586cd6a6acSopenharmony_ci if (rc != 0) { 21596cd6a6acSopenharmony_ci goto exit; 21606cd6a6acSopenharmony_ci } 21616cd6a6acSopenharmony_ci sepol_indent(out, 1); 21626cd6a6acSopenharmony_ci sepol_printf(out, ")\n"); 21636cd6a6acSopenharmony_ci } 21646cd6a6acSopenharmony_ci 21656cd6a6acSopenharmony_ci if (cond->false_list != NULL) { 21666cd6a6acSopenharmony_ci sepol_indent(out, 1); 21676cd6a6acSopenharmony_ci sepol_printf(out, "(false\n"); 21686cd6a6acSopenharmony_ci rc = write_cond_av_list_to_cil(out, pdb, cond->false_list, 2); 21696cd6a6acSopenharmony_ci if (rc != 0) { 21706cd6a6acSopenharmony_ci goto exit; 21716cd6a6acSopenharmony_ci } 21726cd6a6acSopenharmony_ci sepol_indent(out, 1); 21736cd6a6acSopenharmony_ci sepol_printf(out, ")\n"); 21746cd6a6acSopenharmony_ci } 21756cd6a6acSopenharmony_ci sepol_printf(out, ")\n"); 21766cd6a6acSopenharmony_ci } 21776cd6a6acSopenharmony_ci 21786cd6a6acSopenharmony_ciexit: 21796cd6a6acSopenharmony_ci if (cond_data) { 21806cd6a6acSopenharmony_ci for (i=0; i<num; i++) { 21816cd6a6acSopenharmony_ci free(cond_data[i].expr); 21826cd6a6acSopenharmony_ci } 21836cd6a6acSopenharmony_ci free(cond_data); 21846cd6a6acSopenharmony_ci } 21856cd6a6acSopenharmony_ci 21866cd6a6acSopenharmony_ci if (rc != 0) { 21876cd6a6acSopenharmony_ci sepol_log_err("Error writing conditional rules to CIL\n"); 21886cd6a6acSopenharmony_ci } 21896cd6a6acSopenharmony_ci 21906cd6a6acSopenharmony_ci return rc; 21916cd6a6acSopenharmony_ci} 21926cd6a6acSopenharmony_ci 21936cd6a6acSopenharmony_cistatic int write_role_decl_rules_to_cil(FILE *out, struct policydb *pdb) 21946cd6a6acSopenharmony_ci{ 21956cd6a6acSopenharmony_ci struct role_datum *role; 21966cd6a6acSopenharmony_ci struct strs *strs, *type_strs; 21976cd6a6acSopenharmony_ci char *name, *parent, *child, *type; 21986cd6a6acSopenharmony_ci struct ebitmap *types; 21996cd6a6acSopenharmony_ci struct type_datum *type_datum; 22006cd6a6acSopenharmony_ci unsigned i, num, j, num_types; 22016cd6a6acSopenharmony_ci int rc = 0; 22026cd6a6acSopenharmony_ci 22036cd6a6acSopenharmony_ci rc = strs_init(&strs, pdb->p_roles.nprim); 22046cd6a6acSopenharmony_ci if (rc != 0) { 22056cd6a6acSopenharmony_ci goto exit; 22066cd6a6acSopenharmony_ci } 22076cd6a6acSopenharmony_ci 22086cd6a6acSopenharmony_ci for (i=0; i < pdb->p_roles.nprim; i++) { 22096cd6a6acSopenharmony_ci role = pdb->role_val_to_struct[i]; 22106cd6a6acSopenharmony_ci if (role && role->flavor == ROLE_ROLE) { 22116cd6a6acSopenharmony_ci rc = strs_add(strs, pdb->p_role_val_to_name[i]); 22126cd6a6acSopenharmony_ci if (rc != 0) { 22136cd6a6acSopenharmony_ci goto exit; 22146cd6a6acSopenharmony_ci } 22156cd6a6acSopenharmony_ci } 22166cd6a6acSopenharmony_ci } 22176cd6a6acSopenharmony_ci 22186cd6a6acSopenharmony_ci strs_sort(strs); 22196cd6a6acSopenharmony_ci 22206cd6a6acSopenharmony_ci num = strs_num_items(strs); 22216cd6a6acSopenharmony_ci 22226cd6a6acSopenharmony_ci for (i=0; i<num; i++) { 22236cd6a6acSopenharmony_ci name = strs_read_at_index(strs, i); 22246cd6a6acSopenharmony_ci if (!name) { 22256cd6a6acSopenharmony_ci continue; 22266cd6a6acSopenharmony_ci } 22276cd6a6acSopenharmony_ci sepol_printf(out, "(role %s)\n", name); 22286cd6a6acSopenharmony_ci } 22296cd6a6acSopenharmony_ci 22306cd6a6acSopenharmony_ci for (i=0; i<num; i++) { 22316cd6a6acSopenharmony_ci child = strs_read_at_index(strs, i); 22326cd6a6acSopenharmony_ci if (!child) { 22336cd6a6acSopenharmony_ci continue; 22346cd6a6acSopenharmony_ci } 22356cd6a6acSopenharmony_ci role = hashtab_search(pdb->p_roles.table, child); 22366cd6a6acSopenharmony_ci if (!role) { 22376cd6a6acSopenharmony_ci rc = -1; 22386cd6a6acSopenharmony_ci goto exit; 22396cd6a6acSopenharmony_ci } 22406cd6a6acSopenharmony_ci 22416cd6a6acSopenharmony_ci if (role->bounds > 0) { 22426cd6a6acSopenharmony_ci parent = pdb->p_role_val_to_name[role->bounds - 1]; 22436cd6a6acSopenharmony_ci sepol_printf(out, "(rolebounds %s %s)\n", parent, child); 22446cd6a6acSopenharmony_ci } 22456cd6a6acSopenharmony_ci } 22466cd6a6acSopenharmony_ci 22476cd6a6acSopenharmony_ci for (i=0; i<num; i++) { 22486cd6a6acSopenharmony_ci name = strs_read_at_index(strs, i); 22496cd6a6acSopenharmony_ci if (!name) { 22506cd6a6acSopenharmony_ci continue; 22516cd6a6acSopenharmony_ci } 22526cd6a6acSopenharmony_ci role = hashtab_search(pdb->p_roles.table, name); 22536cd6a6acSopenharmony_ci if (!role) { 22546cd6a6acSopenharmony_ci rc = -1; 22556cd6a6acSopenharmony_ci goto exit; 22566cd6a6acSopenharmony_ci } 22576cd6a6acSopenharmony_ci types = &role->types.types; 22586cd6a6acSopenharmony_ci if (types && !ebitmap_is_empty(types)) { 22596cd6a6acSopenharmony_ci rc = strs_init(&type_strs, pdb->p_types.nprim); 22606cd6a6acSopenharmony_ci if (rc != 0) { 22616cd6a6acSopenharmony_ci goto exit; 22626cd6a6acSopenharmony_ci } 22636cd6a6acSopenharmony_ci rc = ebitmap_to_strs(types, type_strs, pdb->p_type_val_to_name); 22646cd6a6acSopenharmony_ci if (rc != 0) { 22656cd6a6acSopenharmony_ci strs_destroy(&type_strs); 22666cd6a6acSopenharmony_ci goto exit; 22676cd6a6acSopenharmony_ci } 22686cd6a6acSopenharmony_ci strs_sort(type_strs); 22696cd6a6acSopenharmony_ci 22706cd6a6acSopenharmony_ci num_types = strs_num_items(type_strs); 22716cd6a6acSopenharmony_ci for (j=0; j<num_types; j++) { 22726cd6a6acSopenharmony_ci type = strs_read_at_index(type_strs, j); 22736cd6a6acSopenharmony_ci sepol_printf(out, "(roletype %s %s)\n", name, type); 22746cd6a6acSopenharmony_ci } 22756cd6a6acSopenharmony_ci strs_destroy(&type_strs); 22766cd6a6acSopenharmony_ci } 22776cd6a6acSopenharmony_ci } 22786cd6a6acSopenharmony_ci 22796cd6a6acSopenharmony_ci strs_destroy(&strs); 22806cd6a6acSopenharmony_ci 22816cd6a6acSopenharmony_ci rc = strs_init(&strs, pdb->p_types.nprim); 22826cd6a6acSopenharmony_ci if (rc != 0) { 22836cd6a6acSopenharmony_ci goto exit; 22846cd6a6acSopenharmony_ci } 22856cd6a6acSopenharmony_ci 22866cd6a6acSopenharmony_ci for (i=0; i < pdb->p_types.nprim; i++) { 22876cd6a6acSopenharmony_ci type_datum = pdb->type_val_to_struct[i]; 22886cd6a6acSopenharmony_ci if (type_datum && type_datum->flavor == TYPE_TYPE && type_datum->primary) { 22896cd6a6acSopenharmony_ci rc = strs_add(strs, pdb->p_type_val_to_name[i]); 22906cd6a6acSopenharmony_ci if (rc != 0) { 22916cd6a6acSopenharmony_ci goto exit; 22926cd6a6acSopenharmony_ci } 22936cd6a6acSopenharmony_ci } 22946cd6a6acSopenharmony_ci } 22956cd6a6acSopenharmony_ci 22966cd6a6acSopenharmony_ci strs_sort(strs); 22976cd6a6acSopenharmony_ci 22986cd6a6acSopenharmony_ci num = strs_num_items(strs); 22996cd6a6acSopenharmony_ci 23006cd6a6acSopenharmony_ci for (i=0; i<num; i++) { 23016cd6a6acSopenharmony_ci name = strs_read_at_index(strs, i); 23026cd6a6acSopenharmony_ci if (!name) { 23036cd6a6acSopenharmony_ci continue; 23046cd6a6acSopenharmony_ci } 23056cd6a6acSopenharmony_ci sepol_printf(out, "(roletype %s %s)\n", DEFAULT_OBJECT, name); 23066cd6a6acSopenharmony_ci } 23076cd6a6acSopenharmony_ci 23086cd6a6acSopenharmony_ciexit: 23096cd6a6acSopenharmony_ci strs_destroy(&strs); 23106cd6a6acSopenharmony_ci 23116cd6a6acSopenharmony_ci if (rc != 0) { 23126cd6a6acSopenharmony_ci sepol_log_err("Error writing role declarations to CIL\n"); 23136cd6a6acSopenharmony_ci } 23146cd6a6acSopenharmony_ci 23156cd6a6acSopenharmony_ci return rc; 23166cd6a6acSopenharmony_ci} 23176cd6a6acSopenharmony_ci 23186cd6a6acSopenharmony_cistatic int write_role_transition_rules_to_cil(FILE *out, struct policydb *pdb) 23196cd6a6acSopenharmony_ci{ 23206cd6a6acSopenharmony_ci role_trans_t *curr = pdb->role_tr; 23216cd6a6acSopenharmony_ci struct strs *strs; 23226cd6a6acSopenharmony_ci char *role, *type, *class, *new; 23236cd6a6acSopenharmony_ci int rc = 0; 23246cd6a6acSopenharmony_ci 23256cd6a6acSopenharmony_ci rc = strs_init(&strs, 32); 23266cd6a6acSopenharmony_ci if (rc != 0) { 23276cd6a6acSopenharmony_ci goto exit; 23286cd6a6acSopenharmony_ci } 23296cd6a6acSopenharmony_ci 23306cd6a6acSopenharmony_ci while (curr) { 23316cd6a6acSopenharmony_ci role = pdb->p_role_val_to_name[curr->role - 1]; 23326cd6a6acSopenharmony_ci type = pdb->p_type_val_to_name[curr->type - 1]; 23336cd6a6acSopenharmony_ci class = pdb->p_class_val_to_name[curr->tclass - 1]; 23346cd6a6acSopenharmony_ci new = pdb->p_role_val_to_name[curr->new_role - 1]; 23356cd6a6acSopenharmony_ci 23366cd6a6acSopenharmony_ci rc = strs_create_and_add(strs, "(roletransition %s %s %s %s)", 4, 23376cd6a6acSopenharmony_ci role, type, class, new); 23386cd6a6acSopenharmony_ci if (rc != 0) { 23396cd6a6acSopenharmony_ci goto exit; 23406cd6a6acSopenharmony_ci } 23416cd6a6acSopenharmony_ci 23426cd6a6acSopenharmony_ci curr = curr->next; 23436cd6a6acSopenharmony_ci } 23446cd6a6acSopenharmony_ci 23456cd6a6acSopenharmony_ci strs_sort(strs); 23466cd6a6acSopenharmony_ci strs_write_each(strs, out); 23476cd6a6acSopenharmony_ci 23486cd6a6acSopenharmony_ciexit: 23496cd6a6acSopenharmony_ci strs_free_all(strs); 23506cd6a6acSopenharmony_ci strs_destroy(&strs); 23516cd6a6acSopenharmony_ci 23526cd6a6acSopenharmony_ci if (rc != 0) { 23536cd6a6acSopenharmony_ci sepol_log_err("Error writing role transition rules to CIL\n"); 23546cd6a6acSopenharmony_ci } 23556cd6a6acSopenharmony_ci 23566cd6a6acSopenharmony_ci return rc; 23576cd6a6acSopenharmony_ci} 23586cd6a6acSopenharmony_ci 23596cd6a6acSopenharmony_cistatic int write_role_allow_rules_to_cil(FILE *out, struct policydb *pdb) 23606cd6a6acSopenharmony_ci{ 23616cd6a6acSopenharmony_ci role_allow_t *curr = pdb->role_allow; 23626cd6a6acSopenharmony_ci struct strs *strs; 23636cd6a6acSopenharmony_ci char *role, *new; 23646cd6a6acSopenharmony_ci int rc = 0; 23656cd6a6acSopenharmony_ci 23666cd6a6acSopenharmony_ci rc = strs_init(&strs, 32); 23676cd6a6acSopenharmony_ci if (rc != 0) { 23686cd6a6acSopenharmony_ci goto exit; 23696cd6a6acSopenharmony_ci } 23706cd6a6acSopenharmony_ci 23716cd6a6acSopenharmony_ci while (curr) { 23726cd6a6acSopenharmony_ci role = pdb->p_role_val_to_name[curr->role - 1]; 23736cd6a6acSopenharmony_ci new = pdb->p_role_val_to_name[curr->new_role - 1]; 23746cd6a6acSopenharmony_ci 23756cd6a6acSopenharmony_ci rc = strs_create_and_add(strs, "(roleallow %s %s)", 2, role, new); 23766cd6a6acSopenharmony_ci if (rc != 0) { 23776cd6a6acSopenharmony_ci goto exit; 23786cd6a6acSopenharmony_ci } 23796cd6a6acSopenharmony_ci 23806cd6a6acSopenharmony_ci curr = curr->next; 23816cd6a6acSopenharmony_ci } 23826cd6a6acSopenharmony_ci 23836cd6a6acSopenharmony_ci strs_sort(strs); 23846cd6a6acSopenharmony_ci strs_write_each(strs, out); 23856cd6a6acSopenharmony_ci 23866cd6a6acSopenharmony_ciexit: 23876cd6a6acSopenharmony_ci strs_free_all(strs); 23886cd6a6acSopenharmony_ci strs_destroy(&strs); 23896cd6a6acSopenharmony_ci 23906cd6a6acSopenharmony_ci if (rc != 0) { 23916cd6a6acSopenharmony_ci sepol_log_err("Error writing role allow rules to CIL\n"); 23926cd6a6acSopenharmony_ci } 23936cd6a6acSopenharmony_ci 23946cd6a6acSopenharmony_ci return rc; 23956cd6a6acSopenharmony_ci} 23966cd6a6acSopenharmony_ci 23976cd6a6acSopenharmony_cistatic int write_user_decl_rules_to_cil(FILE *out, struct policydb *pdb) 23986cd6a6acSopenharmony_ci{ 23996cd6a6acSopenharmony_ci struct user_datum *user; 24006cd6a6acSopenharmony_ci struct strs *strs, *role_strs; 24016cd6a6acSopenharmony_ci char *name, *role, *level, *range; 24026cd6a6acSopenharmony_ci struct ebitmap *roles; 24036cd6a6acSopenharmony_ci unsigned i, j, num, num_roles; 24046cd6a6acSopenharmony_ci int rc = 0; 24056cd6a6acSopenharmony_ci 24066cd6a6acSopenharmony_ci rc = strs_init(&strs, pdb->p_users.nprim); 24076cd6a6acSopenharmony_ci if (rc != 0) { 24086cd6a6acSopenharmony_ci goto exit; 24096cd6a6acSopenharmony_ci } 24106cd6a6acSopenharmony_ci 24116cd6a6acSopenharmony_ci for (i=0; i < pdb->p_users.nprim; i++) { 24126cd6a6acSopenharmony_ci if (!pdb->p_user_val_to_name[i]) continue; 24136cd6a6acSopenharmony_ci rc = strs_add(strs, pdb->p_user_val_to_name[i]); 24146cd6a6acSopenharmony_ci if (rc != 0) { 24156cd6a6acSopenharmony_ci goto exit; 24166cd6a6acSopenharmony_ci } 24176cd6a6acSopenharmony_ci } 24186cd6a6acSopenharmony_ci 24196cd6a6acSopenharmony_ci strs_sort(strs); 24206cd6a6acSopenharmony_ci 24216cd6a6acSopenharmony_ci num = strs_num_items(strs); 24226cd6a6acSopenharmony_ci 24236cd6a6acSopenharmony_ci for (i=0; i<num; i++) { 24246cd6a6acSopenharmony_ci name = strs_read_at_index(strs, i); 24256cd6a6acSopenharmony_ci if (!name) { 24266cd6a6acSopenharmony_ci continue; 24276cd6a6acSopenharmony_ci } 24286cd6a6acSopenharmony_ci sepol_printf(out, "(user %s)\n", name); 24296cd6a6acSopenharmony_ci } 24306cd6a6acSopenharmony_ci 24316cd6a6acSopenharmony_ci for (i=0; i<num; i++) { 24326cd6a6acSopenharmony_ci name = strs_read_at_index(strs, i); 24336cd6a6acSopenharmony_ci if (!name) { 24346cd6a6acSopenharmony_ci continue; 24356cd6a6acSopenharmony_ci } 24366cd6a6acSopenharmony_ci 24376cd6a6acSopenharmony_ci user = hashtab_search(pdb->p_users.table, name); 24386cd6a6acSopenharmony_ci if (!user) { 24396cd6a6acSopenharmony_ci rc = -1; 24406cd6a6acSopenharmony_ci goto exit; 24416cd6a6acSopenharmony_ci } 24426cd6a6acSopenharmony_ci 24436cd6a6acSopenharmony_ci roles = &user->roles.roles; 24446cd6a6acSopenharmony_ci if (roles && !ebitmap_is_empty(roles)) { 24456cd6a6acSopenharmony_ci rc = strs_init(&role_strs, pdb->p_roles.nprim); 24466cd6a6acSopenharmony_ci if (rc != 0) { 24476cd6a6acSopenharmony_ci goto exit; 24486cd6a6acSopenharmony_ci } 24496cd6a6acSopenharmony_ci rc = ebitmap_to_strs(roles, role_strs, pdb->p_role_val_to_name); 24506cd6a6acSopenharmony_ci if (rc != 0) { 24516cd6a6acSopenharmony_ci strs_destroy(&role_strs); 24526cd6a6acSopenharmony_ci goto exit; 24536cd6a6acSopenharmony_ci } 24546cd6a6acSopenharmony_ci 24556cd6a6acSopenharmony_ci rc = strs_add(role_strs, (char *)DEFAULT_OBJECT); 24566cd6a6acSopenharmony_ci if (rc != 0) { 24576cd6a6acSopenharmony_ci strs_destroy(&role_strs); 24586cd6a6acSopenharmony_ci goto exit; 24596cd6a6acSopenharmony_ci } 24606cd6a6acSopenharmony_ci 24616cd6a6acSopenharmony_ci strs_sort(role_strs); 24626cd6a6acSopenharmony_ci 24636cd6a6acSopenharmony_ci num_roles = strs_num_items(role_strs); 24646cd6a6acSopenharmony_ci for (j=0; j<num_roles; j++) { 24656cd6a6acSopenharmony_ci role = strs_read_at_index(role_strs, j); 24666cd6a6acSopenharmony_ci sepol_printf(out, "(userrole %s %s)\n", name, role); 24676cd6a6acSopenharmony_ci } 24686cd6a6acSopenharmony_ci strs_destroy(&role_strs); 24696cd6a6acSopenharmony_ci } 24706cd6a6acSopenharmony_ci } 24716cd6a6acSopenharmony_ci 24726cd6a6acSopenharmony_ci for (i=0; i<num; i++) { 24736cd6a6acSopenharmony_ci name = strs_read_at_index(strs, i); 24746cd6a6acSopenharmony_ci if (!name) { 24756cd6a6acSopenharmony_ci continue; 24766cd6a6acSopenharmony_ci } 24776cd6a6acSopenharmony_ci 24786cd6a6acSopenharmony_ci user = hashtab_search(pdb->p_users.table, name); 24796cd6a6acSopenharmony_ci if (!user) { 24806cd6a6acSopenharmony_ci rc = -1; 24816cd6a6acSopenharmony_ci goto exit; 24826cd6a6acSopenharmony_ci } 24836cd6a6acSopenharmony_ci 24846cd6a6acSopenharmony_ci sepol_printf(out, "(userlevel %s ", name); 24856cd6a6acSopenharmony_ci 24866cd6a6acSopenharmony_ci if (pdb->mls) { 24876cd6a6acSopenharmony_ci level = level_to_str(pdb, &user->exp_dfltlevel); 24886cd6a6acSopenharmony_ci if (!level) { 24896cd6a6acSopenharmony_ci rc = -1; 24906cd6a6acSopenharmony_ci goto exit; 24916cd6a6acSopenharmony_ci } 24926cd6a6acSopenharmony_ci sepol_printf(out, "%s", level); 24936cd6a6acSopenharmony_ci free(level); 24946cd6a6acSopenharmony_ci } else { 24956cd6a6acSopenharmony_ci sepol_printf(out, "%s", DEFAULT_LEVEL); 24966cd6a6acSopenharmony_ci } 24976cd6a6acSopenharmony_ci sepol_printf(out, ")\n"); 24986cd6a6acSopenharmony_ci } 24996cd6a6acSopenharmony_ci 25006cd6a6acSopenharmony_ci for (i=0; i<num; i++) { 25016cd6a6acSopenharmony_ci name = strs_read_at_index(strs, i); 25026cd6a6acSopenharmony_ci if (!name) { 25036cd6a6acSopenharmony_ci continue; 25046cd6a6acSopenharmony_ci } 25056cd6a6acSopenharmony_ci 25066cd6a6acSopenharmony_ci user = hashtab_search(pdb->p_users.table, name); 25076cd6a6acSopenharmony_ci if (!user) { 25086cd6a6acSopenharmony_ci rc = -1; 25096cd6a6acSopenharmony_ci goto exit; 25106cd6a6acSopenharmony_ci } 25116cd6a6acSopenharmony_ci 25126cd6a6acSopenharmony_ci sepol_printf(out, "(userrange %s ", name); 25136cd6a6acSopenharmony_ci if (pdb->mls) { 25146cd6a6acSopenharmony_ci range = range_to_str(pdb, &user->exp_range); 25156cd6a6acSopenharmony_ci if (!range) { 25166cd6a6acSopenharmony_ci rc = -1; 25176cd6a6acSopenharmony_ci goto exit; 25186cd6a6acSopenharmony_ci } 25196cd6a6acSopenharmony_ci sepol_printf(out, "%s", range); 25206cd6a6acSopenharmony_ci free(range); 25216cd6a6acSopenharmony_ci } else { 25226cd6a6acSopenharmony_ci sepol_printf(out, "(%s %s)", DEFAULT_LEVEL, DEFAULT_LEVEL); 25236cd6a6acSopenharmony_ci } 25246cd6a6acSopenharmony_ci sepol_printf(out, ")\n"); 25256cd6a6acSopenharmony_ci } 25266cd6a6acSopenharmony_ci 25276cd6a6acSopenharmony_ciexit: 25286cd6a6acSopenharmony_ci if (strs) 25296cd6a6acSopenharmony_ci strs_destroy(&strs); 25306cd6a6acSopenharmony_ci 25316cd6a6acSopenharmony_ci if (rc != 0) { 25326cd6a6acSopenharmony_ci sepol_log_err("Error writing user declarations to CIL\n"); 25336cd6a6acSopenharmony_ci } 25346cd6a6acSopenharmony_ci 25356cd6a6acSopenharmony_ci return rc; 25366cd6a6acSopenharmony_ci} 25376cd6a6acSopenharmony_ci 25386cd6a6acSopenharmony_cistatic char *context_to_str(struct policydb *pdb, struct context_struct *con) 25396cd6a6acSopenharmony_ci{ 25406cd6a6acSopenharmony_ci char *user, *role, *type, *range; 25416cd6a6acSopenharmony_ci char *ctx = NULL; 25426cd6a6acSopenharmony_ci 25436cd6a6acSopenharmony_ci user = pdb->p_user_val_to_name[con->user - 1]; 25446cd6a6acSopenharmony_ci role = pdb->p_role_val_to_name[con->role - 1]; 25456cd6a6acSopenharmony_ci type = pdb->p_type_val_to_name[con->type - 1]; 25466cd6a6acSopenharmony_ci 25476cd6a6acSopenharmony_ci if (pdb->mls) { 25486cd6a6acSopenharmony_ci range = range_to_str(pdb, &con->range); 25496cd6a6acSopenharmony_ci } else { 25506cd6a6acSopenharmony_ci range = create_str("(%s %s)", 2, DEFAULT_LEVEL, DEFAULT_LEVEL); 25516cd6a6acSopenharmony_ci } 25526cd6a6acSopenharmony_ci if (!range) { 25536cd6a6acSopenharmony_ci goto exit; 25546cd6a6acSopenharmony_ci } 25556cd6a6acSopenharmony_ci 25566cd6a6acSopenharmony_ci ctx = create_str("(%s %s %s %s)", 4, user, role, type, range); 25576cd6a6acSopenharmony_ci free(range); 25586cd6a6acSopenharmony_ci 25596cd6a6acSopenharmony_ciexit: 25606cd6a6acSopenharmony_ci return ctx; 25616cd6a6acSopenharmony_ci} 25626cd6a6acSopenharmony_ci 25636cd6a6acSopenharmony_cistatic int write_sid_context_rules_to_cil(FILE *out, struct policydb *pdb, const char *const *sid_to_str, unsigned num_sids) 25646cd6a6acSopenharmony_ci{ 25656cd6a6acSopenharmony_ci struct ocontext *isid; 25666cd6a6acSopenharmony_ci struct strs *strs; 25676cd6a6acSopenharmony_ci char *sid; 25686cd6a6acSopenharmony_ci char unknown[18]; 25696cd6a6acSopenharmony_ci char *ctx, *rule; 25706cd6a6acSopenharmony_ci unsigned i; 25716cd6a6acSopenharmony_ci int rc = -1; 25726cd6a6acSopenharmony_ci 25736cd6a6acSopenharmony_ci rc = strs_init(&strs, 32); 25746cd6a6acSopenharmony_ci if (rc != 0) { 25756cd6a6acSopenharmony_ci goto exit; 25766cd6a6acSopenharmony_ci } 25776cd6a6acSopenharmony_ci 25786cd6a6acSopenharmony_ci for (isid = pdb->ocontexts[0]; isid != NULL; isid = isid->next) { 25796cd6a6acSopenharmony_ci i = isid->sid[0]; 25806cd6a6acSopenharmony_ci if (i < num_sids) { 25816cd6a6acSopenharmony_ci sid = (char *)sid_to_str[i]; 25826cd6a6acSopenharmony_ci } else { 25836cd6a6acSopenharmony_ci snprintf(unknown, 18, "%s%u", "UNKNOWN", i); 25846cd6a6acSopenharmony_ci sid = unknown; 25856cd6a6acSopenharmony_ci } 25866cd6a6acSopenharmony_ci 25876cd6a6acSopenharmony_ci ctx = context_to_str(pdb, &isid->context[0]); 25886cd6a6acSopenharmony_ci if (!ctx) { 25896cd6a6acSopenharmony_ci rc = -1; 25906cd6a6acSopenharmony_ci goto exit; 25916cd6a6acSopenharmony_ci } 25926cd6a6acSopenharmony_ci 25936cd6a6acSopenharmony_ci rule = create_str("(sidcontext %s %s)", 2, sid, ctx); 25946cd6a6acSopenharmony_ci free(ctx); 25956cd6a6acSopenharmony_ci if (!rule) { 25966cd6a6acSopenharmony_ci rc = -1; 25976cd6a6acSopenharmony_ci goto exit; 25986cd6a6acSopenharmony_ci } 25996cd6a6acSopenharmony_ci 26006cd6a6acSopenharmony_ci rc = strs_add_at_index(strs, rule, i); 26016cd6a6acSopenharmony_ci if (rc != 0) { 26026cd6a6acSopenharmony_ci free(rule); 26036cd6a6acSopenharmony_ci goto exit; 26046cd6a6acSopenharmony_ci } 26056cd6a6acSopenharmony_ci } 26066cd6a6acSopenharmony_ci 26076cd6a6acSopenharmony_ci strs_write_each(strs, out); 26086cd6a6acSopenharmony_ci 26096cd6a6acSopenharmony_ciexit: 26106cd6a6acSopenharmony_ci strs_free_all(strs); 26116cd6a6acSopenharmony_ci strs_destroy(&strs); 26126cd6a6acSopenharmony_ci 26136cd6a6acSopenharmony_ci if (rc != 0) { 26146cd6a6acSopenharmony_ci sepol_log_err("Error writing sidcontext rules to CIL\n"); 26156cd6a6acSopenharmony_ci } 26166cd6a6acSopenharmony_ci 26176cd6a6acSopenharmony_ci return rc; 26186cd6a6acSopenharmony_ci} 26196cd6a6acSopenharmony_ci 26206cd6a6acSopenharmony_cistatic int write_selinux_isid_rules_to_cil(FILE *out, struct policydb *pdb) 26216cd6a6acSopenharmony_ci{ 26226cd6a6acSopenharmony_ci return write_sid_context_rules_to_cil(out, pdb, selinux_sid_to_str, 26236cd6a6acSopenharmony_ci SELINUX_SID_SZ); 26246cd6a6acSopenharmony_ci} 26256cd6a6acSopenharmony_ci 26266cd6a6acSopenharmony_cistatic int write_selinux_fsuse_rules_to_cil(FILE *out, struct policydb *pdb) 26276cd6a6acSopenharmony_ci{ 26286cd6a6acSopenharmony_ci struct ocontext *fsuse; 26296cd6a6acSopenharmony_ci const char *behavior; 26306cd6a6acSopenharmony_ci char *name, *ctx; 26316cd6a6acSopenharmony_ci int rc = 0; 26326cd6a6acSopenharmony_ci 26336cd6a6acSopenharmony_ci for (fsuse = pdb->ocontexts[5]; fsuse != NULL; fsuse = fsuse->next) { 26346cd6a6acSopenharmony_ci switch (fsuse->v.behavior) { 26356cd6a6acSopenharmony_ci case SECURITY_FS_USE_XATTR: behavior = "xattr"; break; 26366cd6a6acSopenharmony_ci case SECURITY_FS_USE_TRANS: behavior = "trans"; break; 26376cd6a6acSopenharmony_ci case SECURITY_FS_USE_TASK: behavior = "task"; break; 26386cd6a6acSopenharmony_ci default: 26396cd6a6acSopenharmony_ci sepol_log_err("Unknown fsuse behavior: %i", fsuse->v.behavior); 26406cd6a6acSopenharmony_ci rc = -1; 26416cd6a6acSopenharmony_ci goto exit; 26426cd6a6acSopenharmony_ci } 26436cd6a6acSopenharmony_ci 26446cd6a6acSopenharmony_ci name = fsuse->u.name; 26456cd6a6acSopenharmony_ci ctx = context_to_str(pdb, &fsuse->context[0]); 26466cd6a6acSopenharmony_ci if (!ctx) { 26476cd6a6acSopenharmony_ci rc = -1; 26486cd6a6acSopenharmony_ci goto exit; 26496cd6a6acSopenharmony_ci } 26506cd6a6acSopenharmony_ci 26516cd6a6acSopenharmony_ci sepol_printf(out, "(fsuse %s %s %s)\n", behavior, name, ctx); 26526cd6a6acSopenharmony_ci 26536cd6a6acSopenharmony_ci free(ctx); 26546cd6a6acSopenharmony_ci } 26556cd6a6acSopenharmony_ci 26566cd6a6acSopenharmony_ciexit: 26576cd6a6acSopenharmony_ci if (rc != 0) { 26586cd6a6acSopenharmony_ci sepol_log_err("Error writing fsuse rules to CIL\n"); 26596cd6a6acSopenharmony_ci } 26606cd6a6acSopenharmony_ci 26616cd6a6acSopenharmony_ci return rc; 26626cd6a6acSopenharmony_ci} 26636cd6a6acSopenharmony_ci 26646cd6a6acSopenharmony_cistatic int write_genfscon_rules_to_cil(FILE *out, struct policydb *pdb) 26656cd6a6acSopenharmony_ci{ 26666cd6a6acSopenharmony_ci struct genfs *genfs; 26676cd6a6acSopenharmony_ci struct ocontext *ocon; 26686cd6a6acSopenharmony_ci struct strs *strs; 26696cd6a6acSopenharmony_ci char *fstype, *name, *ctx; 26706cd6a6acSopenharmony_ci uint32_t sclass; 26716cd6a6acSopenharmony_ci const char *file_type; 26726cd6a6acSopenharmony_ci int rc; 26736cd6a6acSopenharmony_ci 26746cd6a6acSopenharmony_ci rc = strs_init(&strs, 32); 26756cd6a6acSopenharmony_ci if (rc != 0) { 26766cd6a6acSopenharmony_ci goto exit; 26776cd6a6acSopenharmony_ci } 26786cd6a6acSopenharmony_ci 26796cd6a6acSopenharmony_ci for (genfs = pdb->genfs; genfs != NULL; genfs = genfs->next) { 26806cd6a6acSopenharmony_ci for (ocon = genfs->head; ocon != NULL; ocon = ocon->next) { 26816cd6a6acSopenharmony_ci fstype = genfs->fstype; 26826cd6a6acSopenharmony_ci name = ocon->u.name; 26836cd6a6acSopenharmony_ci 26846cd6a6acSopenharmony_ci sclass = ocon->v.sclass; 26856cd6a6acSopenharmony_ci file_type = NULL; 26866cd6a6acSopenharmony_ci if (sclass) { 26876cd6a6acSopenharmony_ci const char *class_name = pdb->p_class_val_to_name[sclass-1]; 26886cd6a6acSopenharmony_ci if (strcmp(class_name, "file") == 0) { 26896cd6a6acSopenharmony_ci file_type = "file"; 26906cd6a6acSopenharmony_ci } else if (strcmp(class_name, "dir") == 0) { 26916cd6a6acSopenharmony_ci file_type = "dir"; 26926cd6a6acSopenharmony_ci } else if (strcmp(class_name, "chr_file") == 0) { 26936cd6a6acSopenharmony_ci file_type = "char"; 26946cd6a6acSopenharmony_ci } else if (strcmp(class_name, "blk_file") == 0) { 26956cd6a6acSopenharmony_ci file_type = "block"; 26966cd6a6acSopenharmony_ci } else if (strcmp(class_name, "sock_file") == 0) { 26976cd6a6acSopenharmony_ci file_type = "socket"; 26986cd6a6acSopenharmony_ci } else if (strcmp(class_name, "fifo_file") == 0) { 26996cd6a6acSopenharmony_ci file_type = "pipe"; 27006cd6a6acSopenharmony_ci } else if (strcmp(class_name, "lnk_file") == 0) { 27016cd6a6acSopenharmony_ci file_type = "symlink"; 27026cd6a6acSopenharmony_ci } else { 27036cd6a6acSopenharmony_ci rc = -1; 27046cd6a6acSopenharmony_ci goto exit; 27056cd6a6acSopenharmony_ci } 27066cd6a6acSopenharmony_ci } 27076cd6a6acSopenharmony_ci 27086cd6a6acSopenharmony_ci ctx = context_to_str(pdb, &ocon->context[0]); 27096cd6a6acSopenharmony_ci if (!ctx) { 27106cd6a6acSopenharmony_ci rc = -1; 27116cd6a6acSopenharmony_ci goto exit; 27126cd6a6acSopenharmony_ci } 27136cd6a6acSopenharmony_ci 27146cd6a6acSopenharmony_ci if (file_type) { 27156cd6a6acSopenharmony_ci rc = strs_create_and_add(strs, "(genfscon %s \"%s\" %s %s)", 4, 27166cd6a6acSopenharmony_ci fstype, name, file_type, ctx); 27176cd6a6acSopenharmony_ci } else { 27186cd6a6acSopenharmony_ci rc = strs_create_and_add(strs, "(genfscon %s \"%s\" %s)", 3, 27196cd6a6acSopenharmony_ci fstype, name, ctx); 27206cd6a6acSopenharmony_ci } 27216cd6a6acSopenharmony_ci free(ctx); 27226cd6a6acSopenharmony_ci if (rc != 0) { 27236cd6a6acSopenharmony_ci goto exit; 27246cd6a6acSopenharmony_ci } 27256cd6a6acSopenharmony_ci } 27266cd6a6acSopenharmony_ci } 27276cd6a6acSopenharmony_ci 27286cd6a6acSopenharmony_ci strs_sort(strs); 27296cd6a6acSopenharmony_ci strs_write_each(strs, out); 27306cd6a6acSopenharmony_ci 27316cd6a6acSopenharmony_ciexit: 27326cd6a6acSopenharmony_ci strs_free_all(strs); 27336cd6a6acSopenharmony_ci strs_destroy(&strs); 27346cd6a6acSopenharmony_ci 27356cd6a6acSopenharmony_ci if (rc != 0) { 27366cd6a6acSopenharmony_ci sepol_log_err("Error writing genfscon rules to CIL\n"); 27376cd6a6acSopenharmony_ci } 27386cd6a6acSopenharmony_ci 27396cd6a6acSopenharmony_ci return rc; 27406cd6a6acSopenharmony_ci} 27416cd6a6acSopenharmony_ci 27426cd6a6acSopenharmony_cistatic int write_selinux_port_rules_to_cil(FILE *out, struct policydb *pdb) 27436cd6a6acSopenharmony_ci{ 27446cd6a6acSopenharmony_ci struct ocontext *portcon; 27456cd6a6acSopenharmony_ci const char *protocol; 27466cd6a6acSopenharmony_ci uint16_t low; 27476cd6a6acSopenharmony_ci uint16_t high; 27486cd6a6acSopenharmony_ci char low_high_str[44]; /* 2^64 <= 20 digits so "(low high)" <= 44 chars */ 27496cd6a6acSopenharmony_ci char *ctx; 27506cd6a6acSopenharmony_ci int rc = 0; 27516cd6a6acSopenharmony_ci 27526cd6a6acSopenharmony_ci for (portcon = pdb->ocontexts[2]; portcon != NULL; portcon = portcon->next) { 27536cd6a6acSopenharmony_ci switch (portcon->u.port.protocol) { 27546cd6a6acSopenharmony_ci case IPPROTO_TCP: protocol = "tcp"; break; 27556cd6a6acSopenharmony_ci case IPPROTO_UDP: protocol = "udp"; break; 27566cd6a6acSopenharmony_ci case IPPROTO_DCCP: protocol = "dccp"; break; 27576cd6a6acSopenharmony_ci case IPPROTO_SCTP: protocol = "sctp"; break; 27586cd6a6acSopenharmony_ci default: 27596cd6a6acSopenharmony_ci sepol_log_err("Unknown portcon protocol: %i", portcon->u.port.protocol); 27606cd6a6acSopenharmony_ci rc = -1; 27616cd6a6acSopenharmony_ci goto exit; 27626cd6a6acSopenharmony_ci } 27636cd6a6acSopenharmony_ci 27646cd6a6acSopenharmony_ci low = portcon->u.port.low_port; 27656cd6a6acSopenharmony_ci high = portcon->u.port.high_port; 27666cd6a6acSopenharmony_ci if (low == high) { 27676cd6a6acSopenharmony_ci rc = snprintf(low_high_str, 44, "%u", low); 27686cd6a6acSopenharmony_ci } else { 27696cd6a6acSopenharmony_ci rc = snprintf(low_high_str, 44, "(%u %u)", low, high); 27706cd6a6acSopenharmony_ci } 27716cd6a6acSopenharmony_ci if (rc < 0 || rc >= 44) { 27726cd6a6acSopenharmony_ci rc = -1; 27736cd6a6acSopenharmony_ci goto exit; 27746cd6a6acSopenharmony_ci } 27756cd6a6acSopenharmony_ci 27766cd6a6acSopenharmony_ci ctx = context_to_str(pdb, &portcon->context[0]); 27776cd6a6acSopenharmony_ci if (!ctx) { 27786cd6a6acSopenharmony_ci rc = -1; 27796cd6a6acSopenharmony_ci goto exit; 27806cd6a6acSopenharmony_ci } 27816cd6a6acSopenharmony_ci 27826cd6a6acSopenharmony_ci sepol_printf(out, "(portcon %s %s %s)\n", protocol, low_high_str, ctx); 27836cd6a6acSopenharmony_ci 27846cd6a6acSopenharmony_ci free(ctx); 27856cd6a6acSopenharmony_ci } 27866cd6a6acSopenharmony_ci 27876cd6a6acSopenharmony_ci rc = 0; 27886cd6a6acSopenharmony_ci 27896cd6a6acSopenharmony_ciexit: 27906cd6a6acSopenharmony_ci if (rc != 0) { 27916cd6a6acSopenharmony_ci sepol_log_err("Error writing portcon rules to CIL\n"); 27926cd6a6acSopenharmony_ci } 27936cd6a6acSopenharmony_ci 27946cd6a6acSopenharmony_ci return rc; 27956cd6a6acSopenharmony_ci} 27966cd6a6acSopenharmony_ci 27976cd6a6acSopenharmony_cistatic int write_selinux_netif_rules_to_cil(FILE *out, struct policydb *pdb) 27986cd6a6acSopenharmony_ci{ 27996cd6a6acSopenharmony_ci struct ocontext *netif; 28006cd6a6acSopenharmony_ci char *name, *ctx1, *ctx2; 28016cd6a6acSopenharmony_ci int rc = 0; 28026cd6a6acSopenharmony_ci 28036cd6a6acSopenharmony_ci for (netif = pdb->ocontexts[3]; netif != NULL; netif = netif->next) { 28046cd6a6acSopenharmony_ci name = netif->u.name; 28056cd6a6acSopenharmony_ci ctx1 = context_to_str(pdb, &netif->context[0]); 28066cd6a6acSopenharmony_ci if (!ctx1) { 28076cd6a6acSopenharmony_ci rc = -1; 28086cd6a6acSopenharmony_ci goto exit; 28096cd6a6acSopenharmony_ci } 28106cd6a6acSopenharmony_ci ctx2 = context_to_str(pdb, &netif->context[1]); 28116cd6a6acSopenharmony_ci if (!ctx2) { 28126cd6a6acSopenharmony_ci free(ctx1); 28136cd6a6acSopenharmony_ci rc = -1; 28146cd6a6acSopenharmony_ci goto exit; 28156cd6a6acSopenharmony_ci } 28166cd6a6acSopenharmony_ci 28176cd6a6acSopenharmony_ci sepol_printf(out, "(netifcon %s %s %s)\n", name, ctx1, ctx2); 28186cd6a6acSopenharmony_ci 28196cd6a6acSopenharmony_ci free(ctx1); 28206cd6a6acSopenharmony_ci free(ctx2); 28216cd6a6acSopenharmony_ci } 28226cd6a6acSopenharmony_ci 28236cd6a6acSopenharmony_ciexit: 28246cd6a6acSopenharmony_ci if (rc != 0) { 28256cd6a6acSopenharmony_ci sepol_log_err("Error writing netifcon rules to CIL\n"); 28266cd6a6acSopenharmony_ci } 28276cd6a6acSopenharmony_ci 28286cd6a6acSopenharmony_ci return rc; 28296cd6a6acSopenharmony_ci} 28306cd6a6acSopenharmony_ci 28316cd6a6acSopenharmony_cistatic int write_selinux_node_rules_to_cil(FILE *out, struct policydb *pdb) 28326cd6a6acSopenharmony_ci{ 28336cd6a6acSopenharmony_ci struct ocontext *node; 28346cd6a6acSopenharmony_ci char addr[INET_ADDRSTRLEN]; 28356cd6a6acSopenharmony_ci char mask[INET_ADDRSTRLEN]; 28366cd6a6acSopenharmony_ci char *ctx; 28376cd6a6acSopenharmony_ci int rc = 0; 28386cd6a6acSopenharmony_ci 28396cd6a6acSopenharmony_ci for (node = pdb->ocontexts[4]; node != NULL; node = node->next) { 28406cd6a6acSopenharmony_ci if (inet_ntop(AF_INET, &node->u.node.addr, addr, INET_ADDRSTRLEN) == NULL) { 28416cd6a6acSopenharmony_ci sepol_log_err("Nodecon address is invalid: %m"); 28426cd6a6acSopenharmony_ci rc = -1; 28436cd6a6acSopenharmony_ci goto exit; 28446cd6a6acSopenharmony_ci } 28456cd6a6acSopenharmony_ci 28466cd6a6acSopenharmony_ci if (inet_ntop(AF_INET, &node->u.node.mask, mask, INET_ADDRSTRLEN) == NULL) { 28476cd6a6acSopenharmony_ci sepol_log_err("Nodecon mask is invalid: %m"); 28486cd6a6acSopenharmony_ci rc = -1; 28496cd6a6acSopenharmony_ci goto exit; 28506cd6a6acSopenharmony_ci } 28516cd6a6acSopenharmony_ci 28526cd6a6acSopenharmony_ci ctx = context_to_str(pdb, &node->context[0]); 28536cd6a6acSopenharmony_ci if (!ctx) { 28546cd6a6acSopenharmony_ci rc = -1; 28556cd6a6acSopenharmony_ci goto exit; 28566cd6a6acSopenharmony_ci } 28576cd6a6acSopenharmony_ci 28586cd6a6acSopenharmony_ci sepol_printf(out, "(nodecon (%s) (%s) %s)\n", addr, mask, ctx); 28596cd6a6acSopenharmony_ci 28606cd6a6acSopenharmony_ci free(ctx); 28616cd6a6acSopenharmony_ci } 28626cd6a6acSopenharmony_ci 28636cd6a6acSopenharmony_ciexit: 28646cd6a6acSopenharmony_ci if (rc != 0) { 28656cd6a6acSopenharmony_ci sepol_log_err("Error writing nodecon rules to CIL\n"); 28666cd6a6acSopenharmony_ci } 28676cd6a6acSopenharmony_ci 28686cd6a6acSopenharmony_ci return rc; 28696cd6a6acSopenharmony_ci} 28706cd6a6acSopenharmony_ci 28716cd6a6acSopenharmony_cistatic int write_selinux_node6_rules_to_cil(FILE *out, struct policydb *pdb) 28726cd6a6acSopenharmony_ci{ 28736cd6a6acSopenharmony_ci struct ocontext *node; 28746cd6a6acSopenharmony_ci char addr[INET6_ADDRSTRLEN]; 28756cd6a6acSopenharmony_ci char mask[INET6_ADDRSTRLEN]; 28766cd6a6acSopenharmony_ci char *ctx; 28776cd6a6acSopenharmony_ci int rc = 0; 28786cd6a6acSopenharmony_ci 28796cd6a6acSopenharmony_ci for (node = pdb->ocontexts[6]; node != NULL; node = node->next) { 28806cd6a6acSopenharmony_ci if (inet_ntop(AF_INET6, &node->u.node6.addr, addr, INET6_ADDRSTRLEN) == NULL) { 28816cd6a6acSopenharmony_ci sepol_log_err("Nodecon address is invalid: %m"); 28826cd6a6acSopenharmony_ci rc = -1; 28836cd6a6acSopenharmony_ci goto exit; 28846cd6a6acSopenharmony_ci } 28856cd6a6acSopenharmony_ci 28866cd6a6acSopenharmony_ci if (inet_ntop(AF_INET6, &node->u.node6.mask, mask, INET6_ADDRSTRLEN) == NULL) { 28876cd6a6acSopenharmony_ci sepol_log_err("Nodecon mask is invalid: %m"); 28886cd6a6acSopenharmony_ci rc = -1; 28896cd6a6acSopenharmony_ci goto exit; 28906cd6a6acSopenharmony_ci } 28916cd6a6acSopenharmony_ci 28926cd6a6acSopenharmony_ci ctx = context_to_str(pdb, &node->context[0]); 28936cd6a6acSopenharmony_ci if (!ctx) { 28946cd6a6acSopenharmony_ci rc = -1; 28956cd6a6acSopenharmony_ci goto exit; 28966cd6a6acSopenharmony_ci } 28976cd6a6acSopenharmony_ci 28986cd6a6acSopenharmony_ci sepol_printf(out, "(nodecon (%s) (%s) %s)\n", addr, mask, ctx); 28996cd6a6acSopenharmony_ci 29006cd6a6acSopenharmony_ci free(ctx); 29016cd6a6acSopenharmony_ci } 29026cd6a6acSopenharmony_ci 29036cd6a6acSopenharmony_ciexit: 29046cd6a6acSopenharmony_ci if (rc != 0) { 29056cd6a6acSopenharmony_ci sepol_log_err("Error writing nodecon rules to CIL\n"); 29066cd6a6acSopenharmony_ci } 29076cd6a6acSopenharmony_ci 29086cd6a6acSopenharmony_ci return rc; 29096cd6a6acSopenharmony_ci} 29106cd6a6acSopenharmony_ci 29116cd6a6acSopenharmony_cistatic int write_selinux_ibpkey_rules_to_cil(FILE *out, struct policydb *pdb) 29126cd6a6acSopenharmony_ci{ 29136cd6a6acSopenharmony_ci struct ocontext *ibpkeycon; 29146cd6a6acSopenharmony_ci char subnet_prefix_str[INET6_ADDRSTRLEN]; 29156cd6a6acSopenharmony_ci struct in6_addr subnet_prefix = IN6ADDR_ANY_INIT; 29166cd6a6acSopenharmony_ci uint16_t low; 29176cd6a6acSopenharmony_ci uint16_t high; 29186cd6a6acSopenharmony_ci char low_high_str[44]; /* 2^64 <= 20 digits so "(low high)" <= 44 chars */ 29196cd6a6acSopenharmony_ci char *ctx; 29206cd6a6acSopenharmony_ci int rc = 0; 29216cd6a6acSopenharmony_ci 29226cd6a6acSopenharmony_ci for (ibpkeycon = pdb->ocontexts[OCON_IBPKEY]; ibpkeycon != NULL; 29236cd6a6acSopenharmony_ci ibpkeycon = ibpkeycon->next) { 29246cd6a6acSopenharmony_ci memcpy(&subnet_prefix.s6_addr, &ibpkeycon->u.ibpkey.subnet_prefix, 29256cd6a6acSopenharmony_ci sizeof(ibpkeycon->u.ibpkey.subnet_prefix)); 29266cd6a6acSopenharmony_ci 29276cd6a6acSopenharmony_ci if (inet_ntop(AF_INET6, &subnet_prefix.s6_addr, 29286cd6a6acSopenharmony_ci subnet_prefix_str, INET6_ADDRSTRLEN) == NULL) { 29296cd6a6acSopenharmony_ci sepol_log_err("ibpkeycon subnet_prefix is invalid: %m"); 29306cd6a6acSopenharmony_ci rc = -1; 29316cd6a6acSopenharmony_ci goto exit; 29326cd6a6acSopenharmony_ci } 29336cd6a6acSopenharmony_ci 29346cd6a6acSopenharmony_ci low = ibpkeycon->u.ibpkey.low_pkey; 29356cd6a6acSopenharmony_ci high = ibpkeycon->u.ibpkey.high_pkey; 29366cd6a6acSopenharmony_ci if (low == high) { 29376cd6a6acSopenharmony_ci rc = snprintf(low_high_str, 44, "%u", low); 29386cd6a6acSopenharmony_ci } else { 29396cd6a6acSopenharmony_ci rc = snprintf(low_high_str, 44, "(%u %u)", low, high); 29406cd6a6acSopenharmony_ci } 29416cd6a6acSopenharmony_ci if (rc < 0 || rc >= 44) { 29426cd6a6acSopenharmony_ci rc = -1; 29436cd6a6acSopenharmony_ci goto exit; 29446cd6a6acSopenharmony_ci } 29456cd6a6acSopenharmony_ci 29466cd6a6acSopenharmony_ci ctx = context_to_str(pdb, &ibpkeycon->context[0]); 29476cd6a6acSopenharmony_ci if (!ctx) { 29486cd6a6acSopenharmony_ci rc = -1; 29496cd6a6acSopenharmony_ci goto exit; 29506cd6a6acSopenharmony_ci } 29516cd6a6acSopenharmony_ci 29526cd6a6acSopenharmony_ci sepol_printf(out, "(ibpkeycon %s %s %s)\n", subnet_prefix_str, low_high_str, ctx); 29536cd6a6acSopenharmony_ci 29546cd6a6acSopenharmony_ci free(ctx); 29556cd6a6acSopenharmony_ci } 29566cd6a6acSopenharmony_ci 29576cd6a6acSopenharmony_ci rc = 0; 29586cd6a6acSopenharmony_ci 29596cd6a6acSopenharmony_ciexit: 29606cd6a6acSopenharmony_ci if (rc != 0) { 29616cd6a6acSopenharmony_ci sepol_log_err("Error writing ibpkeycon rules to CIL\n"); 29626cd6a6acSopenharmony_ci } 29636cd6a6acSopenharmony_ci 29646cd6a6acSopenharmony_ci return rc; 29656cd6a6acSopenharmony_ci} 29666cd6a6acSopenharmony_ci 29676cd6a6acSopenharmony_cistatic int write_selinux_ibendport_rules_to_cil(FILE *out, struct policydb *pdb) 29686cd6a6acSopenharmony_ci{ 29696cd6a6acSopenharmony_ci struct ocontext *ibendportcon; 29706cd6a6acSopenharmony_ci char port_str[4]; 29716cd6a6acSopenharmony_ci char *ctx; 29726cd6a6acSopenharmony_ci int rc = 0; 29736cd6a6acSopenharmony_ci 29746cd6a6acSopenharmony_ci for (ibendportcon = pdb->ocontexts[OCON_IBENDPORT]; 29756cd6a6acSopenharmony_ci ibendportcon != NULL; ibendportcon = ibendportcon->next) { 29766cd6a6acSopenharmony_ci rc = snprintf(port_str, 4, "%u", ibendportcon->u.ibendport.port); 29776cd6a6acSopenharmony_ci if (rc < 0 || rc >= 4) { 29786cd6a6acSopenharmony_ci rc = -1; 29796cd6a6acSopenharmony_ci goto exit; 29806cd6a6acSopenharmony_ci } 29816cd6a6acSopenharmony_ci 29826cd6a6acSopenharmony_ci ctx = context_to_str(pdb, &ibendportcon->context[0]); 29836cd6a6acSopenharmony_ci if (!ctx) { 29846cd6a6acSopenharmony_ci rc = -1; 29856cd6a6acSopenharmony_ci goto exit; 29866cd6a6acSopenharmony_ci } 29876cd6a6acSopenharmony_ci 29886cd6a6acSopenharmony_ci sepol_printf(out, "(ibendportcon %s %s %s)\n", 29896cd6a6acSopenharmony_ci ibendportcon->u.ibendport.dev_name, port_str, ctx); 29906cd6a6acSopenharmony_ci 29916cd6a6acSopenharmony_ci free(ctx); 29926cd6a6acSopenharmony_ci } 29936cd6a6acSopenharmony_ci 29946cd6a6acSopenharmony_ci rc = 0; 29956cd6a6acSopenharmony_ci 29966cd6a6acSopenharmony_ciexit: 29976cd6a6acSopenharmony_ci if (rc != 0) { 29986cd6a6acSopenharmony_ci sepol_log_err("Error writing ibendportcon rules to CIL\n"); 29996cd6a6acSopenharmony_ci } 30006cd6a6acSopenharmony_ci 30016cd6a6acSopenharmony_ci return rc; 30026cd6a6acSopenharmony_ci} 30036cd6a6acSopenharmony_ci 30046cd6a6acSopenharmony_cistatic int write_xen_isid_rules_to_cil(FILE *out, struct policydb *pdb) 30056cd6a6acSopenharmony_ci{ 30066cd6a6acSopenharmony_ci return write_sid_context_rules_to_cil(out, pdb, xen_sid_to_str, XEN_SID_SZ); 30076cd6a6acSopenharmony_ci} 30086cd6a6acSopenharmony_ci 30096cd6a6acSopenharmony_cistatic int write_xen_pirq_rules_to_cil(FILE *out, struct policydb *pdb) 30106cd6a6acSopenharmony_ci{ 30116cd6a6acSopenharmony_ci struct ocontext *pirq; 30126cd6a6acSopenharmony_ci char pirq_str[21]; /* 2^64-1 <= 20 digits */ 30136cd6a6acSopenharmony_ci char *ctx; 30146cd6a6acSopenharmony_ci int rc = 0; 30156cd6a6acSopenharmony_ci 30166cd6a6acSopenharmony_ci for (pirq = pdb->ocontexts[1]; pirq != NULL; pirq = pirq->next) { 30176cd6a6acSopenharmony_ci rc = snprintf(pirq_str, 21, "%i", pirq->u.pirq); 30186cd6a6acSopenharmony_ci if (rc < 0 || rc >= 21) { 30196cd6a6acSopenharmony_ci rc = -1; 30206cd6a6acSopenharmony_ci goto exit; 30216cd6a6acSopenharmony_ci } 30226cd6a6acSopenharmony_ci 30236cd6a6acSopenharmony_ci ctx = context_to_str(pdb, &pirq->context[0]); 30246cd6a6acSopenharmony_ci if (!ctx) { 30256cd6a6acSopenharmony_ci rc = -1; 30266cd6a6acSopenharmony_ci goto exit; 30276cd6a6acSopenharmony_ci } 30286cd6a6acSopenharmony_ci 30296cd6a6acSopenharmony_ci sepol_printf(out, "(pirqcon %s %s)\n", pirq_str, ctx); 30306cd6a6acSopenharmony_ci 30316cd6a6acSopenharmony_ci free(ctx); 30326cd6a6acSopenharmony_ci } 30336cd6a6acSopenharmony_ci 30346cd6a6acSopenharmony_ci rc = 0; 30356cd6a6acSopenharmony_ci 30366cd6a6acSopenharmony_ciexit: 30376cd6a6acSopenharmony_ci if (rc != 0) { 30386cd6a6acSopenharmony_ci sepol_log_err("Error writing pirqcon rules to CIL\n"); 30396cd6a6acSopenharmony_ci } 30406cd6a6acSopenharmony_ci 30416cd6a6acSopenharmony_ci return rc; 30426cd6a6acSopenharmony_ci} 30436cd6a6acSopenharmony_ci 30446cd6a6acSopenharmony_cistatic int write_xen_ioport_rules_to_cil(FILE *out, struct policydb *pdb) 30456cd6a6acSopenharmony_ci{ 30466cd6a6acSopenharmony_ci struct ocontext *ioport; 30476cd6a6acSopenharmony_ci uint32_t low; 30486cd6a6acSopenharmony_ci uint32_t high; 30496cd6a6acSopenharmony_ci char low_high_str[40]; /* 2^64-1 <= 16 digits (hex) so (low high) < 40 chars */ 30506cd6a6acSopenharmony_ci char *ctx; 30516cd6a6acSopenharmony_ci int rc = 0; 30526cd6a6acSopenharmony_ci 30536cd6a6acSopenharmony_ci for (ioport = pdb->ocontexts[2]; ioport != NULL; ioport = ioport->next) { 30546cd6a6acSopenharmony_ci low = ioport->u.ioport.low_ioport; 30556cd6a6acSopenharmony_ci high = ioport->u.ioport.high_ioport; 30566cd6a6acSopenharmony_ci if (low == high) { 30576cd6a6acSopenharmony_ci rc = snprintf(low_high_str, 40, "0x%x", low); 30586cd6a6acSopenharmony_ci } else { 30596cd6a6acSopenharmony_ci rc = snprintf(low_high_str, 40, "(0x%x 0x%x)", low, high); 30606cd6a6acSopenharmony_ci } 30616cd6a6acSopenharmony_ci if (rc < 0 || rc >= 40) { 30626cd6a6acSopenharmony_ci rc = -1; 30636cd6a6acSopenharmony_ci goto exit; 30646cd6a6acSopenharmony_ci } 30656cd6a6acSopenharmony_ci 30666cd6a6acSopenharmony_ci ctx = context_to_str(pdb, &ioport->context[0]); 30676cd6a6acSopenharmony_ci if (!ctx) { 30686cd6a6acSopenharmony_ci rc = -1; 30696cd6a6acSopenharmony_ci goto exit; 30706cd6a6acSopenharmony_ci } 30716cd6a6acSopenharmony_ci 30726cd6a6acSopenharmony_ci sepol_printf(out, "(ioportcon %s %s)\n", low_high_str, ctx); 30736cd6a6acSopenharmony_ci 30746cd6a6acSopenharmony_ci free(ctx); 30756cd6a6acSopenharmony_ci } 30766cd6a6acSopenharmony_ci 30776cd6a6acSopenharmony_ci rc = 0; 30786cd6a6acSopenharmony_ci 30796cd6a6acSopenharmony_ciexit: 30806cd6a6acSopenharmony_ci if (rc != 0) { 30816cd6a6acSopenharmony_ci sepol_log_err("Error writing ioportcon rules to CIL\n"); 30826cd6a6acSopenharmony_ci } 30836cd6a6acSopenharmony_ci 30846cd6a6acSopenharmony_ci return rc; 30856cd6a6acSopenharmony_ci} 30866cd6a6acSopenharmony_ci 30876cd6a6acSopenharmony_cistatic int write_xen_iomem_rules_to_cil(FILE *out, struct policydb *pdb) 30886cd6a6acSopenharmony_ci{ 30896cd6a6acSopenharmony_ci struct ocontext *iomem; 30906cd6a6acSopenharmony_ci uint64_t low; 30916cd6a6acSopenharmony_ci uint64_t high; 30926cd6a6acSopenharmony_ci char low_high_str[40]; /* 2^64-1 <= 16 digits (hex) so (low high) < 40 chars */ 30936cd6a6acSopenharmony_ci char *ctx; 30946cd6a6acSopenharmony_ci int rc = 0; 30956cd6a6acSopenharmony_ci 30966cd6a6acSopenharmony_ci for (iomem = pdb->ocontexts[3]; iomem != NULL; iomem = iomem->next) { 30976cd6a6acSopenharmony_ci low = iomem->u.iomem.low_iomem; 30986cd6a6acSopenharmony_ci high = iomem->u.iomem.high_iomem; 30996cd6a6acSopenharmony_ci if (low == high) { 31006cd6a6acSopenharmony_ci rc = snprintf(low_high_str, 40, "0x%"PRIx64, low); 31016cd6a6acSopenharmony_ci } else { 31026cd6a6acSopenharmony_ci rc = snprintf(low_high_str, 40, "(0x%"PRIx64" 0x%"PRIx64")", low, high); 31036cd6a6acSopenharmony_ci } 31046cd6a6acSopenharmony_ci if (rc < 0 || rc >= 40) { 31056cd6a6acSopenharmony_ci rc = -1; 31066cd6a6acSopenharmony_ci goto exit; 31076cd6a6acSopenharmony_ci } 31086cd6a6acSopenharmony_ci 31096cd6a6acSopenharmony_ci ctx = context_to_str(pdb, &iomem->context[0]); 31106cd6a6acSopenharmony_ci if (!ctx) { 31116cd6a6acSopenharmony_ci rc = -1; 31126cd6a6acSopenharmony_ci goto exit; 31136cd6a6acSopenharmony_ci } 31146cd6a6acSopenharmony_ci 31156cd6a6acSopenharmony_ci sepol_printf(out, "(iomemcon %s %s)\n", low_high_str, ctx); 31166cd6a6acSopenharmony_ci 31176cd6a6acSopenharmony_ci free(ctx); 31186cd6a6acSopenharmony_ci } 31196cd6a6acSopenharmony_ci 31206cd6a6acSopenharmony_ci rc = 0; 31216cd6a6acSopenharmony_ci 31226cd6a6acSopenharmony_ciexit: 31236cd6a6acSopenharmony_ci if (rc != 0) { 31246cd6a6acSopenharmony_ci sepol_log_err("Error writing iomemcon rules to CIL\n"); 31256cd6a6acSopenharmony_ci } 31266cd6a6acSopenharmony_ci 31276cd6a6acSopenharmony_ci return rc; 31286cd6a6acSopenharmony_ci} 31296cd6a6acSopenharmony_ci 31306cd6a6acSopenharmony_cistatic int write_xen_pcidevice_rules_to_cil(FILE *out, struct policydb *pdb) 31316cd6a6acSopenharmony_ci{ 31326cd6a6acSopenharmony_ci struct ocontext *pcid; 31336cd6a6acSopenharmony_ci char device_str[20]; /* 2^64-1 <= 16 digits (hex) so (low high) < 19 chars */ 31346cd6a6acSopenharmony_ci char *ctx; 31356cd6a6acSopenharmony_ci int rc = 0; 31366cd6a6acSopenharmony_ci 31376cd6a6acSopenharmony_ci for (pcid = pdb->ocontexts[4]; pcid != NULL; pcid = pcid->next) { 31386cd6a6acSopenharmony_ci rc = snprintf(device_str, 20, "0x%lx", (unsigned long)pcid->u.device); 31396cd6a6acSopenharmony_ci if (rc < 0 || rc >= 20) { 31406cd6a6acSopenharmony_ci rc = -1; 31416cd6a6acSopenharmony_ci goto exit; 31426cd6a6acSopenharmony_ci } 31436cd6a6acSopenharmony_ci 31446cd6a6acSopenharmony_ci ctx = context_to_str(pdb, &pcid->context[0]); 31456cd6a6acSopenharmony_ci if (!ctx) { 31466cd6a6acSopenharmony_ci rc = -1; 31476cd6a6acSopenharmony_ci goto exit; 31486cd6a6acSopenharmony_ci } 31496cd6a6acSopenharmony_ci 31506cd6a6acSopenharmony_ci sepol_printf(out, "(pcidevicecon %s %s)\n", device_str, ctx); 31516cd6a6acSopenharmony_ci 31526cd6a6acSopenharmony_ci free(ctx); 31536cd6a6acSopenharmony_ci } 31546cd6a6acSopenharmony_ci 31556cd6a6acSopenharmony_ci rc = 0; 31566cd6a6acSopenharmony_ci 31576cd6a6acSopenharmony_ciexit: 31586cd6a6acSopenharmony_ci if (rc != 0) { 31596cd6a6acSopenharmony_ci sepol_log_err("Error writing pcidevicecon rules to CIL\n"); 31606cd6a6acSopenharmony_ci } 31616cd6a6acSopenharmony_ci 31626cd6a6acSopenharmony_ci return rc; 31636cd6a6acSopenharmony_ci} 31646cd6a6acSopenharmony_ci 31656cd6a6acSopenharmony_cistatic int write_xen_devicetree_rules_to_cil(FILE *out, struct policydb *pdb) 31666cd6a6acSopenharmony_ci{ 31676cd6a6acSopenharmony_ci struct ocontext *dtree; 31686cd6a6acSopenharmony_ci char *name, *ctx; 31696cd6a6acSopenharmony_ci int rc = 0; 31706cd6a6acSopenharmony_ci 31716cd6a6acSopenharmony_ci for (dtree = pdb->ocontexts[5]; dtree != NULL; dtree = dtree->next) { 31726cd6a6acSopenharmony_ci name = dtree->u.name; 31736cd6a6acSopenharmony_ci ctx = context_to_str(pdb, &dtree->context[0]); 31746cd6a6acSopenharmony_ci if (!ctx) { 31756cd6a6acSopenharmony_ci rc = -1; 31766cd6a6acSopenharmony_ci goto exit; 31776cd6a6acSopenharmony_ci } 31786cd6a6acSopenharmony_ci 31796cd6a6acSopenharmony_ci sepol_printf(out, "(devicetreecon \"%s\" %s)\n", name, ctx); 31806cd6a6acSopenharmony_ci 31816cd6a6acSopenharmony_ci free(ctx); 31826cd6a6acSopenharmony_ci } 31836cd6a6acSopenharmony_ci 31846cd6a6acSopenharmony_ciexit: 31856cd6a6acSopenharmony_ci if (rc != 0) { 31866cd6a6acSopenharmony_ci sepol_log_err("Error writing devicetreecon rules to CIL\n"); 31876cd6a6acSopenharmony_ci } 31886cd6a6acSopenharmony_ci 31896cd6a6acSopenharmony_ci return rc; 31906cd6a6acSopenharmony_ci} 31916cd6a6acSopenharmony_ci 31926cd6a6acSopenharmony_ciint sepol_kernel_policydb_to_cil(FILE *out, struct policydb *pdb) 31936cd6a6acSopenharmony_ci{ 31946cd6a6acSopenharmony_ci struct strs *mls_constraints = NULL; 31956cd6a6acSopenharmony_ci struct strs *non_mls_constraints = NULL; 31966cd6a6acSopenharmony_ci struct strs *mls_validatetrans = NULL; 31976cd6a6acSopenharmony_ci struct strs *non_mls_validatetrans = NULL; 31986cd6a6acSopenharmony_ci int rc = 0; 31996cd6a6acSopenharmony_ci 32006cd6a6acSopenharmony_ci rc = strs_init(&mls_constraints, 32); 32016cd6a6acSopenharmony_ci if (rc != 0) { 32026cd6a6acSopenharmony_ci goto exit; 32036cd6a6acSopenharmony_ci } 32046cd6a6acSopenharmony_ci 32056cd6a6acSopenharmony_ci rc = strs_init(&non_mls_constraints, 32); 32066cd6a6acSopenharmony_ci if (rc != 0) { 32076cd6a6acSopenharmony_ci goto exit; 32086cd6a6acSopenharmony_ci } 32096cd6a6acSopenharmony_ci 32106cd6a6acSopenharmony_ci rc = strs_init(&mls_validatetrans, 32); 32116cd6a6acSopenharmony_ci if (rc != 0) { 32126cd6a6acSopenharmony_ci goto exit; 32136cd6a6acSopenharmony_ci } 32146cd6a6acSopenharmony_ci 32156cd6a6acSopenharmony_ci rc = strs_init(&non_mls_validatetrans, 32); 32166cd6a6acSopenharmony_ci if (rc != 0) { 32176cd6a6acSopenharmony_ci goto exit; 32186cd6a6acSopenharmony_ci } 32196cd6a6acSopenharmony_ci 32206cd6a6acSopenharmony_ci if (pdb == NULL) { 32216cd6a6acSopenharmony_ci sepol_log_err("No policy"); 32226cd6a6acSopenharmony_ci rc = -1; 32236cd6a6acSopenharmony_ci goto exit; 32246cd6a6acSopenharmony_ci } 32256cd6a6acSopenharmony_ci 32266cd6a6acSopenharmony_ci if (pdb->policy_type != SEPOL_POLICY_KERN) { 32276cd6a6acSopenharmony_ci sepol_log_err("Policy is not a kernel policy"); 32286cd6a6acSopenharmony_ci rc = -1; 32296cd6a6acSopenharmony_ci goto exit; 32306cd6a6acSopenharmony_ci } 32316cd6a6acSopenharmony_ci 32326cd6a6acSopenharmony_ci if (pdb->policyvers >= POLICYDB_VERSION_AVTAB && pdb->policyvers <= POLICYDB_VERSION_PERMISSIVE) { 32336cd6a6acSopenharmony_ci /* 32346cd6a6acSopenharmony_ci * For policy versions between 20 and 23, attributes exist in the policy, 32356cd6a6acSopenharmony_ci * but only in the type_attr_map. This means that there are gaps in both 32366cd6a6acSopenharmony_ci * the type_val_to_struct and p_type_val_to_name arrays and policy rules 32376cd6a6acSopenharmony_ci * can refer to those gaps. 32386cd6a6acSopenharmony_ci */ 32396cd6a6acSopenharmony_ci sepol_log_err("Writing policy versions between 20 and 23 as CIL is not supported"); 32406cd6a6acSopenharmony_ci rc = -1; 32416cd6a6acSopenharmony_ci goto exit; 32426cd6a6acSopenharmony_ci } 32436cd6a6acSopenharmony_ci 32446cd6a6acSopenharmony_ci rc = constraint_rules_to_strs(pdb, mls_constraints, non_mls_constraints); 32456cd6a6acSopenharmony_ci if (rc != 0) { 32466cd6a6acSopenharmony_ci goto exit; 32476cd6a6acSopenharmony_ci } 32486cd6a6acSopenharmony_ci 32496cd6a6acSopenharmony_ci rc = validatetrans_rules_to_strs(pdb, mls_validatetrans, non_mls_validatetrans); 32506cd6a6acSopenharmony_ci if (rc != 0) { 32516cd6a6acSopenharmony_ci goto exit; 32526cd6a6acSopenharmony_ci } 32536cd6a6acSopenharmony_ci 32546cd6a6acSopenharmony_ci rc = write_handle_unknown_to_cil(out, pdb); 32556cd6a6acSopenharmony_ci if (rc != 0) { 32566cd6a6acSopenharmony_ci goto exit; 32576cd6a6acSopenharmony_ci } 32586cd6a6acSopenharmony_ci 32596cd6a6acSopenharmony_ci rc = write_class_decl_rules_to_cil(out, pdb); 32606cd6a6acSopenharmony_ci if (rc != 0) { 32616cd6a6acSopenharmony_ci goto exit; 32626cd6a6acSopenharmony_ci } 32636cd6a6acSopenharmony_ci 32646cd6a6acSopenharmony_ci rc = write_sid_decl_rules_to_cil(out, pdb); 32656cd6a6acSopenharmony_ci if (rc != 0) { 32666cd6a6acSopenharmony_ci goto exit; 32676cd6a6acSopenharmony_ci } 32686cd6a6acSopenharmony_ci 32696cd6a6acSopenharmony_ci rc = write_default_rules_to_cil(out, pdb); 32706cd6a6acSopenharmony_ci if (rc != 0) { 32716cd6a6acSopenharmony_ci goto exit; 32726cd6a6acSopenharmony_ci } 32736cd6a6acSopenharmony_ci 32746cd6a6acSopenharmony_ci rc = write_mls_rules_to_cil(out, pdb); 32756cd6a6acSopenharmony_ci if (rc != 0) { 32766cd6a6acSopenharmony_ci goto exit; 32776cd6a6acSopenharmony_ci } 32786cd6a6acSopenharmony_ci 32796cd6a6acSopenharmony_ci strs_write_each(mls_constraints, out); 32806cd6a6acSopenharmony_ci strs_write_each(mls_validatetrans, out); 32816cd6a6acSopenharmony_ci 32826cd6a6acSopenharmony_ci rc = write_polcap_rules_to_cil(out, pdb); 32836cd6a6acSopenharmony_ci if (rc != 0) { 32846cd6a6acSopenharmony_ci goto exit; 32856cd6a6acSopenharmony_ci } 32866cd6a6acSopenharmony_ci 32876cd6a6acSopenharmony_ci rc = write_type_attributes_to_cil(out, pdb); 32886cd6a6acSopenharmony_ci if (rc != 0) { 32896cd6a6acSopenharmony_ci goto exit; 32906cd6a6acSopenharmony_ci } 32916cd6a6acSopenharmony_ci 32926cd6a6acSopenharmony_ci rc = write_role_attributes_to_cil(out, pdb); 32936cd6a6acSopenharmony_ci if (rc != 0) { 32946cd6a6acSopenharmony_ci goto exit; 32956cd6a6acSopenharmony_ci } 32966cd6a6acSopenharmony_ci 32976cd6a6acSopenharmony_ci rc = write_boolean_decl_rules_to_cil(out, pdb); 32986cd6a6acSopenharmony_ci if (rc != 0) { 32996cd6a6acSopenharmony_ci goto exit; 33006cd6a6acSopenharmony_ci } 33016cd6a6acSopenharmony_ci 33026cd6a6acSopenharmony_ci rc = write_type_decl_rules_to_cil(out, pdb); 33036cd6a6acSopenharmony_ci if (rc != 0) { 33046cd6a6acSopenharmony_ci goto exit; 33056cd6a6acSopenharmony_ci } 33066cd6a6acSopenharmony_ci 33076cd6a6acSopenharmony_ci rc = write_type_alias_rules_to_cil(out, pdb); 33086cd6a6acSopenharmony_ci if (rc != 0) { 33096cd6a6acSopenharmony_ci goto exit; 33106cd6a6acSopenharmony_ci } 33116cd6a6acSopenharmony_ci 33126cd6a6acSopenharmony_ci rc = write_type_bounds_rules_to_cil(out, pdb); 33136cd6a6acSopenharmony_ci if (rc != 0) { 33146cd6a6acSopenharmony_ci goto exit; 33156cd6a6acSopenharmony_ci } 33166cd6a6acSopenharmony_ci 33176cd6a6acSopenharmony_ci rc = write_type_attribute_sets_to_cil(out, pdb); 33186cd6a6acSopenharmony_ci if (rc != 0) { 33196cd6a6acSopenharmony_ci goto exit; 33206cd6a6acSopenharmony_ci } 33216cd6a6acSopenharmony_ci 33226cd6a6acSopenharmony_ci rc = write_type_permissive_rules_to_cil(out, pdb); 33236cd6a6acSopenharmony_ci if (rc != 0) { 33246cd6a6acSopenharmony_ci goto exit; 33256cd6a6acSopenharmony_ci } 33266cd6a6acSopenharmony_ci 33276cd6a6acSopenharmony_ci rc = write_avtab_to_cil(out, pdb, 0); 33286cd6a6acSopenharmony_ci if (rc != 0) { 33296cd6a6acSopenharmony_ci goto exit; 33306cd6a6acSopenharmony_ci } 33316cd6a6acSopenharmony_ci 33326cd6a6acSopenharmony_ci rc = write_filename_trans_rules_to_cil(out, pdb); 33336cd6a6acSopenharmony_ci if (rc != 0) { 33346cd6a6acSopenharmony_ci goto exit; 33356cd6a6acSopenharmony_ci } 33366cd6a6acSopenharmony_ci 33376cd6a6acSopenharmony_ci if (pdb->mls) { 33386cd6a6acSopenharmony_ci rc = write_range_trans_rules_to_cil(out, pdb); 33396cd6a6acSopenharmony_ci if (rc != 0) { 33406cd6a6acSopenharmony_ci goto exit; 33416cd6a6acSopenharmony_ci } 33426cd6a6acSopenharmony_ci } 33436cd6a6acSopenharmony_ci 33446cd6a6acSopenharmony_ci rc = write_cond_nodes_to_cil(out, pdb); 33456cd6a6acSopenharmony_ci if (rc != 0) { 33466cd6a6acSopenharmony_ci goto exit; 33476cd6a6acSopenharmony_ci } 33486cd6a6acSopenharmony_ci 33496cd6a6acSopenharmony_ci rc = write_role_decl_rules_to_cil(out, pdb); 33506cd6a6acSopenharmony_ci if (rc != 0) { 33516cd6a6acSopenharmony_ci goto exit; 33526cd6a6acSopenharmony_ci } 33536cd6a6acSopenharmony_ci 33546cd6a6acSopenharmony_ci rc = write_role_transition_rules_to_cil(out, pdb); 33556cd6a6acSopenharmony_ci if (rc != 0) { 33566cd6a6acSopenharmony_ci goto exit; 33576cd6a6acSopenharmony_ci } 33586cd6a6acSopenharmony_ci 33596cd6a6acSopenharmony_ci rc = write_role_allow_rules_to_cil(out, pdb); 33606cd6a6acSopenharmony_ci if (rc != 0) { 33616cd6a6acSopenharmony_ci goto exit; 33626cd6a6acSopenharmony_ci } 33636cd6a6acSopenharmony_ci 33646cd6a6acSopenharmony_ci rc = write_user_decl_rules_to_cil(out, pdb); 33656cd6a6acSopenharmony_ci if (rc != 0) { 33666cd6a6acSopenharmony_ci goto exit; 33676cd6a6acSopenharmony_ci } 33686cd6a6acSopenharmony_ci 33696cd6a6acSopenharmony_ci strs_write_each(non_mls_constraints, out); 33706cd6a6acSopenharmony_ci strs_write_each(non_mls_validatetrans, out); 33716cd6a6acSopenharmony_ci 33726cd6a6acSopenharmony_ci rc = sort_ocontexts(pdb); 33736cd6a6acSopenharmony_ci if (rc != 0) { 33746cd6a6acSopenharmony_ci goto exit; 33756cd6a6acSopenharmony_ci } 33766cd6a6acSopenharmony_ci 33776cd6a6acSopenharmony_ci if (pdb->target_platform == SEPOL_TARGET_SELINUX) { 33786cd6a6acSopenharmony_ci rc = write_selinux_isid_rules_to_cil(out, pdb); 33796cd6a6acSopenharmony_ci if (rc != 0) { 33806cd6a6acSopenharmony_ci goto exit; 33816cd6a6acSopenharmony_ci } 33826cd6a6acSopenharmony_ci 33836cd6a6acSopenharmony_ci rc = write_selinux_fsuse_rules_to_cil(out, pdb); 33846cd6a6acSopenharmony_ci if (rc != 0) { 33856cd6a6acSopenharmony_ci goto exit; 33866cd6a6acSopenharmony_ci } 33876cd6a6acSopenharmony_ci 33886cd6a6acSopenharmony_ci rc = write_genfscon_rules_to_cil(out, pdb); 33896cd6a6acSopenharmony_ci if (rc != 0) { 33906cd6a6acSopenharmony_ci goto exit; 33916cd6a6acSopenharmony_ci } 33926cd6a6acSopenharmony_ci 33936cd6a6acSopenharmony_ci rc = write_selinux_port_rules_to_cil(out, pdb); 33946cd6a6acSopenharmony_ci if (rc != 0) { 33956cd6a6acSopenharmony_ci goto exit; 33966cd6a6acSopenharmony_ci } 33976cd6a6acSopenharmony_ci 33986cd6a6acSopenharmony_ci rc = write_selinux_netif_rules_to_cil(out, pdb); 33996cd6a6acSopenharmony_ci if (rc != 0) { 34006cd6a6acSopenharmony_ci goto exit; 34016cd6a6acSopenharmony_ci } 34026cd6a6acSopenharmony_ci 34036cd6a6acSopenharmony_ci rc = write_selinux_node_rules_to_cil(out, pdb); 34046cd6a6acSopenharmony_ci if (rc != 0) { 34056cd6a6acSopenharmony_ci goto exit; 34066cd6a6acSopenharmony_ci } 34076cd6a6acSopenharmony_ci 34086cd6a6acSopenharmony_ci rc = write_selinux_node6_rules_to_cil(out, pdb); 34096cd6a6acSopenharmony_ci if (rc != 0) { 34106cd6a6acSopenharmony_ci goto exit; 34116cd6a6acSopenharmony_ci } 34126cd6a6acSopenharmony_ci 34136cd6a6acSopenharmony_ci rc = write_selinux_ibpkey_rules_to_cil(out, pdb); 34146cd6a6acSopenharmony_ci if (rc != 0) { 34156cd6a6acSopenharmony_ci goto exit; 34166cd6a6acSopenharmony_ci } 34176cd6a6acSopenharmony_ci 34186cd6a6acSopenharmony_ci rc = write_selinux_ibendport_rules_to_cil(out, pdb); 34196cd6a6acSopenharmony_ci if (rc != 0) { 34206cd6a6acSopenharmony_ci goto exit; 34216cd6a6acSopenharmony_ci } 34226cd6a6acSopenharmony_ci } else if (pdb->target_platform == SEPOL_TARGET_XEN) { 34236cd6a6acSopenharmony_ci rc = write_xen_isid_rules_to_cil(out, pdb); 34246cd6a6acSopenharmony_ci if (rc != 0) { 34256cd6a6acSopenharmony_ci goto exit; 34266cd6a6acSopenharmony_ci } 34276cd6a6acSopenharmony_ci 34286cd6a6acSopenharmony_ci rc = write_xen_pirq_rules_to_cil(out, pdb); 34296cd6a6acSopenharmony_ci if (rc != 0) { 34306cd6a6acSopenharmony_ci goto exit; 34316cd6a6acSopenharmony_ci } 34326cd6a6acSopenharmony_ci 34336cd6a6acSopenharmony_ci rc = write_xen_ioport_rules_to_cil(out, pdb); 34346cd6a6acSopenharmony_ci if (rc != 0) { 34356cd6a6acSopenharmony_ci goto exit; 34366cd6a6acSopenharmony_ci } 34376cd6a6acSopenharmony_ci 34386cd6a6acSopenharmony_ci rc = write_xen_iomem_rules_to_cil(out, pdb); 34396cd6a6acSopenharmony_ci if (rc != 0) { 34406cd6a6acSopenharmony_ci goto exit; 34416cd6a6acSopenharmony_ci } 34426cd6a6acSopenharmony_ci 34436cd6a6acSopenharmony_ci rc = write_xen_pcidevice_rules_to_cil(out, pdb); 34446cd6a6acSopenharmony_ci if (rc != 0) { 34456cd6a6acSopenharmony_ci goto exit; 34466cd6a6acSopenharmony_ci } 34476cd6a6acSopenharmony_ci 34486cd6a6acSopenharmony_ci rc = write_xen_devicetree_rules_to_cil(out, pdb); 34496cd6a6acSopenharmony_ci if (rc != 0) { 34506cd6a6acSopenharmony_ci goto exit; 34516cd6a6acSopenharmony_ci } 34526cd6a6acSopenharmony_ci } 34536cd6a6acSopenharmony_ci 34546cd6a6acSopenharmony_ciexit: 34556cd6a6acSopenharmony_ci strs_free_all(mls_constraints); 34566cd6a6acSopenharmony_ci strs_destroy(&mls_constraints); 34576cd6a6acSopenharmony_ci strs_free_all(non_mls_constraints); 34586cd6a6acSopenharmony_ci strs_destroy(&non_mls_constraints); 34596cd6a6acSopenharmony_ci strs_free_all(mls_validatetrans); 34606cd6a6acSopenharmony_ci strs_destroy(&mls_validatetrans); 34616cd6a6acSopenharmony_ci strs_free_all(non_mls_validatetrans); 34626cd6a6acSopenharmony_ci strs_destroy(&non_mls_validatetrans); 34636cd6a6acSopenharmony_ci 34646cd6a6acSopenharmony_ci return rc; 34656cd6a6acSopenharmony_ci} 3466