16cd6a6acSopenharmony_ci 26cd6a6acSopenharmony_ci#include <sepol/policydb/conditional.h> 36cd6a6acSopenharmony_ci#include <sepol/policydb/ebitmap.h> 46cd6a6acSopenharmony_ci#include <sepol/policydb/policydb.h> 56cd6a6acSopenharmony_ci#include <sepol/policydb/services.h> 66cd6a6acSopenharmony_ci 76cd6a6acSopenharmony_ci#include "debug.h" 86cd6a6acSopenharmony_ci#include "policydb_validate.h" 96cd6a6acSopenharmony_ci 106cd6a6acSopenharmony_ci#define bool_xor(a, b) (!(a) != !(b)) 116cd6a6acSopenharmony_ci#define bool_xnor(a, b) (!bool_xor(a, b)) 126cd6a6acSopenharmony_ci 136cd6a6acSopenharmony_citypedef struct validate { 146cd6a6acSopenharmony_ci uint32_t nprim; 156cd6a6acSopenharmony_ci ebitmap_t gaps; 166cd6a6acSopenharmony_ci} validate_t; 176cd6a6acSopenharmony_ci 186cd6a6acSopenharmony_citypedef struct map_arg { 196cd6a6acSopenharmony_ci validate_t *flavors; 206cd6a6acSopenharmony_ci sepol_handle_t *handle; 216cd6a6acSopenharmony_ci const policydb_t *policy; 226cd6a6acSopenharmony_ci} map_arg_t; 236cd6a6acSopenharmony_ci 246cd6a6acSopenharmony_cistatic int create_gap_ebitmap(char **val_to_name, uint32_t nprim, ebitmap_t *gaps) 256cd6a6acSopenharmony_ci{ 266cd6a6acSopenharmony_ci unsigned int i; 276cd6a6acSopenharmony_ci 286cd6a6acSopenharmony_ci ebitmap_init(gaps); 296cd6a6acSopenharmony_ci 306cd6a6acSopenharmony_ci for (i = 0; i < nprim; i++) { 316cd6a6acSopenharmony_ci if (!val_to_name[i]) { 326cd6a6acSopenharmony_ci if (ebitmap_set_bit(gaps, i, 1)) 336cd6a6acSopenharmony_ci return -1; 346cd6a6acSopenharmony_ci } 356cd6a6acSopenharmony_ci } 366cd6a6acSopenharmony_ci 376cd6a6acSopenharmony_ci return 0; 386cd6a6acSopenharmony_ci} 396cd6a6acSopenharmony_ci 406cd6a6acSopenharmony_cistatic int validate_init(validate_t *flavor, char **val_to_name, uint32_t nprim) 416cd6a6acSopenharmony_ci{ 426cd6a6acSopenharmony_ci flavor->nprim = nprim; 436cd6a6acSopenharmony_ci if (create_gap_ebitmap(val_to_name, nprim, &flavor->gaps)) 446cd6a6acSopenharmony_ci return -1; 456cd6a6acSopenharmony_ci 466cd6a6acSopenharmony_ci return 0; 476cd6a6acSopenharmony_ci} 486cd6a6acSopenharmony_ci 496cd6a6acSopenharmony_cistatic int validate_array_init(const policydb_t *p, validate_t flavors[]) 506cd6a6acSopenharmony_ci{ 516cd6a6acSopenharmony_ci if (validate_init(&flavors[SYM_COMMONS], p->p_common_val_to_name, p->p_commons.nprim)) 526cd6a6acSopenharmony_ci goto bad; 536cd6a6acSopenharmony_ci if (validate_init(&flavors[SYM_CLASSES], p->p_class_val_to_name, p->p_classes.nprim)) 546cd6a6acSopenharmony_ci goto bad; 556cd6a6acSopenharmony_ci if (validate_init(&flavors[SYM_ROLES], p->p_role_val_to_name, p->p_roles.nprim)) 566cd6a6acSopenharmony_ci goto bad; 576cd6a6acSopenharmony_ci if (p->policyvers < POLICYDB_VERSION_AVTAB || p->policyvers > POLICYDB_VERSION_PERMISSIVE) { 586cd6a6acSopenharmony_ci if (validate_init(&flavors[SYM_TYPES], p->p_type_val_to_name, p->p_types.nprim)) 596cd6a6acSopenharmony_ci goto bad; 606cd6a6acSopenharmony_ci } else { 616cd6a6acSopenharmony_ci /* 626cd6a6acSopenharmony_ci * For policy versions between 20 and 23, attributes exist in the policy, 636cd6a6acSopenharmony_ci * but they only exist in the type_attr_map, so there will be references 646cd6a6acSopenharmony_ci * to gaps and we just have to treat this case as if there were no gaps. 656cd6a6acSopenharmony_ci */ 666cd6a6acSopenharmony_ci flavors[SYM_TYPES].nprim = p->p_types.nprim; 676cd6a6acSopenharmony_ci ebitmap_init(&flavors[SYM_TYPES].gaps); 686cd6a6acSopenharmony_ci } 696cd6a6acSopenharmony_ci if (validate_init(&flavors[SYM_USERS], p->p_user_val_to_name, p->p_users.nprim)) 706cd6a6acSopenharmony_ci goto bad; 716cd6a6acSopenharmony_ci if (validate_init(&flavors[SYM_BOOLS], p->p_bool_val_to_name, p->p_bools.nprim)) 726cd6a6acSopenharmony_ci goto bad; 736cd6a6acSopenharmony_ci if (validate_init(&flavors[SYM_LEVELS], p->p_sens_val_to_name, p->p_levels.nprim)) 746cd6a6acSopenharmony_ci goto bad; 756cd6a6acSopenharmony_ci if (validate_init(&flavors[SYM_CATS], p->p_cat_val_to_name, p->p_cats.nprim)) 766cd6a6acSopenharmony_ci goto bad; 776cd6a6acSopenharmony_ci 786cd6a6acSopenharmony_ci return 0; 796cd6a6acSopenharmony_ci 806cd6a6acSopenharmony_cibad: 816cd6a6acSopenharmony_ci return -1; 826cd6a6acSopenharmony_ci} 836cd6a6acSopenharmony_ci 846cd6a6acSopenharmony_ci/* 856cd6a6acSopenharmony_ci * Functions to validate both kernel and module policydbs 866cd6a6acSopenharmony_ci */ 876cd6a6acSopenharmony_ci 886cd6a6acSopenharmony_ciint value_isvalid(uint32_t value, uint32_t nprim) 896cd6a6acSopenharmony_ci{ 906cd6a6acSopenharmony_ci if (!value || value > nprim) 916cd6a6acSopenharmony_ci return 0; 926cd6a6acSopenharmony_ci 936cd6a6acSopenharmony_ci return 1; 946cd6a6acSopenharmony_ci} 956cd6a6acSopenharmony_ci 966cd6a6acSopenharmony_cistatic int validate_value(uint32_t value, const validate_t *flavor) 976cd6a6acSopenharmony_ci{ 986cd6a6acSopenharmony_ci if (!value || value > flavor->nprim) 996cd6a6acSopenharmony_ci goto bad; 1006cd6a6acSopenharmony_ci if (ebitmap_get_bit(&flavor->gaps, value-1)) 1016cd6a6acSopenharmony_ci goto bad; 1026cd6a6acSopenharmony_ci 1036cd6a6acSopenharmony_ci return 0; 1046cd6a6acSopenharmony_ci 1056cd6a6acSopenharmony_cibad: 1066cd6a6acSopenharmony_ci return -1; 1076cd6a6acSopenharmony_ci} 1086cd6a6acSopenharmony_ci 1096cd6a6acSopenharmony_cistatic int validate_ebitmap(const ebitmap_t *map, const validate_t *flavor) 1106cd6a6acSopenharmony_ci{ 1116cd6a6acSopenharmony_ci if (ebitmap_length(map) > 0 && ebitmap_highest_set_bit(map) >= flavor->nprim) 1126cd6a6acSopenharmony_ci goto bad; 1136cd6a6acSopenharmony_ci if (ebitmap_match_any(map, &flavor->gaps)) 1146cd6a6acSopenharmony_ci goto bad; 1156cd6a6acSopenharmony_ci 1166cd6a6acSopenharmony_ci return 0; 1176cd6a6acSopenharmony_ci 1186cd6a6acSopenharmony_cibad: 1196cd6a6acSopenharmony_ci return -1; 1206cd6a6acSopenharmony_ci} 1216cd6a6acSopenharmony_ci 1226cd6a6acSopenharmony_cistatic int validate_type_set(const type_set_t *type_set, const validate_t *type) 1236cd6a6acSopenharmony_ci{ 1246cd6a6acSopenharmony_ci if (validate_ebitmap(&type_set->types, type)) 1256cd6a6acSopenharmony_ci goto bad; 1266cd6a6acSopenharmony_ci if (validate_ebitmap(&type_set->negset, type)) 1276cd6a6acSopenharmony_ci goto bad; 1286cd6a6acSopenharmony_ci 1296cd6a6acSopenharmony_ci switch (type_set->flags) { 1306cd6a6acSopenharmony_ci case 0: 1316cd6a6acSopenharmony_ci case TYPE_STAR: 1326cd6a6acSopenharmony_ci case TYPE_COMP: 1336cd6a6acSopenharmony_ci break; 1346cd6a6acSopenharmony_ci default: 1356cd6a6acSopenharmony_ci goto bad; 1366cd6a6acSopenharmony_ci } 1376cd6a6acSopenharmony_ci 1386cd6a6acSopenharmony_ci return 0; 1396cd6a6acSopenharmony_ci 1406cd6a6acSopenharmony_cibad: 1416cd6a6acSopenharmony_ci return -1; 1426cd6a6acSopenharmony_ci} 1436cd6a6acSopenharmony_ci 1446cd6a6acSopenharmony_cistatic int validate_empty_type_set(const type_set_t *type_set) 1456cd6a6acSopenharmony_ci{ 1466cd6a6acSopenharmony_ci if (!ebitmap_is_empty(&type_set->types)) 1476cd6a6acSopenharmony_ci goto bad; 1486cd6a6acSopenharmony_ci if (!ebitmap_is_empty(&type_set->negset)) 1496cd6a6acSopenharmony_ci goto bad; 1506cd6a6acSopenharmony_ci if (type_set->flags != 0) 1516cd6a6acSopenharmony_ci goto bad; 1526cd6a6acSopenharmony_ci 1536cd6a6acSopenharmony_ci return 0; 1546cd6a6acSopenharmony_ci 1556cd6a6acSopenharmony_cibad: 1566cd6a6acSopenharmony_ci return -1; 1576cd6a6acSopenharmony_ci} 1586cd6a6acSopenharmony_ci 1596cd6a6acSopenharmony_cistatic int validate_role_set(const role_set_t *role_set, const validate_t *role) 1606cd6a6acSopenharmony_ci{ 1616cd6a6acSopenharmony_ci if (validate_ebitmap(&role_set->roles, role)) 1626cd6a6acSopenharmony_ci goto bad; 1636cd6a6acSopenharmony_ci 1646cd6a6acSopenharmony_ci switch (role_set->flags) { 1656cd6a6acSopenharmony_ci case 0: 1666cd6a6acSopenharmony_ci case ROLE_STAR: 1676cd6a6acSopenharmony_ci case ROLE_COMP: 1686cd6a6acSopenharmony_ci break; 1696cd6a6acSopenharmony_ci default: 1706cd6a6acSopenharmony_ci goto bad; 1716cd6a6acSopenharmony_ci } 1726cd6a6acSopenharmony_ci 1736cd6a6acSopenharmony_ci return 0; 1746cd6a6acSopenharmony_ci 1756cd6a6acSopenharmony_cibad: 1766cd6a6acSopenharmony_ci return -1; 1776cd6a6acSopenharmony_ci} 1786cd6a6acSopenharmony_ci 1796cd6a6acSopenharmony_cistatic int validate_scope(__attribute__ ((unused)) hashtab_key_t k, hashtab_datum_t d, void *args) 1806cd6a6acSopenharmony_ci{ 1816cd6a6acSopenharmony_ci const scope_datum_t *scope_datum = (scope_datum_t *)d; 1826cd6a6acSopenharmony_ci const uint32_t *nprim = (uint32_t *)args; 1836cd6a6acSopenharmony_ci unsigned int i; 1846cd6a6acSopenharmony_ci 1856cd6a6acSopenharmony_ci switch (scope_datum->scope) { 1866cd6a6acSopenharmony_ci case SCOPE_REQ: 1876cd6a6acSopenharmony_ci case SCOPE_DECL: 1886cd6a6acSopenharmony_ci break; 1896cd6a6acSopenharmony_ci default: 1906cd6a6acSopenharmony_ci goto bad; 1916cd6a6acSopenharmony_ci } 1926cd6a6acSopenharmony_ci 1936cd6a6acSopenharmony_ci for (i = 0; i < scope_datum->decl_ids_len; i++) { 1946cd6a6acSopenharmony_ci if (!value_isvalid(scope_datum->decl_ids[i], *nprim)) 1956cd6a6acSopenharmony_ci goto bad; 1966cd6a6acSopenharmony_ci } 1976cd6a6acSopenharmony_ci 1986cd6a6acSopenharmony_ci return 0; 1996cd6a6acSopenharmony_ci 2006cd6a6acSopenharmony_cibad: 2016cd6a6acSopenharmony_ci return -1; 2026cd6a6acSopenharmony_ci} 2036cd6a6acSopenharmony_ci 2046cd6a6acSopenharmony_cistatic int validate_scopes(sepol_handle_t *handle, const symtab_t scopes[], const avrule_block_t *block) 2056cd6a6acSopenharmony_ci{ 2066cd6a6acSopenharmony_ci const avrule_decl_t *decl; 2076cd6a6acSopenharmony_ci unsigned int i; 2086cd6a6acSopenharmony_ci unsigned int num_decls = 0; 2096cd6a6acSopenharmony_ci 2106cd6a6acSopenharmony_ci for (; block != NULL; block = block->next) { 2116cd6a6acSopenharmony_ci for (decl = block->branch_list; decl; decl = decl->next) { 2126cd6a6acSopenharmony_ci num_decls++; 2136cd6a6acSopenharmony_ci } 2146cd6a6acSopenharmony_ci } 2156cd6a6acSopenharmony_ci 2166cd6a6acSopenharmony_ci for (i = 0; i < SYM_NUM; i++) { 2176cd6a6acSopenharmony_ci if (hashtab_map(scopes[i].table, validate_scope, &num_decls)) 2186cd6a6acSopenharmony_ci goto bad; 2196cd6a6acSopenharmony_ci } 2206cd6a6acSopenharmony_ci 2216cd6a6acSopenharmony_ci return 0; 2226cd6a6acSopenharmony_ci 2236cd6a6acSopenharmony_cibad: 2246cd6a6acSopenharmony_ci ERR(handle, "Invalid scope"); 2256cd6a6acSopenharmony_ci return -1; 2266cd6a6acSopenharmony_ci} 2276cd6a6acSopenharmony_ci 2286cd6a6acSopenharmony_cistatic int validate_constraint_nodes(sepol_handle_t *handle, unsigned int nperms, const constraint_node_t *cons, validate_t flavors[]) 2296cd6a6acSopenharmony_ci{ 2306cd6a6acSopenharmony_ci const constraint_expr_t *cexp; 2316cd6a6acSopenharmony_ci 2326cd6a6acSopenharmony_ci for (; cons; cons = cons->next) { 2336cd6a6acSopenharmony_ci if (nperms == 0 && cons->permissions != 0) 2346cd6a6acSopenharmony_ci goto bad; 2356cd6a6acSopenharmony_ci if (nperms > 0 && cons->permissions == 0) 2366cd6a6acSopenharmony_ci goto bad; 2376cd6a6acSopenharmony_ci if (nperms > 0 && nperms != PERM_SYMTAB_SIZE && cons->permissions >= (UINT32_C(1) << nperms)) 2386cd6a6acSopenharmony_ci goto bad; 2396cd6a6acSopenharmony_ci 2406cd6a6acSopenharmony_ci if (!cons->expr) 2416cd6a6acSopenharmony_ci goto bad; 2426cd6a6acSopenharmony_ci 2436cd6a6acSopenharmony_ci for (cexp = cons->expr; cexp; cexp = cexp->next) { 2446cd6a6acSopenharmony_ci if (cexp->expr_type == CEXPR_NAMES) { 2456cd6a6acSopenharmony_ci if (cexp->attr & CEXPR_XTARGET && nperms != 0) 2466cd6a6acSopenharmony_ci goto bad; 2476cd6a6acSopenharmony_ci if (!(cexp->attr & CEXPR_TYPE)) { 2486cd6a6acSopenharmony_ci if (validate_empty_type_set(cexp->type_names)) 2496cd6a6acSopenharmony_ci goto bad; 2506cd6a6acSopenharmony_ci } 2516cd6a6acSopenharmony_ci 2526cd6a6acSopenharmony_ci switch (cexp->op) { 2536cd6a6acSopenharmony_ci case CEXPR_EQ: 2546cd6a6acSopenharmony_ci case CEXPR_NEQ: 2556cd6a6acSopenharmony_ci break; 2566cd6a6acSopenharmony_ci default: 2576cd6a6acSopenharmony_ci goto bad; 2586cd6a6acSopenharmony_ci } 2596cd6a6acSopenharmony_ci 2606cd6a6acSopenharmony_ci switch (cexp->attr) { 2616cd6a6acSopenharmony_ci case CEXPR_USER: 2626cd6a6acSopenharmony_ci case CEXPR_USER | CEXPR_TARGET: 2636cd6a6acSopenharmony_ci case CEXPR_USER | CEXPR_XTARGET: 2646cd6a6acSopenharmony_ci if (validate_ebitmap(&cexp->names, &flavors[SYM_USERS])) 2656cd6a6acSopenharmony_ci goto bad; 2666cd6a6acSopenharmony_ci break; 2676cd6a6acSopenharmony_ci case CEXPR_ROLE: 2686cd6a6acSopenharmony_ci case CEXPR_ROLE | CEXPR_TARGET: 2696cd6a6acSopenharmony_ci case CEXPR_ROLE | CEXPR_XTARGET: 2706cd6a6acSopenharmony_ci if (validate_ebitmap(&cexp->names, &flavors[SYM_ROLES])) 2716cd6a6acSopenharmony_ci goto bad; 2726cd6a6acSopenharmony_ci break; 2736cd6a6acSopenharmony_ci case CEXPR_TYPE: 2746cd6a6acSopenharmony_ci case CEXPR_TYPE | CEXPR_TARGET: 2756cd6a6acSopenharmony_ci case CEXPR_TYPE | CEXPR_XTARGET: 2766cd6a6acSopenharmony_ci if (validate_ebitmap(&cexp->names, &flavors[SYM_TYPES])) 2776cd6a6acSopenharmony_ci goto bad; 2786cd6a6acSopenharmony_ci if (validate_type_set(cexp->type_names, &flavors[SYM_TYPES])) 2796cd6a6acSopenharmony_ci goto bad; 2806cd6a6acSopenharmony_ci break; 2816cd6a6acSopenharmony_ci default: 2826cd6a6acSopenharmony_ci goto bad; 2836cd6a6acSopenharmony_ci } 2846cd6a6acSopenharmony_ci } else if (cexp->expr_type == CEXPR_ATTR) { 2856cd6a6acSopenharmony_ci if (!ebitmap_is_empty(&cexp->names)) 2866cd6a6acSopenharmony_ci goto bad; 2876cd6a6acSopenharmony_ci if (validate_empty_type_set(cexp->type_names)) 2886cd6a6acSopenharmony_ci goto bad; 2896cd6a6acSopenharmony_ci 2906cd6a6acSopenharmony_ci switch (cexp->op) { 2916cd6a6acSopenharmony_ci case CEXPR_EQ: 2926cd6a6acSopenharmony_ci case CEXPR_NEQ: 2936cd6a6acSopenharmony_ci break; 2946cd6a6acSopenharmony_ci case CEXPR_DOM: 2956cd6a6acSopenharmony_ci case CEXPR_DOMBY: 2966cd6a6acSopenharmony_ci case CEXPR_INCOMP: 2976cd6a6acSopenharmony_ci if ((cexp->attr & CEXPR_USER) || (cexp->attr & CEXPR_TYPE)) 2986cd6a6acSopenharmony_ci goto bad; 2996cd6a6acSopenharmony_ci break; 3006cd6a6acSopenharmony_ci default: 3016cd6a6acSopenharmony_ci goto bad; 3026cd6a6acSopenharmony_ci } 3036cd6a6acSopenharmony_ci 3046cd6a6acSopenharmony_ci switch (cexp->attr) { 3056cd6a6acSopenharmony_ci case CEXPR_USER: 3066cd6a6acSopenharmony_ci case CEXPR_ROLE: 3076cd6a6acSopenharmony_ci case CEXPR_TYPE: 3086cd6a6acSopenharmony_ci case CEXPR_L1L2: 3096cd6a6acSopenharmony_ci case CEXPR_L1H2: 3106cd6a6acSopenharmony_ci case CEXPR_H1L2: 3116cd6a6acSopenharmony_ci case CEXPR_H1H2: 3126cd6a6acSopenharmony_ci case CEXPR_L1H1: 3136cd6a6acSopenharmony_ci case CEXPR_L2H2: 3146cd6a6acSopenharmony_ci break; 3156cd6a6acSopenharmony_ci default: 3166cd6a6acSopenharmony_ci goto bad; 3176cd6a6acSopenharmony_ci } 3186cd6a6acSopenharmony_ci } else { 3196cd6a6acSopenharmony_ci switch (cexp->expr_type) { 3206cd6a6acSopenharmony_ci case CEXPR_NOT: 3216cd6a6acSopenharmony_ci case CEXPR_AND: 3226cd6a6acSopenharmony_ci case CEXPR_OR: 3236cd6a6acSopenharmony_ci break; 3246cd6a6acSopenharmony_ci default: 3256cd6a6acSopenharmony_ci goto bad; 3266cd6a6acSopenharmony_ci } 3276cd6a6acSopenharmony_ci 3286cd6a6acSopenharmony_ci if (cexp->op != 0) 3296cd6a6acSopenharmony_ci goto bad; 3306cd6a6acSopenharmony_ci if (cexp->attr != 0) 3316cd6a6acSopenharmony_ci goto bad; 3326cd6a6acSopenharmony_ci if (!ebitmap_is_empty(&cexp->names)) 3336cd6a6acSopenharmony_ci goto bad; 3346cd6a6acSopenharmony_ci if (validate_empty_type_set(cexp->type_names)) 3356cd6a6acSopenharmony_ci goto bad; 3366cd6a6acSopenharmony_ci } 3376cd6a6acSopenharmony_ci } 3386cd6a6acSopenharmony_ci } 3396cd6a6acSopenharmony_ci 3406cd6a6acSopenharmony_ci return 0; 3416cd6a6acSopenharmony_ci 3426cd6a6acSopenharmony_cibad: 3436cd6a6acSopenharmony_ci ERR(handle, "Invalid constraint expr"); 3446cd6a6acSopenharmony_ci return -1; 3456cd6a6acSopenharmony_ci} 3466cd6a6acSopenharmony_ci 3476cd6a6acSopenharmony_cistatic int validate_common_datum(sepol_handle_t *handle, const common_datum_t *common, validate_t flavors[]) 3486cd6a6acSopenharmony_ci{ 3496cd6a6acSopenharmony_ci if (validate_value(common->s.value, &flavors[SYM_COMMONS])) 3506cd6a6acSopenharmony_ci goto bad; 3516cd6a6acSopenharmony_ci if (common->permissions.nprim > PERM_SYMTAB_SIZE) 3526cd6a6acSopenharmony_ci goto bad; 3536cd6a6acSopenharmony_ci 3546cd6a6acSopenharmony_ci return 0; 3556cd6a6acSopenharmony_ci 3566cd6a6acSopenharmony_cibad: 3576cd6a6acSopenharmony_ci ERR(handle, "Invalid common class datum"); 3586cd6a6acSopenharmony_ci return -1; 3596cd6a6acSopenharmony_ci} 3606cd6a6acSopenharmony_ci 3616cd6a6acSopenharmony_cistatic int validate_common_datum_wrapper(__attribute__((unused)) hashtab_key_t k, hashtab_datum_t d, void *args) 3626cd6a6acSopenharmony_ci{ 3636cd6a6acSopenharmony_ci map_arg_t *margs = args; 3646cd6a6acSopenharmony_ci 3656cd6a6acSopenharmony_ci return validate_common_datum(margs->handle, d, margs->flavors); 3666cd6a6acSopenharmony_ci} 3676cd6a6acSopenharmony_ci 3686cd6a6acSopenharmony_cistatic int validate_class_datum(sepol_handle_t *handle, const class_datum_t *class, validate_t flavors[]) 3696cd6a6acSopenharmony_ci{ 3706cd6a6acSopenharmony_ci if (validate_value(class->s.value, &flavors[SYM_CLASSES])) 3716cd6a6acSopenharmony_ci goto bad; 3726cd6a6acSopenharmony_ci if (class->comdatum && validate_common_datum(handle, class->comdatum, flavors)) 3736cd6a6acSopenharmony_ci goto bad; 3746cd6a6acSopenharmony_ci if (class->permissions.nprim > PERM_SYMTAB_SIZE) 3756cd6a6acSopenharmony_ci goto bad; 3766cd6a6acSopenharmony_ci if (validate_constraint_nodes(handle, class->permissions.nprim, class->constraints, flavors)) 3776cd6a6acSopenharmony_ci goto bad; 3786cd6a6acSopenharmony_ci if (validate_constraint_nodes(handle, 0, class->validatetrans, flavors)) 3796cd6a6acSopenharmony_ci goto bad; 3806cd6a6acSopenharmony_ci 3816cd6a6acSopenharmony_ci switch (class->default_user) { 3826cd6a6acSopenharmony_ci case 0: 3836cd6a6acSopenharmony_ci case DEFAULT_SOURCE: 3846cd6a6acSopenharmony_ci case DEFAULT_TARGET: 3856cd6a6acSopenharmony_ci break; 3866cd6a6acSopenharmony_ci default: 3876cd6a6acSopenharmony_ci goto bad; 3886cd6a6acSopenharmony_ci } 3896cd6a6acSopenharmony_ci 3906cd6a6acSopenharmony_ci switch (class->default_role) { 3916cd6a6acSopenharmony_ci case 0: 3926cd6a6acSopenharmony_ci case DEFAULT_SOURCE: 3936cd6a6acSopenharmony_ci case DEFAULT_TARGET: 3946cd6a6acSopenharmony_ci break; 3956cd6a6acSopenharmony_ci default: 3966cd6a6acSopenharmony_ci goto bad; 3976cd6a6acSopenharmony_ci } 3986cd6a6acSopenharmony_ci 3996cd6a6acSopenharmony_ci switch (class->default_type) { 4006cd6a6acSopenharmony_ci case 0: 4016cd6a6acSopenharmony_ci case DEFAULT_SOURCE: 4026cd6a6acSopenharmony_ci case DEFAULT_TARGET: 4036cd6a6acSopenharmony_ci break; 4046cd6a6acSopenharmony_ci default: 4056cd6a6acSopenharmony_ci goto bad; 4066cd6a6acSopenharmony_ci } 4076cd6a6acSopenharmony_ci 4086cd6a6acSopenharmony_ci switch (class->default_range) { 4096cd6a6acSopenharmony_ci case 0: 4106cd6a6acSopenharmony_ci case DEFAULT_SOURCE_LOW: 4116cd6a6acSopenharmony_ci case DEFAULT_SOURCE_HIGH: 4126cd6a6acSopenharmony_ci case DEFAULT_SOURCE_LOW_HIGH: 4136cd6a6acSopenharmony_ci case DEFAULT_TARGET_LOW: 4146cd6a6acSopenharmony_ci case DEFAULT_TARGET_HIGH: 4156cd6a6acSopenharmony_ci case DEFAULT_TARGET_LOW_HIGH: 4166cd6a6acSopenharmony_ci case DEFAULT_GLBLUB: 4176cd6a6acSopenharmony_ci break; 4186cd6a6acSopenharmony_ci default: 4196cd6a6acSopenharmony_ci goto bad; 4206cd6a6acSopenharmony_ci } 4216cd6a6acSopenharmony_ci 4226cd6a6acSopenharmony_ci return 0; 4236cd6a6acSopenharmony_ci 4246cd6a6acSopenharmony_cibad: 4256cd6a6acSopenharmony_ci ERR(handle, "Invalid class datum"); 4266cd6a6acSopenharmony_ci return -1; 4276cd6a6acSopenharmony_ci} 4286cd6a6acSopenharmony_ci 4296cd6a6acSopenharmony_cistatic int validate_class_datum_wrapper(__attribute__((unused)) hashtab_key_t k, hashtab_datum_t d, void *args) 4306cd6a6acSopenharmony_ci{ 4316cd6a6acSopenharmony_ci map_arg_t *margs = args; 4326cd6a6acSopenharmony_ci 4336cd6a6acSopenharmony_ci return validate_class_datum(margs->handle, d, margs->flavors); 4346cd6a6acSopenharmony_ci} 4356cd6a6acSopenharmony_ci 4366cd6a6acSopenharmony_cistatic int validate_role_datum(sepol_handle_t *handle, const role_datum_t *role, validate_t flavors[]) 4376cd6a6acSopenharmony_ci{ 4386cd6a6acSopenharmony_ci if (validate_value(role->s.value, &flavors[SYM_ROLES])) 4396cd6a6acSopenharmony_ci goto bad; 4406cd6a6acSopenharmony_ci if (validate_ebitmap(&role->dominates, &flavors[SYM_ROLES])) 4416cd6a6acSopenharmony_ci goto bad; 4426cd6a6acSopenharmony_ci if (validate_type_set(&role->types, &flavors[SYM_TYPES])) 4436cd6a6acSopenharmony_ci goto bad; 4446cd6a6acSopenharmony_ci if (role->bounds && validate_value(role->bounds, &flavors[SYM_ROLES])) 4456cd6a6acSopenharmony_ci goto bad; 4466cd6a6acSopenharmony_ci if (validate_ebitmap(&role->roles, &flavors[SYM_ROLES])) 4476cd6a6acSopenharmony_ci goto bad; 4486cd6a6acSopenharmony_ci 4496cd6a6acSopenharmony_ci switch(role->flavor) { 4506cd6a6acSopenharmony_ci case ROLE_ROLE: 4516cd6a6acSopenharmony_ci case ROLE_ATTRIB: 4526cd6a6acSopenharmony_ci break; 4536cd6a6acSopenharmony_ci default: 4546cd6a6acSopenharmony_ci goto bad; 4556cd6a6acSopenharmony_ci } 4566cd6a6acSopenharmony_ci 4576cd6a6acSopenharmony_ci return 0; 4586cd6a6acSopenharmony_ci 4596cd6a6acSopenharmony_cibad: 4606cd6a6acSopenharmony_ci ERR(handle, "Invalid role datum"); 4616cd6a6acSopenharmony_ci return -1; 4626cd6a6acSopenharmony_ci} 4636cd6a6acSopenharmony_ci 4646cd6a6acSopenharmony_cistatic int validate_role_datum_wrapper(__attribute__((unused)) hashtab_key_t k, hashtab_datum_t d, void *args) 4656cd6a6acSopenharmony_ci{ 4666cd6a6acSopenharmony_ci map_arg_t *margs = args; 4676cd6a6acSopenharmony_ci 4686cd6a6acSopenharmony_ci return validate_role_datum(margs->handle, d, margs->flavors); 4696cd6a6acSopenharmony_ci} 4706cd6a6acSopenharmony_ci 4716cd6a6acSopenharmony_cistatic int validate_simpletype(uint32_t value, const policydb_t *p, validate_t flavors[]) 4726cd6a6acSopenharmony_ci{ 4736cd6a6acSopenharmony_ci const type_datum_t *type; 4746cd6a6acSopenharmony_ci 4756cd6a6acSopenharmony_ci if (validate_value(value, &flavors[SYM_TYPES])) 4766cd6a6acSopenharmony_ci goto bad; 4776cd6a6acSopenharmony_ci 4786cd6a6acSopenharmony_ci type = p->type_val_to_struct[value - 1]; 4796cd6a6acSopenharmony_ci if (!type) 4806cd6a6acSopenharmony_ci goto bad; 4816cd6a6acSopenharmony_ci 4826cd6a6acSopenharmony_ci if (type->flavor == TYPE_ATTRIB) 4836cd6a6acSopenharmony_ci goto bad; 4846cd6a6acSopenharmony_ci 4856cd6a6acSopenharmony_ci return 0; 4866cd6a6acSopenharmony_ci 4876cd6a6acSopenharmony_cibad: 4886cd6a6acSopenharmony_ci return -1; 4896cd6a6acSopenharmony_ci} 4906cd6a6acSopenharmony_ci 4916cd6a6acSopenharmony_cistatic int validate_type_datum(sepol_handle_t *handle, const type_datum_t *type, const policydb_t *p, validate_t flavors[]) 4926cd6a6acSopenharmony_ci{ 4936cd6a6acSopenharmony_ci if (validate_value(type->s.value, &flavors[SYM_TYPES])) 4946cd6a6acSopenharmony_ci goto bad; 4956cd6a6acSopenharmony_ci if (type->primary && validate_value(type->primary, &flavors[SYM_TYPES])) 4966cd6a6acSopenharmony_ci goto bad; 4976cd6a6acSopenharmony_ci 4986cd6a6acSopenharmony_ci switch (type->flavor) { 4996cd6a6acSopenharmony_ci case TYPE_TYPE: 5006cd6a6acSopenharmony_ci case TYPE_ALIAS: 5016cd6a6acSopenharmony_ci if (!ebitmap_is_empty(&type->types)) 5026cd6a6acSopenharmony_ci goto bad; 5036cd6a6acSopenharmony_ci if (type->bounds && validate_simpletype(type->bounds, p, flavors)) 5046cd6a6acSopenharmony_ci goto bad; 5056cd6a6acSopenharmony_ci break; 5066cd6a6acSopenharmony_ci case TYPE_ATTRIB: 5076cd6a6acSopenharmony_ci if (validate_ebitmap(&type->types, &flavors[SYM_TYPES])) 5086cd6a6acSopenharmony_ci goto bad; 5096cd6a6acSopenharmony_ci if (type->bounds) 5106cd6a6acSopenharmony_ci goto bad; 5116cd6a6acSopenharmony_ci break; 5126cd6a6acSopenharmony_ci default: 5136cd6a6acSopenharmony_ci goto bad; 5146cd6a6acSopenharmony_ci } 5156cd6a6acSopenharmony_ci 5166cd6a6acSopenharmony_ci switch (type->flags) { 5176cd6a6acSopenharmony_ci case 0: 5186cd6a6acSopenharmony_ci case TYPE_FLAGS_PERMISSIVE: 5196cd6a6acSopenharmony_ci case TYPE_FLAGS_EXPAND_ATTR_TRUE: 5206cd6a6acSopenharmony_ci case TYPE_FLAGS_EXPAND_ATTR_FALSE: 5216cd6a6acSopenharmony_ci case TYPE_FLAGS_EXPAND_ATTR: 5226cd6a6acSopenharmony_ci break; 5236cd6a6acSopenharmony_ci default: 5246cd6a6acSopenharmony_ci goto bad; 5256cd6a6acSopenharmony_ci } 5266cd6a6acSopenharmony_ci 5276cd6a6acSopenharmony_ci return 0; 5286cd6a6acSopenharmony_ci 5296cd6a6acSopenharmony_cibad: 5306cd6a6acSopenharmony_ci ERR(handle, "Invalid type datum"); 5316cd6a6acSopenharmony_ci return -1; 5326cd6a6acSopenharmony_ci} 5336cd6a6acSopenharmony_ci 5346cd6a6acSopenharmony_cistatic int validate_type_datum_wrapper(__attribute__((unused)) hashtab_key_t k, hashtab_datum_t d, void *args) 5356cd6a6acSopenharmony_ci{ 5366cd6a6acSopenharmony_ci map_arg_t *margs = args; 5376cd6a6acSopenharmony_ci 5386cd6a6acSopenharmony_ci return validate_type_datum(margs->handle, d, margs->policy, margs->flavors); 5396cd6a6acSopenharmony_ci} 5406cd6a6acSopenharmony_ci 5416cd6a6acSopenharmony_cistatic int validate_mls_semantic_cat(const mls_semantic_cat_t *cat, const validate_t *cats) 5426cd6a6acSopenharmony_ci{ 5436cd6a6acSopenharmony_ci for (; cat; cat = cat->next) { 5446cd6a6acSopenharmony_ci if (validate_value(cat->low, cats)) 5456cd6a6acSopenharmony_ci goto bad; 5466cd6a6acSopenharmony_ci if (validate_value(cat->high, cats)) 5476cd6a6acSopenharmony_ci goto bad; 5486cd6a6acSopenharmony_ci } 5496cd6a6acSopenharmony_ci 5506cd6a6acSopenharmony_ci return 0; 5516cd6a6acSopenharmony_ci 5526cd6a6acSopenharmony_cibad: 5536cd6a6acSopenharmony_ci return -1; 5546cd6a6acSopenharmony_ci} 5556cd6a6acSopenharmony_ci 5566cd6a6acSopenharmony_cistatic int validate_mls_semantic_level(const mls_semantic_level_t *level, const validate_t *sens, const validate_t *cats) 5576cd6a6acSopenharmony_ci{ 5586cd6a6acSopenharmony_ci if (level->sens == 0) 5596cd6a6acSopenharmony_ci return 0; 5606cd6a6acSopenharmony_ci if (validate_value(level->sens, sens)) 5616cd6a6acSopenharmony_ci goto bad; 5626cd6a6acSopenharmony_ci if (validate_mls_semantic_cat(level->cat, cats)) 5636cd6a6acSopenharmony_ci goto bad; 5646cd6a6acSopenharmony_ci 5656cd6a6acSopenharmony_ci return 0; 5666cd6a6acSopenharmony_ci 5676cd6a6acSopenharmony_cibad: 5686cd6a6acSopenharmony_ci return -1; 5696cd6a6acSopenharmony_ci} 5706cd6a6acSopenharmony_ci 5716cd6a6acSopenharmony_cistatic int validate_mls_semantic_range(const mls_semantic_range_t *range, const validate_t *sens, const validate_t *cats) 5726cd6a6acSopenharmony_ci{ 5736cd6a6acSopenharmony_ci if (validate_mls_semantic_level(&range->level[0], sens, cats)) 5746cd6a6acSopenharmony_ci goto bad; 5756cd6a6acSopenharmony_ci if (validate_mls_semantic_level(&range->level[1], sens, cats)) 5766cd6a6acSopenharmony_ci goto bad; 5776cd6a6acSopenharmony_ci 5786cd6a6acSopenharmony_ci return 0; 5796cd6a6acSopenharmony_ci 5806cd6a6acSopenharmony_cibad: 5816cd6a6acSopenharmony_ci return -1; 5826cd6a6acSopenharmony_ci} 5836cd6a6acSopenharmony_ci 5846cd6a6acSopenharmony_cistatic int validate_mls_level(const mls_level_t *level, const validate_t *sens, const validate_t *cats) 5856cd6a6acSopenharmony_ci{ 5866cd6a6acSopenharmony_ci if (validate_value(level->sens, sens)) 5876cd6a6acSopenharmony_ci goto bad; 5886cd6a6acSopenharmony_ci if (validate_ebitmap(&level->cat, cats)) 5896cd6a6acSopenharmony_ci goto bad; 5906cd6a6acSopenharmony_ci 5916cd6a6acSopenharmony_ci return 0; 5926cd6a6acSopenharmony_ci 5936cd6a6acSopenharmony_ci bad: 5946cd6a6acSopenharmony_ci return -1; 5956cd6a6acSopenharmony_ci} 5966cd6a6acSopenharmony_ci 5976cd6a6acSopenharmony_cistatic int validate_level_datum(__attribute__ ((unused)) hashtab_key_t k, hashtab_datum_t d, void *args) 5986cd6a6acSopenharmony_ci{ 5996cd6a6acSopenharmony_ci level_datum_t *level = d; 6006cd6a6acSopenharmony_ci validate_t *flavors = args; 6016cd6a6acSopenharmony_ci 6026cd6a6acSopenharmony_ci return validate_mls_level(level->level, &flavors[SYM_LEVELS], &flavors[SYM_CATS]); 6036cd6a6acSopenharmony_ci} 6046cd6a6acSopenharmony_ci 6056cd6a6acSopenharmony_cistatic int validate_mls_range(const mls_range_t *range, const validate_t *sens, const validate_t *cats) 6066cd6a6acSopenharmony_ci{ 6076cd6a6acSopenharmony_ci if (validate_mls_level(&range->level[0], sens, cats)) 6086cd6a6acSopenharmony_ci goto bad; 6096cd6a6acSopenharmony_ci if (validate_mls_level(&range->level[1], sens, cats)) 6106cd6a6acSopenharmony_ci goto bad; 6116cd6a6acSopenharmony_ci 6126cd6a6acSopenharmony_ci return 0; 6136cd6a6acSopenharmony_ci 6146cd6a6acSopenharmony_ci bad: 6156cd6a6acSopenharmony_ci return -1; 6166cd6a6acSopenharmony_ci} 6176cd6a6acSopenharmony_ci 6186cd6a6acSopenharmony_cistatic int validate_user_datum(sepol_handle_t *handle, const user_datum_t *user, validate_t flavors[], const policydb_t *p) 6196cd6a6acSopenharmony_ci{ 6206cd6a6acSopenharmony_ci if (validate_value(user->s.value, &flavors[SYM_USERS])) 6216cd6a6acSopenharmony_ci goto bad; 6226cd6a6acSopenharmony_ci if (validate_role_set(&user->roles, &flavors[SYM_ROLES])) 6236cd6a6acSopenharmony_ci goto bad; 6246cd6a6acSopenharmony_ci if (validate_mls_semantic_range(&user->range, &flavors[SYM_LEVELS], &flavors[SYM_CATS])) 6256cd6a6acSopenharmony_ci goto bad; 6266cd6a6acSopenharmony_ci if (validate_mls_semantic_level(&user->dfltlevel, &flavors[SYM_LEVELS], &flavors[SYM_CATS])) 6276cd6a6acSopenharmony_ci goto bad; 6286cd6a6acSopenharmony_ci if (p->mls && p->policy_type != POLICY_MOD && validate_mls_range(&user->exp_range, &flavors[SYM_LEVELS], &flavors[SYM_CATS])) 6296cd6a6acSopenharmony_ci goto bad; 6306cd6a6acSopenharmony_ci if (p->mls && p->policy_type != POLICY_MOD && validate_mls_level(&user->exp_dfltlevel, &flavors[SYM_LEVELS], &flavors[SYM_CATS])) 6316cd6a6acSopenharmony_ci goto bad; 6326cd6a6acSopenharmony_ci if (user->bounds && validate_value(user->bounds, &flavors[SYM_USERS])) 6336cd6a6acSopenharmony_ci goto bad; 6346cd6a6acSopenharmony_ci 6356cd6a6acSopenharmony_ci return 0; 6366cd6a6acSopenharmony_ci 6376cd6a6acSopenharmony_cibad: 6386cd6a6acSopenharmony_ci ERR(handle, "Invalid user datum"); 6396cd6a6acSopenharmony_ci return -1; 6406cd6a6acSopenharmony_ci} 6416cd6a6acSopenharmony_ci 6426cd6a6acSopenharmony_cistatic int validate_user_datum_wrapper(__attribute__((unused)) hashtab_key_t k, hashtab_datum_t d, void *args) 6436cd6a6acSopenharmony_ci{ 6446cd6a6acSopenharmony_ci map_arg_t *margs = args; 6456cd6a6acSopenharmony_ci 6466cd6a6acSopenharmony_ci return validate_user_datum(margs->handle, d, margs->flavors, margs->policy); 6476cd6a6acSopenharmony_ci} 6486cd6a6acSopenharmony_ci 6496cd6a6acSopenharmony_cistatic int validate_bool_datum(sepol_handle_t *handle, const cond_bool_datum_t *boolean, validate_t flavors[]) 6506cd6a6acSopenharmony_ci{ 6516cd6a6acSopenharmony_ci if (validate_value(boolean->s.value, &flavors[SYM_BOOLS])) 6526cd6a6acSopenharmony_ci goto bad; 6536cd6a6acSopenharmony_ci 6546cd6a6acSopenharmony_ci switch (boolean->state) { 6556cd6a6acSopenharmony_ci case 0: 6566cd6a6acSopenharmony_ci case 1: 6576cd6a6acSopenharmony_ci break; 6586cd6a6acSopenharmony_ci default: 6596cd6a6acSopenharmony_ci goto bad; 6606cd6a6acSopenharmony_ci } 6616cd6a6acSopenharmony_ci 6626cd6a6acSopenharmony_ci switch (boolean->flags) { 6636cd6a6acSopenharmony_ci case 0: 6646cd6a6acSopenharmony_ci case COND_BOOL_FLAGS_TUNABLE: 6656cd6a6acSopenharmony_ci break; 6666cd6a6acSopenharmony_ci default: 6676cd6a6acSopenharmony_ci goto bad; 6686cd6a6acSopenharmony_ci } 6696cd6a6acSopenharmony_ci 6706cd6a6acSopenharmony_ci return 0; 6716cd6a6acSopenharmony_ci 6726cd6a6acSopenharmony_cibad: 6736cd6a6acSopenharmony_ci ERR(handle, "Invalid bool datum"); 6746cd6a6acSopenharmony_ci return -1; 6756cd6a6acSopenharmony_ci} 6766cd6a6acSopenharmony_ci 6776cd6a6acSopenharmony_cistatic int validate_bool_datum_wrapper(__attribute__((unused)) hashtab_key_t k, hashtab_datum_t d, void *args) 6786cd6a6acSopenharmony_ci{ 6796cd6a6acSopenharmony_ci map_arg_t *margs = args; 6806cd6a6acSopenharmony_ci 6816cd6a6acSopenharmony_ci return validate_bool_datum(margs->handle, d, margs->flavors); 6826cd6a6acSopenharmony_ci} 6836cd6a6acSopenharmony_ci 6846cd6a6acSopenharmony_cistatic int validate_datum_array_gaps(sepol_handle_t *handle, const policydb_t *p, validate_t flavors[]) 6856cd6a6acSopenharmony_ci{ 6866cd6a6acSopenharmony_ci unsigned int i; 6876cd6a6acSopenharmony_ci 6886cd6a6acSopenharmony_ci for (i = 0; i < p->p_classes.nprim; i++) { 6896cd6a6acSopenharmony_ci if (bool_xnor(p->class_val_to_struct[i], ebitmap_get_bit(&flavors[SYM_CLASSES].gaps, i))) 6906cd6a6acSopenharmony_ci goto bad; 6916cd6a6acSopenharmony_ci } 6926cd6a6acSopenharmony_ci 6936cd6a6acSopenharmony_ci for (i = 0; i < p->p_roles.nprim; i++) { 6946cd6a6acSopenharmony_ci if (bool_xnor(p->role_val_to_struct[i], ebitmap_get_bit(&flavors[SYM_ROLES].gaps, i))) 6956cd6a6acSopenharmony_ci goto bad; 6966cd6a6acSopenharmony_ci } 6976cd6a6acSopenharmony_ci 6986cd6a6acSopenharmony_ci /* 6996cd6a6acSopenharmony_ci * For policy versions between 20 and 23, attributes exist in the policy, 7006cd6a6acSopenharmony_ci * but only in the type_attr_map, so all gaps must be assumed to be valid. 7016cd6a6acSopenharmony_ci */ 7026cd6a6acSopenharmony_ci if (p->policyvers < POLICYDB_VERSION_AVTAB || p->policyvers > POLICYDB_VERSION_PERMISSIVE) { 7036cd6a6acSopenharmony_ci for (i = 0; i < p->p_types.nprim; i++) { 7046cd6a6acSopenharmony_ci if (bool_xnor(p->type_val_to_struct[i], ebitmap_get_bit(&flavors[SYM_TYPES].gaps, i))) 7056cd6a6acSopenharmony_ci goto bad; 7066cd6a6acSopenharmony_ci } 7076cd6a6acSopenharmony_ci } 7086cd6a6acSopenharmony_ci 7096cd6a6acSopenharmony_ci for (i = 0; i < p->p_users.nprim; i++) { 7106cd6a6acSopenharmony_ci if (bool_xnor(p->user_val_to_struct[i], ebitmap_get_bit(&flavors[SYM_USERS].gaps, i))) 7116cd6a6acSopenharmony_ci goto bad; 7126cd6a6acSopenharmony_ci } 7136cd6a6acSopenharmony_ci 7146cd6a6acSopenharmony_ci for (i = 0; i < p->p_bools.nprim; i++) { 7156cd6a6acSopenharmony_ci if (bool_xnor(p->bool_val_to_struct[i], ebitmap_get_bit(&flavors[SYM_BOOLS].gaps, i))) 7166cd6a6acSopenharmony_ci goto bad; 7176cd6a6acSopenharmony_ci } 7186cd6a6acSopenharmony_ci 7196cd6a6acSopenharmony_ci return 0; 7206cd6a6acSopenharmony_ci 7216cd6a6acSopenharmony_cibad: 7226cd6a6acSopenharmony_ci ERR(handle, "Invalid datum array gaps"); 7236cd6a6acSopenharmony_ci return -1; 7246cd6a6acSopenharmony_ci} 7256cd6a6acSopenharmony_ci 7266cd6a6acSopenharmony_cistatic int validate_datum(__attribute__ ((unused))hashtab_key_t k, hashtab_datum_t d, void *args) 7276cd6a6acSopenharmony_ci{ 7286cd6a6acSopenharmony_ci symtab_datum_t *s = d; 7296cd6a6acSopenharmony_ci uint32_t *nprim = (uint32_t *)args; 7306cd6a6acSopenharmony_ci 7316cd6a6acSopenharmony_ci return !value_isvalid(s->value, *nprim); 7326cd6a6acSopenharmony_ci} 7336cd6a6acSopenharmony_ci 7346cd6a6acSopenharmony_cistatic int validate_datum_array_entries(sepol_handle_t *handle, const policydb_t *p, validate_t flavors[]) 7356cd6a6acSopenharmony_ci{ 7366cd6a6acSopenharmony_ci map_arg_t margs = { flavors, handle, p }; 7376cd6a6acSopenharmony_ci 7386cd6a6acSopenharmony_ci if (hashtab_map(p->p_commons.table, validate_common_datum_wrapper, &margs)) 7396cd6a6acSopenharmony_ci goto bad; 7406cd6a6acSopenharmony_ci 7416cd6a6acSopenharmony_ci if (hashtab_map(p->p_classes.table, validate_class_datum_wrapper, &margs)) 7426cd6a6acSopenharmony_ci goto bad; 7436cd6a6acSopenharmony_ci 7446cd6a6acSopenharmony_ci if (hashtab_map(p->p_roles.table, validate_role_datum_wrapper, &margs)) 7456cd6a6acSopenharmony_ci goto bad; 7466cd6a6acSopenharmony_ci 7476cd6a6acSopenharmony_ci if (hashtab_map(p->p_types.table, validate_type_datum_wrapper, &margs)) 7486cd6a6acSopenharmony_ci goto bad; 7496cd6a6acSopenharmony_ci 7506cd6a6acSopenharmony_ci if (hashtab_map(p->p_users.table, validate_user_datum_wrapper, &margs)) 7516cd6a6acSopenharmony_ci goto bad; 7526cd6a6acSopenharmony_ci 7536cd6a6acSopenharmony_ci if (p->mls && hashtab_map(p->p_levels.table, validate_level_datum, flavors)) 7546cd6a6acSopenharmony_ci goto bad; 7556cd6a6acSopenharmony_ci 7566cd6a6acSopenharmony_ci if (hashtab_map(p->p_cats.table, validate_datum, &flavors[SYM_CATS])) 7576cd6a6acSopenharmony_ci goto bad; 7586cd6a6acSopenharmony_ci 7596cd6a6acSopenharmony_ci if (hashtab_map(p->p_bools.table, validate_bool_datum_wrapper, &margs)) 7606cd6a6acSopenharmony_ci goto bad; 7616cd6a6acSopenharmony_ci 7626cd6a6acSopenharmony_ci return 0; 7636cd6a6acSopenharmony_ci 7646cd6a6acSopenharmony_cibad: 7656cd6a6acSopenharmony_ci ERR(handle, "Invalid datum array entries"); 7666cd6a6acSopenharmony_ci return -1; 7676cd6a6acSopenharmony_ci} 7686cd6a6acSopenharmony_ci 7696cd6a6acSopenharmony_ci/* 7706cd6a6acSopenharmony_ci * Functions to validate a kernel policydb 7716cd6a6acSopenharmony_ci */ 7726cd6a6acSopenharmony_ci 7736cd6a6acSopenharmony_cistatic int validate_avtab_key(const avtab_key_t *key, int conditional, const policydb_t *p, validate_t flavors[]) 7746cd6a6acSopenharmony_ci{ 7756cd6a6acSopenharmony_ci if (p->policy_type == POLICY_KERN && key->specified & AVTAB_TYPE) { 7766cd6a6acSopenharmony_ci if (validate_simpletype(key->source_type, p, flavors)) 7776cd6a6acSopenharmony_ci goto bad; 7786cd6a6acSopenharmony_ci if (validate_simpletype(key->target_type, p, flavors)) 7796cd6a6acSopenharmony_ci goto bad; 7806cd6a6acSopenharmony_ci } else { 7816cd6a6acSopenharmony_ci if (validate_value(key->source_type, &flavors[SYM_TYPES])) 7826cd6a6acSopenharmony_ci goto bad; 7836cd6a6acSopenharmony_ci if (validate_value(key->target_type, &flavors[SYM_TYPES])) 7846cd6a6acSopenharmony_ci goto bad; 7856cd6a6acSopenharmony_ci } 7866cd6a6acSopenharmony_ci 7876cd6a6acSopenharmony_ci if (validate_value(key->target_class, &flavors[SYM_CLASSES])) 7886cd6a6acSopenharmony_ci goto bad; 7896cd6a6acSopenharmony_ci switch (0xFFF & key->specified) { 7906cd6a6acSopenharmony_ci case AVTAB_ALLOWED: 7916cd6a6acSopenharmony_ci case AVTAB_AUDITALLOW: 7926cd6a6acSopenharmony_ci case AVTAB_AUDITDENY: 7936cd6a6acSopenharmony_ci case AVTAB_TRANSITION: 7946cd6a6acSopenharmony_ci case AVTAB_MEMBER: 7956cd6a6acSopenharmony_ci case AVTAB_CHANGE: 7966cd6a6acSopenharmony_ci break; 7976cd6a6acSopenharmony_ci case AVTAB_XPERMS_ALLOWED: 7986cd6a6acSopenharmony_ci case AVTAB_XPERMS_AUDITALLOW: 7996cd6a6acSopenharmony_ci case AVTAB_XPERMS_DONTAUDIT: 8006cd6a6acSopenharmony_ci if (conditional) 8016cd6a6acSopenharmony_ci goto bad; 8026cd6a6acSopenharmony_ci break; 8036cd6a6acSopenharmony_ci default: 8046cd6a6acSopenharmony_ci goto bad; 8056cd6a6acSopenharmony_ci } 8066cd6a6acSopenharmony_ci 8076cd6a6acSopenharmony_ci return 0; 8086cd6a6acSopenharmony_ci 8096cd6a6acSopenharmony_cibad: 8106cd6a6acSopenharmony_ci return -1; 8116cd6a6acSopenharmony_ci} 8126cd6a6acSopenharmony_ci 8136cd6a6acSopenharmony_cistatic int validate_xperms(const avtab_extended_perms_t *xperms) 8146cd6a6acSopenharmony_ci{ 8156cd6a6acSopenharmony_ci switch (xperms->specified) { 8166cd6a6acSopenharmony_ci case AVTAB_XPERMS_IOCTLDRIVER: 8176cd6a6acSopenharmony_ci case AVTAB_XPERMS_IOCTLFUNCTION: 8186cd6a6acSopenharmony_ci break; 8196cd6a6acSopenharmony_ci default: 8206cd6a6acSopenharmony_ci goto bad; 8216cd6a6acSopenharmony_ci } 8226cd6a6acSopenharmony_ci 8236cd6a6acSopenharmony_ci return 0; 8246cd6a6acSopenharmony_ci 8256cd6a6acSopenharmony_cibad: 8266cd6a6acSopenharmony_ci return -1; 8276cd6a6acSopenharmony_ci} 8286cd6a6acSopenharmony_cistatic int validate_avtab_key_and_datum(avtab_key_t *k, avtab_datum_t *d, void *args) 8296cd6a6acSopenharmony_ci{ 8306cd6a6acSopenharmony_ci map_arg_t *margs = args; 8316cd6a6acSopenharmony_ci 8326cd6a6acSopenharmony_ci if (validate_avtab_key(k, 0, margs->policy, margs->flavors)) 8336cd6a6acSopenharmony_ci return -1; 8346cd6a6acSopenharmony_ci 8356cd6a6acSopenharmony_ci if ((k->specified & AVTAB_TYPE) && validate_simpletype(d->data, margs->policy, margs->flavors)) 8366cd6a6acSopenharmony_ci return -1; 8376cd6a6acSopenharmony_ci 8386cd6a6acSopenharmony_ci if ((k->specified & AVTAB_XPERMS) && validate_xperms(d->xperms)) 8396cd6a6acSopenharmony_ci return -1; 8406cd6a6acSopenharmony_ci 8416cd6a6acSopenharmony_ci return 0; 8426cd6a6acSopenharmony_ci} 8436cd6a6acSopenharmony_ci 8446cd6a6acSopenharmony_cistatic int validate_avtab(sepol_handle_t *handle, const avtab_t *avtab, const policydb_t *p, validate_t flavors[]) 8456cd6a6acSopenharmony_ci{ 8466cd6a6acSopenharmony_ci map_arg_t margs = { flavors, handle, p }; 8476cd6a6acSopenharmony_ci 8486cd6a6acSopenharmony_ci if (avtab_map(avtab, validate_avtab_key_and_datum, &margs)) { 8496cd6a6acSopenharmony_ci ERR(handle, "Invalid avtab"); 8506cd6a6acSopenharmony_ci return -1; 8516cd6a6acSopenharmony_ci } 8526cd6a6acSopenharmony_ci 8536cd6a6acSopenharmony_ci return 0; 8546cd6a6acSopenharmony_ci} 8556cd6a6acSopenharmony_ci 8566cd6a6acSopenharmony_cistatic int validate_cond_av_list(sepol_handle_t *handle, const cond_av_list_t *cond_av, const policydb_t *p, validate_t flavors[]) 8576cd6a6acSopenharmony_ci{ 8586cd6a6acSopenharmony_ci const struct avtab_node *avtab_ptr; 8596cd6a6acSopenharmony_ci 8606cd6a6acSopenharmony_ci for (; cond_av; cond_av = cond_av->next) { 8616cd6a6acSopenharmony_ci for (avtab_ptr = cond_av->node; avtab_ptr; avtab_ptr = avtab_ptr->next) { 8626cd6a6acSopenharmony_ci if (validate_avtab_key(&avtab_ptr->key, 1, p, flavors)) { 8636cd6a6acSopenharmony_ci ERR(handle, "Invalid cond av list"); 8646cd6a6acSopenharmony_ci return -1; 8656cd6a6acSopenharmony_ci } 8666cd6a6acSopenharmony_ci } 8676cd6a6acSopenharmony_ci } 8686cd6a6acSopenharmony_ci 8696cd6a6acSopenharmony_ci return 0; 8706cd6a6acSopenharmony_ci} 8716cd6a6acSopenharmony_ci 8726cd6a6acSopenharmony_cistatic int validate_avrules(sepol_handle_t *handle, const avrule_t *avrule, int conditional, const policydb_t *p, validate_t flavors[]) 8736cd6a6acSopenharmony_ci{ 8746cd6a6acSopenharmony_ci const class_perm_node_t *classperm; 8756cd6a6acSopenharmony_ci 8766cd6a6acSopenharmony_ci for (; avrule; avrule = avrule->next) { 8776cd6a6acSopenharmony_ci if (validate_type_set(&avrule->stypes, &flavors[SYM_TYPES])) 8786cd6a6acSopenharmony_ci goto bad; 8796cd6a6acSopenharmony_ci if (validate_type_set(&avrule->ttypes, &flavors[SYM_TYPES])) 8806cd6a6acSopenharmony_ci goto bad; 8816cd6a6acSopenharmony_ci 8826cd6a6acSopenharmony_ci switch(avrule->specified) { 8836cd6a6acSopenharmony_ci case AVRULE_ALLOWED: 8846cd6a6acSopenharmony_ci case AVRULE_AUDITALLOW: 8856cd6a6acSopenharmony_ci case AVRULE_AUDITDENY: 8866cd6a6acSopenharmony_ci case AVRULE_DONTAUDIT: 8876cd6a6acSopenharmony_ci case AVRULE_TRANSITION: 8886cd6a6acSopenharmony_ci case AVRULE_MEMBER: 8896cd6a6acSopenharmony_ci case AVRULE_CHANGE: 8906cd6a6acSopenharmony_ci break; 8916cd6a6acSopenharmony_ci case AVRULE_NEVERALLOW: 8926cd6a6acSopenharmony_ci case AVRULE_XPERMS_ALLOWED: 8936cd6a6acSopenharmony_ci case AVRULE_XPERMS_AUDITALLOW: 8946cd6a6acSopenharmony_ci case AVRULE_XPERMS_DONTAUDIT: 8956cd6a6acSopenharmony_ci case AVRULE_XPERMS_NEVERALLOW: 8966cd6a6acSopenharmony_ci if (conditional) 8976cd6a6acSopenharmony_ci goto bad; 8986cd6a6acSopenharmony_ci break; 8996cd6a6acSopenharmony_ci default: 9006cd6a6acSopenharmony_ci goto bad; 9016cd6a6acSopenharmony_ci } 9026cd6a6acSopenharmony_ci 9036cd6a6acSopenharmony_ci for (classperm = avrule->perms; classperm; classperm = classperm->next) { 9046cd6a6acSopenharmony_ci if (validate_value(classperm->tclass, &flavors[SYM_CLASSES])) 9056cd6a6acSopenharmony_ci goto bad; 9066cd6a6acSopenharmony_ci if ((avrule->specified & AVRULE_TYPE) && validate_simpletype(classperm->data, p, flavors)) 9076cd6a6acSopenharmony_ci goto bad; 9086cd6a6acSopenharmony_ci } 9096cd6a6acSopenharmony_ci 9106cd6a6acSopenharmony_ci if (avrule->specified & AVRULE_XPERMS) { 9116cd6a6acSopenharmony_ci if (!avrule->xperms) 9126cd6a6acSopenharmony_ci goto bad; 9136cd6a6acSopenharmony_ci switch (avrule->xperms->specified) { 9146cd6a6acSopenharmony_ci case AVRULE_XPERMS_IOCTLFUNCTION: 9156cd6a6acSopenharmony_ci case AVRULE_XPERMS_IOCTLDRIVER: 9166cd6a6acSopenharmony_ci break; 9176cd6a6acSopenharmony_ci default: 9186cd6a6acSopenharmony_ci goto bad; 9196cd6a6acSopenharmony_ci } 9206cd6a6acSopenharmony_ci } else if (avrule->xperms) 9216cd6a6acSopenharmony_ci goto bad; 9226cd6a6acSopenharmony_ci 9236cd6a6acSopenharmony_ci switch(avrule->flags) { 9246cd6a6acSopenharmony_ci case 0: 9256cd6a6acSopenharmony_ci case RULE_SELF: 9266cd6a6acSopenharmony_ci break; 9276cd6a6acSopenharmony_ci default: 9286cd6a6acSopenharmony_ci goto bad; 9296cd6a6acSopenharmony_ci } 9306cd6a6acSopenharmony_ci } 9316cd6a6acSopenharmony_ci 9326cd6a6acSopenharmony_ci return 0; 9336cd6a6acSopenharmony_ci 9346cd6a6acSopenharmony_cibad: 9356cd6a6acSopenharmony_ci ERR(handle, "Invalid avrule"); 9366cd6a6acSopenharmony_ci return -1; 9376cd6a6acSopenharmony_ci} 9386cd6a6acSopenharmony_ci 9396cd6a6acSopenharmony_cistatic int validate_bool_id_array(sepol_handle_t *handle, const uint32_t bool_ids[], unsigned int nbools, const validate_t *boolean) 9406cd6a6acSopenharmony_ci{ 9416cd6a6acSopenharmony_ci unsigned int i; 9426cd6a6acSopenharmony_ci 9436cd6a6acSopenharmony_ci if (nbools >= COND_MAX_BOOLS) 9446cd6a6acSopenharmony_ci goto bad; 9456cd6a6acSopenharmony_ci 9466cd6a6acSopenharmony_ci for (i=0; i < nbools; i++) { 9476cd6a6acSopenharmony_ci if (validate_value(bool_ids[i], boolean)) 9486cd6a6acSopenharmony_ci goto bad; 9496cd6a6acSopenharmony_ci } 9506cd6a6acSopenharmony_ci 9516cd6a6acSopenharmony_ci return 0; 9526cd6a6acSopenharmony_ci 9536cd6a6acSopenharmony_cibad: 9546cd6a6acSopenharmony_ci ERR(handle, "Invalid bool id array"); 9556cd6a6acSopenharmony_ci return -1; 9566cd6a6acSopenharmony_ci} 9576cd6a6acSopenharmony_ci 9586cd6a6acSopenharmony_cistatic int validate_cond_expr(sepol_handle_t *handle, const struct cond_expr *expr, const validate_t *boolean) 9596cd6a6acSopenharmony_ci{ 9606cd6a6acSopenharmony_ci int depth = -1; 9616cd6a6acSopenharmony_ci 9626cd6a6acSopenharmony_ci if (!expr) 9636cd6a6acSopenharmony_ci goto bad; 9646cd6a6acSopenharmony_ci 9656cd6a6acSopenharmony_ci for (; expr; expr = expr->next) { 9666cd6a6acSopenharmony_ci switch(expr->expr_type) { 9676cd6a6acSopenharmony_ci case COND_BOOL: 9686cd6a6acSopenharmony_ci if (validate_value(expr->bool, boolean)) 9696cd6a6acSopenharmony_ci goto bad; 9706cd6a6acSopenharmony_ci if (depth == (COND_EXPR_MAXDEPTH - 1)) 9716cd6a6acSopenharmony_ci goto bad; 9726cd6a6acSopenharmony_ci depth++; 9736cd6a6acSopenharmony_ci break; 9746cd6a6acSopenharmony_ci case COND_NOT: 9756cd6a6acSopenharmony_ci if (depth < 0) 9766cd6a6acSopenharmony_ci goto bad; 9776cd6a6acSopenharmony_ci break; 9786cd6a6acSopenharmony_ci case COND_OR: 9796cd6a6acSopenharmony_ci case COND_AND: 9806cd6a6acSopenharmony_ci case COND_XOR: 9816cd6a6acSopenharmony_ci case COND_EQ: 9826cd6a6acSopenharmony_ci case COND_NEQ: 9836cd6a6acSopenharmony_ci if (depth < 1) 9846cd6a6acSopenharmony_ci goto bad; 9856cd6a6acSopenharmony_ci depth--; 9866cd6a6acSopenharmony_ci break; 9876cd6a6acSopenharmony_ci default: 9886cd6a6acSopenharmony_ci goto bad; 9896cd6a6acSopenharmony_ci } 9906cd6a6acSopenharmony_ci } 9916cd6a6acSopenharmony_ci 9926cd6a6acSopenharmony_ci if (depth != 0) 9936cd6a6acSopenharmony_ci goto bad; 9946cd6a6acSopenharmony_ci 9956cd6a6acSopenharmony_ci return 0; 9966cd6a6acSopenharmony_ci 9976cd6a6acSopenharmony_cibad: 9986cd6a6acSopenharmony_ci ERR(handle, "Invalid cond expression"); 9996cd6a6acSopenharmony_ci return -1; 10006cd6a6acSopenharmony_ci} 10016cd6a6acSopenharmony_ci 10026cd6a6acSopenharmony_cistatic int validate_cond_list(sepol_handle_t *handle, const cond_list_t *cond, const policydb_t *p, validate_t flavors[]) 10036cd6a6acSopenharmony_ci{ 10046cd6a6acSopenharmony_ci for (; cond; cond = cond->next) { 10056cd6a6acSopenharmony_ci if (validate_cond_expr(handle, cond->expr, &flavors[SYM_BOOLS])) 10066cd6a6acSopenharmony_ci goto bad; 10076cd6a6acSopenharmony_ci if (validate_cond_av_list(handle, cond->true_list, p, flavors)) 10086cd6a6acSopenharmony_ci goto bad; 10096cd6a6acSopenharmony_ci if (validate_cond_av_list(handle, cond->false_list, p, flavors)) 10106cd6a6acSopenharmony_ci goto bad; 10116cd6a6acSopenharmony_ci if (validate_avrules(handle, cond->avtrue_list, 1, p, flavors)) 10126cd6a6acSopenharmony_ci goto bad; 10136cd6a6acSopenharmony_ci if (validate_avrules(handle, cond->avfalse_list, 1, p, flavors)) 10146cd6a6acSopenharmony_ci goto bad; 10156cd6a6acSopenharmony_ci if (validate_bool_id_array(handle, cond->bool_ids, cond->nbools, &flavors[SYM_BOOLS])) 10166cd6a6acSopenharmony_ci goto bad; 10176cd6a6acSopenharmony_ci 10186cd6a6acSopenharmony_ci switch (cond->cur_state) { 10196cd6a6acSopenharmony_ci case 0: 10206cd6a6acSopenharmony_ci case 1: 10216cd6a6acSopenharmony_ci break; 10226cd6a6acSopenharmony_ci default: 10236cd6a6acSopenharmony_ci goto bad; 10246cd6a6acSopenharmony_ci } 10256cd6a6acSopenharmony_ci 10266cd6a6acSopenharmony_ci switch (cond->flags) { 10276cd6a6acSopenharmony_ci case 0: 10286cd6a6acSopenharmony_ci case COND_NODE_FLAGS_TUNABLE: 10296cd6a6acSopenharmony_ci break; 10306cd6a6acSopenharmony_ci default: 10316cd6a6acSopenharmony_ci goto bad; 10326cd6a6acSopenharmony_ci } 10336cd6a6acSopenharmony_ci } 10346cd6a6acSopenharmony_ci 10356cd6a6acSopenharmony_ci return 0; 10366cd6a6acSopenharmony_ci 10376cd6a6acSopenharmony_cibad: 10386cd6a6acSopenharmony_ci ERR(handle, "Invalid cond list"); 10396cd6a6acSopenharmony_ci return -1; 10406cd6a6acSopenharmony_ci} 10416cd6a6acSopenharmony_ci 10426cd6a6acSopenharmony_cistatic int validate_role_transes(sepol_handle_t *handle, const role_trans_t *role_trans, validate_t flavors[]) 10436cd6a6acSopenharmony_ci{ 10446cd6a6acSopenharmony_ci for (; role_trans; role_trans = role_trans->next) { 10456cd6a6acSopenharmony_ci if (validate_value(role_trans->role, &flavors[SYM_ROLES])) 10466cd6a6acSopenharmony_ci goto bad; 10476cd6a6acSopenharmony_ci if (validate_value(role_trans->type, &flavors[SYM_TYPES])) 10486cd6a6acSopenharmony_ci goto bad; 10496cd6a6acSopenharmony_ci if (validate_value(role_trans->tclass, &flavors[SYM_CLASSES])) 10506cd6a6acSopenharmony_ci goto bad; 10516cd6a6acSopenharmony_ci if (validate_value(role_trans->new_role, &flavors[SYM_ROLES])) 10526cd6a6acSopenharmony_ci goto bad; 10536cd6a6acSopenharmony_ci } 10546cd6a6acSopenharmony_ci 10556cd6a6acSopenharmony_ci return 0; 10566cd6a6acSopenharmony_ci 10576cd6a6acSopenharmony_cibad: 10586cd6a6acSopenharmony_ci ERR(handle, "Invalid role trans"); 10596cd6a6acSopenharmony_ci return -1; 10606cd6a6acSopenharmony_ci} 10616cd6a6acSopenharmony_ci 10626cd6a6acSopenharmony_cistatic int validate_role_allows(sepol_handle_t *handle, const role_allow_t *role_allow, validate_t flavors[]) 10636cd6a6acSopenharmony_ci{ 10646cd6a6acSopenharmony_ci for (; role_allow; role_allow = role_allow->next) { 10656cd6a6acSopenharmony_ci if (validate_value(role_allow->role, &flavors[SYM_ROLES])) 10666cd6a6acSopenharmony_ci goto bad; 10676cd6a6acSopenharmony_ci if (validate_value(role_allow->new_role, &flavors[SYM_ROLES])) 10686cd6a6acSopenharmony_ci goto bad; 10696cd6a6acSopenharmony_ci } 10706cd6a6acSopenharmony_ci 10716cd6a6acSopenharmony_ci return 0; 10726cd6a6acSopenharmony_ci 10736cd6a6acSopenharmony_cibad: 10746cd6a6acSopenharmony_ci ERR(handle, "Invalid role allow"); 10756cd6a6acSopenharmony_ci return -1; 10766cd6a6acSopenharmony_ci} 10776cd6a6acSopenharmony_ci 10786cd6a6acSopenharmony_cistatic int validate_filename_trans(hashtab_key_t k, hashtab_datum_t d, void *args) 10796cd6a6acSopenharmony_ci{ 10806cd6a6acSopenharmony_ci const filename_trans_key_t *ftk = (filename_trans_key_t *)k; 10816cd6a6acSopenharmony_ci const filename_trans_datum_t *ftd = d; 10826cd6a6acSopenharmony_ci validate_t *flavors = (validate_t *)args; 10836cd6a6acSopenharmony_ci 10846cd6a6acSopenharmony_ci if (validate_value(ftk->ttype, &flavors[SYM_TYPES])) 10856cd6a6acSopenharmony_ci goto bad; 10866cd6a6acSopenharmony_ci if (validate_value(ftk->tclass, &flavors[SYM_CLASSES])) 10876cd6a6acSopenharmony_ci goto bad; 10886cd6a6acSopenharmony_ci if (!ftd) 10896cd6a6acSopenharmony_ci goto bad; 10906cd6a6acSopenharmony_ci for (; ftd; ftd = ftd->next) { 10916cd6a6acSopenharmony_ci if (validate_ebitmap(&ftd->stypes, &flavors[SYM_TYPES])) 10926cd6a6acSopenharmony_ci goto bad; 10936cd6a6acSopenharmony_ci if (validate_value(ftd->otype, &flavors[SYM_TYPES])) 10946cd6a6acSopenharmony_ci goto bad; 10956cd6a6acSopenharmony_ci } 10966cd6a6acSopenharmony_ci 10976cd6a6acSopenharmony_ci return 0; 10986cd6a6acSopenharmony_ci 10996cd6a6acSopenharmony_cibad: 11006cd6a6acSopenharmony_ci return -1; 11016cd6a6acSopenharmony_ci} 11026cd6a6acSopenharmony_ci 11036cd6a6acSopenharmony_cistatic int validate_filename_trans_hashtab(sepol_handle_t *handle, hashtab_t filename_trans, validate_t flavors[]) 11046cd6a6acSopenharmony_ci{ 11056cd6a6acSopenharmony_ci if (hashtab_map(filename_trans, validate_filename_trans, flavors)) { 11066cd6a6acSopenharmony_ci ERR(handle, "Invalid filename trans"); 11076cd6a6acSopenharmony_ci return -1; 11086cd6a6acSopenharmony_ci } 11096cd6a6acSopenharmony_ci 11106cd6a6acSopenharmony_ci return 0; 11116cd6a6acSopenharmony_ci} 11126cd6a6acSopenharmony_ci 11136cd6a6acSopenharmony_cistatic int validate_context(const context_struct_t *con, validate_t flavors[], int mls) 11146cd6a6acSopenharmony_ci{ 11156cd6a6acSopenharmony_ci if (validate_value(con->user, &flavors[SYM_USERS])) 11166cd6a6acSopenharmony_ci return -1; 11176cd6a6acSopenharmony_ci if (validate_value(con->role, &flavors[SYM_ROLES])) 11186cd6a6acSopenharmony_ci return -1; 11196cd6a6acSopenharmony_ci if (validate_value(con->type, &flavors[SYM_TYPES])) 11206cd6a6acSopenharmony_ci return -1; 11216cd6a6acSopenharmony_ci if (mls && validate_mls_range(&con->range, &flavors[SYM_LEVELS], &flavors[SYM_CATS])) 11226cd6a6acSopenharmony_ci return -1; 11236cd6a6acSopenharmony_ci 11246cd6a6acSopenharmony_ci return 0; 11256cd6a6acSopenharmony_ci} 11266cd6a6acSopenharmony_ci 11276cd6a6acSopenharmony_cistatic int validate_ocontexts(sepol_handle_t *handle, const policydb_t *p, validate_t flavors[]) 11286cd6a6acSopenharmony_ci{ 11296cd6a6acSopenharmony_ci const ocontext_t *octx; 11306cd6a6acSopenharmony_ci unsigned int i; 11316cd6a6acSopenharmony_ci 11326cd6a6acSopenharmony_ci for (i = 0; i < OCON_NUM; i++) { 11336cd6a6acSopenharmony_ci for (octx = p->ocontexts[i]; octx; octx = octx->next) { 11346cd6a6acSopenharmony_ci if (validate_context(&octx->context[0], flavors, p->mls)) 11356cd6a6acSopenharmony_ci goto bad; 11366cd6a6acSopenharmony_ci 11376cd6a6acSopenharmony_ci if (p->target_platform == SEPOL_TARGET_SELINUX) { 11386cd6a6acSopenharmony_ci switch (i) { 11396cd6a6acSopenharmony_ci case OCON_FS: 11406cd6a6acSopenharmony_ci case OCON_NETIF: 11416cd6a6acSopenharmony_ci if (validate_context(&octx->context[1], flavors, p->mls)) 11426cd6a6acSopenharmony_ci goto bad; 11436cd6a6acSopenharmony_ci break; 11446cd6a6acSopenharmony_ci case OCON_PORT: 11456cd6a6acSopenharmony_ci if (octx->u.port.low_port > octx->u.port.high_port) 11466cd6a6acSopenharmony_ci goto bad; 11476cd6a6acSopenharmony_ci break; 11486cd6a6acSopenharmony_ci case OCON_FSUSE: 11496cd6a6acSopenharmony_ci switch (octx->v.behavior) { 11506cd6a6acSopenharmony_ci case SECURITY_FS_USE_XATTR: 11516cd6a6acSopenharmony_ci case SECURITY_FS_USE_TRANS: 11526cd6a6acSopenharmony_ci case SECURITY_FS_USE_TASK: 11536cd6a6acSopenharmony_ci break; 11546cd6a6acSopenharmony_ci default: 11556cd6a6acSopenharmony_ci goto bad; 11566cd6a6acSopenharmony_ci } 11576cd6a6acSopenharmony_ci } 11586cd6a6acSopenharmony_ci } 11596cd6a6acSopenharmony_ci } 11606cd6a6acSopenharmony_ci } 11616cd6a6acSopenharmony_ci 11626cd6a6acSopenharmony_ci return 0; 11636cd6a6acSopenharmony_ci 11646cd6a6acSopenharmony_cibad: 11656cd6a6acSopenharmony_ci ERR(handle, "Invalid ocontext"); 11666cd6a6acSopenharmony_ci return -1; 11676cd6a6acSopenharmony_ci} 11686cd6a6acSopenharmony_ci 11696cd6a6acSopenharmony_cistatic int validate_genfs(sepol_handle_t *handle, const policydb_t *p, validate_t flavors[]) 11706cd6a6acSopenharmony_ci{ 11716cd6a6acSopenharmony_ci const genfs_t *genfs; 11726cd6a6acSopenharmony_ci const ocontext_t *octx; 11736cd6a6acSopenharmony_ci 11746cd6a6acSopenharmony_ci for (genfs = p->genfs; genfs; genfs = genfs->next) { 11756cd6a6acSopenharmony_ci for (octx = genfs->head; octx; octx = octx->next) { 11766cd6a6acSopenharmony_ci if (validate_context(&octx->context[0], flavors, p->mls)) 11776cd6a6acSopenharmony_ci goto bad; 11786cd6a6acSopenharmony_ci if (octx->v.sclass && validate_value(octx->v.sclass, &flavors[SYM_CLASSES])) 11796cd6a6acSopenharmony_ci goto bad; 11806cd6a6acSopenharmony_ci } 11816cd6a6acSopenharmony_ci 11826cd6a6acSopenharmony_ci if (!genfs->fstype) 11836cd6a6acSopenharmony_ci goto bad; 11846cd6a6acSopenharmony_ci } 11856cd6a6acSopenharmony_ci 11866cd6a6acSopenharmony_ci return 0; 11876cd6a6acSopenharmony_ci 11886cd6a6acSopenharmony_cibad: 11896cd6a6acSopenharmony_ci ERR(handle, "Invalid genfs"); 11906cd6a6acSopenharmony_ci return -1; 11916cd6a6acSopenharmony_ci} 11926cd6a6acSopenharmony_ci 11936cd6a6acSopenharmony_ci/* 11946cd6a6acSopenharmony_ci * Functions to validate a module policydb 11956cd6a6acSopenharmony_ci */ 11966cd6a6acSopenharmony_ci 11976cd6a6acSopenharmony_cistatic int validate_role_trans_rules(sepol_handle_t *handle, const role_trans_rule_t *role_trans, validate_t flavors[]) 11986cd6a6acSopenharmony_ci{ 11996cd6a6acSopenharmony_ci for (; role_trans; role_trans = role_trans->next) { 12006cd6a6acSopenharmony_ci if (validate_role_set(&role_trans->roles, &flavors[SYM_ROLES])) 12016cd6a6acSopenharmony_ci goto bad; 12026cd6a6acSopenharmony_ci if (validate_type_set(&role_trans->types, &flavors[SYM_TYPES])) 12036cd6a6acSopenharmony_ci goto bad; 12046cd6a6acSopenharmony_ci if (validate_ebitmap(&role_trans->classes, &flavors[SYM_CLASSES])) 12056cd6a6acSopenharmony_ci goto bad; 12066cd6a6acSopenharmony_ci if (validate_value(role_trans->new_role, &flavors[SYM_ROLES])) 12076cd6a6acSopenharmony_ci goto bad; 12086cd6a6acSopenharmony_ci } 12096cd6a6acSopenharmony_ci 12106cd6a6acSopenharmony_ci return 0; 12116cd6a6acSopenharmony_ci 12126cd6a6acSopenharmony_cibad: 12136cd6a6acSopenharmony_ci ERR(handle, "Invalid role trans rule"); 12146cd6a6acSopenharmony_ci return -1; 12156cd6a6acSopenharmony_ci} 12166cd6a6acSopenharmony_ci 12176cd6a6acSopenharmony_cistatic int validate_role_allow_rules(sepol_handle_t *handle, const role_allow_rule_t *role_allow, validate_t flavors[]) 12186cd6a6acSopenharmony_ci{ 12196cd6a6acSopenharmony_ci for (; role_allow; role_allow = role_allow->next) { 12206cd6a6acSopenharmony_ci if (validate_role_set(&role_allow->roles, &flavors[SYM_ROLES])) 12216cd6a6acSopenharmony_ci goto bad; 12226cd6a6acSopenharmony_ci if (validate_role_set(&role_allow->new_roles, &flavors[SYM_ROLES])) 12236cd6a6acSopenharmony_ci goto bad; 12246cd6a6acSopenharmony_ci } 12256cd6a6acSopenharmony_ci 12266cd6a6acSopenharmony_ci return 0; 12276cd6a6acSopenharmony_ci 12286cd6a6acSopenharmony_cibad: 12296cd6a6acSopenharmony_ci ERR(handle, "Invalid role allow rule"); 12306cd6a6acSopenharmony_ci return -1; 12316cd6a6acSopenharmony_ci} 12326cd6a6acSopenharmony_ci 12336cd6a6acSopenharmony_cistatic int validate_range_trans_rules(sepol_handle_t *handle, const range_trans_rule_t *range_trans, validate_t flavors[]) 12346cd6a6acSopenharmony_ci{ 12356cd6a6acSopenharmony_ci for (; range_trans; range_trans = range_trans->next) { 12366cd6a6acSopenharmony_ci if (validate_type_set(&range_trans->stypes, &flavors[SYM_TYPES])) 12376cd6a6acSopenharmony_ci goto bad; 12386cd6a6acSopenharmony_ci if (validate_type_set(&range_trans->ttypes, &flavors[SYM_TYPES])) 12396cd6a6acSopenharmony_ci goto bad; 12406cd6a6acSopenharmony_ci if (validate_ebitmap(&range_trans->tclasses, &flavors[SYM_CLASSES])) 12416cd6a6acSopenharmony_ci goto bad; 12426cd6a6acSopenharmony_ci if (validate_mls_semantic_range(&range_trans->trange, &flavors[SYM_LEVELS], &flavors[SYM_CATS])) 12436cd6a6acSopenharmony_ci goto bad; 12446cd6a6acSopenharmony_ci } 12456cd6a6acSopenharmony_ci 12466cd6a6acSopenharmony_ci return 0; 12476cd6a6acSopenharmony_ci 12486cd6a6acSopenharmony_cibad: 12496cd6a6acSopenharmony_ci ERR(handle, "Invalid range trans rule"); 12506cd6a6acSopenharmony_ci return -1; 12516cd6a6acSopenharmony_ci} 12526cd6a6acSopenharmony_ci 12536cd6a6acSopenharmony_cistatic int validate_scope_index(sepol_handle_t *handle, const scope_index_t *scope_index, validate_t flavors[]) 12546cd6a6acSopenharmony_ci{ 12556cd6a6acSopenharmony_ci if (validate_ebitmap(&scope_index->p_classes_scope, &flavors[SYM_CLASSES])) 12566cd6a6acSopenharmony_ci goto bad; 12576cd6a6acSopenharmony_ci if (validate_ebitmap(&scope_index->p_roles_scope, &flavors[SYM_ROLES])) 12586cd6a6acSopenharmony_ci goto bad; 12596cd6a6acSopenharmony_ci if (validate_ebitmap(&scope_index->p_types_scope, &flavors[SYM_TYPES])) 12606cd6a6acSopenharmony_ci goto bad; 12616cd6a6acSopenharmony_ci if (validate_ebitmap(&scope_index->p_users_scope, &flavors[SYM_USERS])) 12626cd6a6acSopenharmony_ci goto bad; 12636cd6a6acSopenharmony_ci if (validate_ebitmap(&scope_index->p_bools_scope, &flavors[SYM_BOOLS])) 12646cd6a6acSopenharmony_ci goto bad; 12656cd6a6acSopenharmony_ci if (validate_ebitmap(&scope_index->p_sens_scope, &flavors[SYM_LEVELS])) 12666cd6a6acSopenharmony_ci goto bad; 12676cd6a6acSopenharmony_ci if (validate_ebitmap(&scope_index->p_cat_scope, &flavors[SYM_CATS])) 12686cd6a6acSopenharmony_ci goto bad; 12696cd6a6acSopenharmony_ci if (scope_index->class_perms_len > flavors[SYM_CLASSES].nprim) 12706cd6a6acSopenharmony_ci goto bad; 12716cd6a6acSopenharmony_ci 12726cd6a6acSopenharmony_ci return 0; 12736cd6a6acSopenharmony_ci 12746cd6a6acSopenharmony_cibad: 12756cd6a6acSopenharmony_ci ERR(handle, "Invalid scope"); 12766cd6a6acSopenharmony_ci return -1; 12776cd6a6acSopenharmony_ci} 12786cd6a6acSopenharmony_ci 12796cd6a6acSopenharmony_ci 12806cd6a6acSopenharmony_cistatic int validate_filename_trans_rules(sepol_handle_t *handle, const filename_trans_rule_t *filename_trans, const policydb_t *p, validate_t flavors[]) 12816cd6a6acSopenharmony_ci{ 12826cd6a6acSopenharmony_ci for (; filename_trans; filename_trans = filename_trans->next) { 12836cd6a6acSopenharmony_ci if (validate_type_set(&filename_trans->stypes, &flavors[SYM_TYPES])) 12846cd6a6acSopenharmony_ci goto bad; 12856cd6a6acSopenharmony_ci if (validate_type_set(&filename_trans->ttypes, &flavors[SYM_TYPES])) 12866cd6a6acSopenharmony_ci goto bad; 12876cd6a6acSopenharmony_ci if (validate_value(filename_trans->tclass,&flavors[SYM_CLASSES] )) 12886cd6a6acSopenharmony_ci goto bad; 12896cd6a6acSopenharmony_ci if (validate_simpletype(filename_trans->otype, p, flavors)) 12906cd6a6acSopenharmony_ci goto bad; 12916cd6a6acSopenharmony_ci 12926cd6a6acSopenharmony_ci /* currently only the RULE_SELF flag can be set */ 12936cd6a6acSopenharmony_ci if ((filename_trans->flags & ~RULE_SELF) != 0) 12946cd6a6acSopenharmony_ci goto bad; 12956cd6a6acSopenharmony_ci } 12966cd6a6acSopenharmony_ci 12976cd6a6acSopenharmony_ci return 0; 12986cd6a6acSopenharmony_ci 12996cd6a6acSopenharmony_cibad: 13006cd6a6acSopenharmony_ci ERR(handle, "Invalid filename trans rule list"); 13016cd6a6acSopenharmony_ci return -1; 13026cd6a6acSopenharmony_ci} 13036cd6a6acSopenharmony_ci 13046cd6a6acSopenharmony_cistatic int validate_symtabs(sepol_handle_t *handle, const symtab_t symtabs[], validate_t flavors[]) 13056cd6a6acSopenharmony_ci{ 13066cd6a6acSopenharmony_ci unsigned int i; 13076cd6a6acSopenharmony_ci 13086cd6a6acSopenharmony_ci for (i = 0; i < SYM_NUM; i++) { 13096cd6a6acSopenharmony_ci if (hashtab_map(symtabs[i].table, validate_datum, &flavors[i].nprim)) { 13106cd6a6acSopenharmony_ci ERR(handle, "Invalid symtab"); 13116cd6a6acSopenharmony_ci return -1; 13126cd6a6acSopenharmony_ci } 13136cd6a6acSopenharmony_ci } 13146cd6a6acSopenharmony_ci 13156cd6a6acSopenharmony_ci return 0; 13166cd6a6acSopenharmony_ci} 13176cd6a6acSopenharmony_ci 13186cd6a6acSopenharmony_cistatic int validate_avrule_blocks(sepol_handle_t *handle, const avrule_block_t *avrule_block, const policydb_t *p, validate_t flavors[]) 13196cd6a6acSopenharmony_ci{ 13206cd6a6acSopenharmony_ci const avrule_decl_t *decl; 13216cd6a6acSopenharmony_ci 13226cd6a6acSopenharmony_ci for (; avrule_block; avrule_block = avrule_block->next) { 13236cd6a6acSopenharmony_ci for (decl = avrule_block->branch_list; decl != NULL; decl = decl->next) { 13246cd6a6acSopenharmony_ci if (validate_cond_list(handle, decl->cond_list, p, flavors)) 13256cd6a6acSopenharmony_ci goto bad; 13266cd6a6acSopenharmony_ci if (validate_avrules(handle, decl->avrules, 0, p, flavors)) 13276cd6a6acSopenharmony_ci goto bad; 13286cd6a6acSopenharmony_ci if (validate_role_trans_rules(handle, decl->role_tr_rules, flavors)) 13296cd6a6acSopenharmony_ci goto bad; 13306cd6a6acSopenharmony_ci if (validate_role_allow_rules(handle, decl->role_allow_rules, flavors)) 13316cd6a6acSopenharmony_ci goto bad; 13326cd6a6acSopenharmony_ci if (validate_range_trans_rules(handle, decl->range_tr_rules, flavors)) 13336cd6a6acSopenharmony_ci goto bad; 13346cd6a6acSopenharmony_ci if (validate_scope_index(handle, &decl->required, flavors)) 13356cd6a6acSopenharmony_ci goto bad; 13366cd6a6acSopenharmony_ci if (validate_scope_index(handle, &decl->declared, flavors)) 13376cd6a6acSopenharmony_ci goto bad; 13386cd6a6acSopenharmony_ci if (validate_filename_trans_rules(handle, decl->filename_trans_rules, p, flavors)) 13396cd6a6acSopenharmony_ci goto bad; 13406cd6a6acSopenharmony_ci if (validate_symtabs(handle, decl->symtab, flavors)) 13416cd6a6acSopenharmony_ci goto bad; 13426cd6a6acSopenharmony_ci } 13436cd6a6acSopenharmony_ci 13446cd6a6acSopenharmony_ci switch (avrule_block->flags) { 13456cd6a6acSopenharmony_ci case 0: 13466cd6a6acSopenharmony_ci case AVRULE_OPTIONAL: 13476cd6a6acSopenharmony_ci break; 13486cd6a6acSopenharmony_ci default: 13496cd6a6acSopenharmony_ci goto bad; 13506cd6a6acSopenharmony_ci } 13516cd6a6acSopenharmony_ci } 13526cd6a6acSopenharmony_ci 13536cd6a6acSopenharmony_ci return 0; 13546cd6a6acSopenharmony_ci 13556cd6a6acSopenharmony_cibad: 13566cd6a6acSopenharmony_ci ERR(handle, "Invalid avrule block"); 13576cd6a6acSopenharmony_ci return -1; 13586cd6a6acSopenharmony_ci} 13596cd6a6acSopenharmony_ci 13606cd6a6acSopenharmony_cistatic int validate_permissives(sepol_handle_t *handle, const policydb_t *p, validate_t flavors[]) 13616cd6a6acSopenharmony_ci{ 13626cd6a6acSopenharmony_ci ebitmap_node_t *node; 13636cd6a6acSopenharmony_ci unsigned i; 13646cd6a6acSopenharmony_ci 13656cd6a6acSopenharmony_ci ebitmap_for_each_positive_bit(&p->permissive_map, node, i) { 13666cd6a6acSopenharmony_ci if (validate_simpletype(i, p, flavors)) 13676cd6a6acSopenharmony_ci goto bad; 13686cd6a6acSopenharmony_ci } 13696cd6a6acSopenharmony_ci 13706cd6a6acSopenharmony_ci return 0; 13716cd6a6acSopenharmony_ci 13726cd6a6acSopenharmony_cibad: 13736cd6a6acSopenharmony_ci ERR(handle, "Invalid permissive type"); 13746cd6a6acSopenharmony_ci return -1; 13756cd6a6acSopenharmony_ci} 13766cd6a6acSopenharmony_ci 13776cd6a6acSopenharmony_cistatic int validate_range_transition(hashtab_key_t key, hashtab_datum_t data, void *args) 13786cd6a6acSopenharmony_ci{ 13796cd6a6acSopenharmony_ci const range_trans_t *rt = (const range_trans_t *)key; 13806cd6a6acSopenharmony_ci const mls_range_t *r = data; 13816cd6a6acSopenharmony_ci const map_arg_t *margs = args; 13826cd6a6acSopenharmony_ci const validate_t *flavors = margs->flavors; 13836cd6a6acSopenharmony_ci 13846cd6a6acSopenharmony_ci if (validate_value(rt->source_type, &flavors[SYM_TYPES])) 13856cd6a6acSopenharmony_ci goto bad; 13866cd6a6acSopenharmony_ci if (validate_value(rt->target_type, &flavors[SYM_TYPES])) 13876cd6a6acSopenharmony_ci goto bad; 13886cd6a6acSopenharmony_ci if (validate_value(rt->target_class, &flavors[SYM_CLASSES])) 13896cd6a6acSopenharmony_ci goto bad; 13906cd6a6acSopenharmony_ci 13916cd6a6acSopenharmony_ci if (validate_mls_range(r, &flavors[SYM_LEVELS], &flavors[SYM_CATS])) 13926cd6a6acSopenharmony_ci goto bad; 13936cd6a6acSopenharmony_ci 13946cd6a6acSopenharmony_ci return 0; 13956cd6a6acSopenharmony_ci 13966cd6a6acSopenharmony_cibad: 13976cd6a6acSopenharmony_ci return -1; 13986cd6a6acSopenharmony_ci} 13996cd6a6acSopenharmony_ci 14006cd6a6acSopenharmony_cistatic int validate_range_transitions(sepol_handle_t *handle, const policydb_t *p, validate_t flavors[]) 14016cd6a6acSopenharmony_ci{ 14026cd6a6acSopenharmony_ci map_arg_t margs = { flavors, handle, p }; 14036cd6a6acSopenharmony_ci 14046cd6a6acSopenharmony_ci if (hashtab_map(p->range_tr, validate_range_transition, &margs)) { 14056cd6a6acSopenharmony_ci ERR(handle, "Invalid range transition"); 14066cd6a6acSopenharmony_ci return -1; 14076cd6a6acSopenharmony_ci } 14086cd6a6acSopenharmony_ci 14096cd6a6acSopenharmony_ci return 0; 14106cd6a6acSopenharmony_ci} 14116cd6a6acSopenharmony_ci 14126cd6a6acSopenharmony_cistatic int validate_typeattr_map(sepol_handle_t *handle, const policydb_t *p, validate_t flavors[]) 14136cd6a6acSopenharmony_ci{ 14146cd6a6acSopenharmony_ci const ebitmap_t *maps = p->type_attr_map; 14156cd6a6acSopenharmony_ci unsigned int i; 14166cd6a6acSopenharmony_ci 14176cd6a6acSopenharmony_ci if (p->policy_type == POLICY_KERN) { 14186cd6a6acSopenharmony_ci for (i = 0; i < p->p_types.nprim; i++) { 14196cd6a6acSopenharmony_ci if (validate_ebitmap(&maps[i], &flavors[SYM_TYPES])) 14206cd6a6acSopenharmony_ci goto bad; 14216cd6a6acSopenharmony_ci } 14226cd6a6acSopenharmony_ci } else if (maps) 14236cd6a6acSopenharmony_ci goto bad; 14246cd6a6acSopenharmony_ci 14256cd6a6acSopenharmony_ci return 0; 14266cd6a6acSopenharmony_ci 14276cd6a6acSopenharmony_cibad: 14286cd6a6acSopenharmony_ci ERR(handle, "Invalid type attr map"); 14296cd6a6acSopenharmony_ci return -1; 14306cd6a6acSopenharmony_ci} 14316cd6a6acSopenharmony_ci 14326cd6a6acSopenharmony_cistatic int validate_properties(sepol_handle_t *handle, const policydb_t *p) 14336cd6a6acSopenharmony_ci{ 14346cd6a6acSopenharmony_ci switch (p->policy_type) { 14356cd6a6acSopenharmony_ci case POLICY_KERN: 14366cd6a6acSopenharmony_ci if (p->policyvers < POLICYDB_VERSION_MIN || p->policyvers > POLICYDB_VERSION_MAX) 14376cd6a6acSopenharmony_ci goto bad; 14386cd6a6acSopenharmony_ci break; 14396cd6a6acSopenharmony_ci case POLICY_BASE: 14406cd6a6acSopenharmony_ci case POLICY_MOD: 14416cd6a6acSopenharmony_ci if (p->policyvers < MOD_POLICYDB_VERSION_MIN || p->policyvers > MOD_POLICYDB_VERSION_MAX) 14426cd6a6acSopenharmony_ci goto bad; 14436cd6a6acSopenharmony_ci break; 14446cd6a6acSopenharmony_ci default: 14456cd6a6acSopenharmony_ci goto bad; 14466cd6a6acSopenharmony_ci } 14476cd6a6acSopenharmony_ci 14486cd6a6acSopenharmony_ci switch (p->target_platform) { 14496cd6a6acSopenharmony_ci case SEPOL_TARGET_SELINUX: 14506cd6a6acSopenharmony_ci case SEPOL_TARGET_XEN: 14516cd6a6acSopenharmony_ci break; 14526cd6a6acSopenharmony_ci default: 14536cd6a6acSopenharmony_ci goto bad; 14546cd6a6acSopenharmony_ci } 14556cd6a6acSopenharmony_ci 14566cd6a6acSopenharmony_ci switch (p->mls) { 14576cd6a6acSopenharmony_ci case 0: 14586cd6a6acSopenharmony_ci case 1: 14596cd6a6acSopenharmony_ci break; 14606cd6a6acSopenharmony_ci default: 14616cd6a6acSopenharmony_ci goto bad; 14626cd6a6acSopenharmony_ci } 14636cd6a6acSopenharmony_ci 14646cd6a6acSopenharmony_ci switch (p->handle_unknown) { 14656cd6a6acSopenharmony_ci case SEPOL_DENY_UNKNOWN: 14666cd6a6acSopenharmony_ci case SEPOL_REJECT_UNKNOWN: 14676cd6a6acSopenharmony_ci case SEPOL_ALLOW_UNKNOWN: 14686cd6a6acSopenharmony_ci break; 14696cd6a6acSopenharmony_ci default: 14706cd6a6acSopenharmony_ci goto bad; 14716cd6a6acSopenharmony_ci } 14726cd6a6acSopenharmony_ci 14736cd6a6acSopenharmony_ci return 0; 14746cd6a6acSopenharmony_ci 14756cd6a6acSopenharmony_cibad: 14766cd6a6acSopenharmony_ci ERR(handle, "Invalid policy property"); 14776cd6a6acSopenharmony_ci return -1; 14786cd6a6acSopenharmony_ci} 14796cd6a6acSopenharmony_ci 14806cd6a6acSopenharmony_cistatic void validate_array_destroy(validate_t flavors[]) 14816cd6a6acSopenharmony_ci{ 14826cd6a6acSopenharmony_ci unsigned int i; 14836cd6a6acSopenharmony_ci 14846cd6a6acSopenharmony_ci for (i = 0; i < SYM_NUM; i++) { 14856cd6a6acSopenharmony_ci ebitmap_destroy(&flavors[i].gaps); 14866cd6a6acSopenharmony_ci } 14876cd6a6acSopenharmony_ci} 14886cd6a6acSopenharmony_ci 14896cd6a6acSopenharmony_ci/* 14906cd6a6acSopenharmony_ci * Validate policydb 14916cd6a6acSopenharmony_ci */ 14926cd6a6acSopenharmony_ciint policydb_validate(sepol_handle_t *handle, const policydb_t *p) 14936cd6a6acSopenharmony_ci{ 14946cd6a6acSopenharmony_ci validate_t flavors[SYM_NUM] = {}; 14956cd6a6acSopenharmony_ci 14966cd6a6acSopenharmony_ci if (validate_array_init(p, flavors)) 14976cd6a6acSopenharmony_ci goto bad; 14986cd6a6acSopenharmony_ci 14996cd6a6acSopenharmony_ci if (validate_properties(handle, p)) 15006cd6a6acSopenharmony_ci goto bad; 15016cd6a6acSopenharmony_ci 15026cd6a6acSopenharmony_ci if (p->policy_type == POLICY_KERN) { 15036cd6a6acSopenharmony_ci if (validate_avtab(handle, &p->te_avtab, p, flavors)) 15046cd6a6acSopenharmony_ci goto bad; 15056cd6a6acSopenharmony_ci if (p->policyvers >= POLICYDB_VERSION_BOOL) 15066cd6a6acSopenharmony_ci if (validate_cond_list(handle, p->cond_list, p, flavors)) 15076cd6a6acSopenharmony_ci goto bad; 15086cd6a6acSopenharmony_ci if (validate_role_transes(handle, p->role_tr, flavors)) 15096cd6a6acSopenharmony_ci goto bad; 15106cd6a6acSopenharmony_ci if (validate_role_allows(handle, p->role_allow, flavors)) 15116cd6a6acSopenharmony_ci goto bad; 15126cd6a6acSopenharmony_ci if (p->policyvers >= POLICYDB_VERSION_FILENAME_TRANS) 15136cd6a6acSopenharmony_ci if (validate_filename_trans_hashtab(handle, p->filename_trans, flavors)) 15146cd6a6acSopenharmony_ci goto bad; 15156cd6a6acSopenharmony_ci } else { 15166cd6a6acSopenharmony_ci if (validate_avrule_blocks(handle, p->global, p, flavors)) 15176cd6a6acSopenharmony_ci goto bad; 15186cd6a6acSopenharmony_ci } 15196cd6a6acSopenharmony_ci 15206cd6a6acSopenharmony_ci if (validate_ocontexts(handle, p, flavors)) 15216cd6a6acSopenharmony_ci goto bad; 15226cd6a6acSopenharmony_ci 15236cd6a6acSopenharmony_ci if (validate_genfs(handle, p, flavors)) 15246cd6a6acSopenharmony_ci goto bad; 15256cd6a6acSopenharmony_ci 15266cd6a6acSopenharmony_ci if (validate_scopes(handle, p->scope, p->global)) 15276cd6a6acSopenharmony_ci goto bad; 15286cd6a6acSopenharmony_ci 15296cd6a6acSopenharmony_ci if (validate_datum_array_gaps(handle, p, flavors)) 15306cd6a6acSopenharmony_ci goto bad; 15316cd6a6acSopenharmony_ci 15326cd6a6acSopenharmony_ci if (validate_datum_array_entries(handle, p, flavors)) 15336cd6a6acSopenharmony_ci goto bad; 15346cd6a6acSopenharmony_ci 15356cd6a6acSopenharmony_ci if (validate_permissives(handle, p, flavors)) 15366cd6a6acSopenharmony_ci goto bad; 15376cd6a6acSopenharmony_ci 15386cd6a6acSopenharmony_ci if (validate_range_transitions(handle, p, flavors)) 15396cd6a6acSopenharmony_ci goto bad; 15406cd6a6acSopenharmony_ci 15416cd6a6acSopenharmony_ci if (p->policyvers >= POLICYDB_VERSION_AVTAB) { 15426cd6a6acSopenharmony_ci if (validate_typeattr_map(handle, p, flavors)) 15436cd6a6acSopenharmony_ci goto bad; 15446cd6a6acSopenharmony_ci } 15456cd6a6acSopenharmony_ci 15466cd6a6acSopenharmony_ci validate_array_destroy(flavors); 15476cd6a6acSopenharmony_ci 15486cd6a6acSopenharmony_ci return 0; 15496cd6a6acSopenharmony_ci 15506cd6a6acSopenharmony_cibad: 15516cd6a6acSopenharmony_ci ERR(handle, "Invalid policydb"); 15526cd6a6acSopenharmony_ci validate_array_destroy(flavors); 15536cd6a6acSopenharmony_ci return -1; 15546cd6a6acSopenharmony_ci} 1555