16cd6a6acSopenharmony_ci 26cd6a6acSopenharmony_ci/* 36cd6a6acSopenharmony_ci * Author : Stephen Smalley, <sds@tycho.nsa.gov> 46cd6a6acSopenharmony_ci */ 56cd6a6acSopenharmony_ci 66cd6a6acSopenharmony_ci/* 76cd6a6acSopenharmony_ci * Updated: Trusted Computer Solutions, Inc. <dgoeddel@trustedcs.com> 86cd6a6acSopenharmony_ci * 96cd6a6acSopenharmony_ci * Support for enhanced MLS infrastructure. 106cd6a6acSopenharmony_ci * 116cd6a6acSopenharmony_ci * Updated: Karl MacMillan <kmacmillan@tresys.com> 126cd6a6acSopenharmony_ci * 136cd6a6acSopenharmony_ci * Added conditional policy language extensions 146cd6a6acSopenharmony_ci * 156cd6a6acSopenharmony_ci * Updated: James Morris <jmorris@intercode.com.au> 166cd6a6acSopenharmony_ci * 176cd6a6acSopenharmony_ci * Added IPv6 support. 186cd6a6acSopenharmony_ci * 196cd6a6acSopenharmony_ci * Updated: Joshua Brindle <jbrindle@tresys.com> 206cd6a6acSopenharmony_ci * Karl MacMillan <kmacmillan@tresys.com> 216cd6a6acSopenharmony_ci * Jason Tang <jtang@tresys.com> 226cd6a6acSopenharmony_ci * 236cd6a6acSopenharmony_ci * Policy Module support. 246cd6a6acSopenharmony_ci * 256cd6a6acSopenharmony_ci * Copyright (C) 2017 Mellanox Technologies Inc. 266cd6a6acSopenharmony_ci * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc. 276cd6a6acSopenharmony_ci * Copyright (C) 2003 - 2005 Tresys Technology, LLC 286cd6a6acSopenharmony_ci * Copyright (C) 2003 Red Hat, Inc., James Morris <jmorris@redhat.com> 296cd6a6acSopenharmony_ci * This program is free software; you can redistribute it and/or modify 306cd6a6acSopenharmony_ci * it under the terms of the GNU General Public License as published by 316cd6a6acSopenharmony_ci * the Free Software Foundation, version 2. 326cd6a6acSopenharmony_ci */ 336cd6a6acSopenharmony_ci 346cd6a6acSopenharmony_ci/* FLASK */ 356cd6a6acSopenharmony_ci 366cd6a6acSopenharmony_ci/* 376cd6a6acSopenharmony_ci * checkpolicy 386cd6a6acSopenharmony_ci * 396cd6a6acSopenharmony_ci * Load and check a policy configuration. 406cd6a6acSopenharmony_ci * 416cd6a6acSopenharmony_ci * A policy configuration is created in a text format, 426cd6a6acSopenharmony_ci * and then compiled into a binary format for use by 436cd6a6acSopenharmony_ci * the security server. By default, checkpolicy reads 446cd6a6acSopenharmony_ci * the text format. If '-b' is specified, then checkpolicy 456cd6a6acSopenharmony_ci * reads the binary format instead. 466cd6a6acSopenharmony_ci * 476cd6a6acSopenharmony_ci * If '-o output_file' is specified, then checkpolicy 486cd6a6acSopenharmony_ci * writes the binary format version of the configuration 496cd6a6acSopenharmony_ci * to the specified output file. 506cd6a6acSopenharmony_ci * 516cd6a6acSopenharmony_ci * If '-d' is specified, then checkpolicy permits the user 526cd6a6acSopenharmony_ci * to interactively test the security server functions with 536cd6a6acSopenharmony_ci * the loaded policy configuration. 546cd6a6acSopenharmony_ci * 556cd6a6acSopenharmony_ci * If '-c' is specified, then the supplied parameter is used to 566cd6a6acSopenharmony_ci * determine which policy version to use for generating binary 576cd6a6acSopenharmony_ci * policy. This is for compatibility with older kernels. If any 586cd6a6acSopenharmony_ci * booleans or conditional rules are thrown away a warning is printed. 596cd6a6acSopenharmony_ci */ 606cd6a6acSopenharmony_ci 616cd6a6acSopenharmony_ci#include <ctype.h> 626cd6a6acSopenharmony_ci#include <getopt.h> 636cd6a6acSopenharmony_ci#include <unistd.h> 646cd6a6acSopenharmony_ci#include <stdlib.h> 656cd6a6acSopenharmony_ci#include <sys/types.h> 666cd6a6acSopenharmony_ci#include <sys/stat.h> 676cd6a6acSopenharmony_ci#include <sys/socket.h> 686cd6a6acSopenharmony_ci#include <netinet/in.h> 696cd6a6acSopenharmony_ci#ifndef IPPROTO_DCCP 706cd6a6acSopenharmony_ci#define IPPROTO_DCCP 33 716cd6a6acSopenharmony_ci#endif 726cd6a6acSopenharmony_ci#ifndef IPPROTO_SCTP 736cd6a6acSopenharmony_ci#define IPPROTO_SCTP 132 746cd6a6acSopenharmony_ci#endif 756cd6a6acSopenharmony_ci#include <arpa/inet.h> 766cd6a6acSopenharmony_ci#include <fcntl.h> 776cd6a6acSopenharmony_ci#include <stdio.h> 786cd6a6acSopenharmony_ci#include <errno.h> 796cd6a6acSopenharmony_ci#include <sys/mman.h> 806cd6a6acSopenharmony_ci 816cd6a6acSopenharmony_ci#include <sepol/module_to_cil.h> 826cd6a6acSopenharmony_ci#include <sepol/kernel_to_cil.h> 836cd6a6acSopenharmony_ci#include <sepol/kernel_to_conf.h> 846cd6a6acSopenharmony_ci#include <sepol/policydb/policydb.h> 856cd6a6acSopenharmony_ci#include <sepol/policydb/services.h> 866cd6a6acSopenharmony_ci#include <sepol/policydb/conditional.h> 876cd6a6acSopenharmony_ci#include <sepol/policydb/hierarchy.h> 886cd6a6acSopenharmony_ci#include <sepol/policydb/expand.h> 896cd6a6acSopenharmony_ci#include <sepol/policydb/link.h> 906cd6a6acSopenharmony_ci 916cd6a6acSopenharmony_ci#include "queue.h" 926cd6a6acSopenharmony_ci#include "checkpolicy.h" 936cd6a6acSopenharmony_ci#include "parse_util.h" 946cd6a6acSopenharmony_ci 956cd6a6acSopenharmony_cistatic policydb_t policydb; 966cd6a6acSopenharmony_cistatic sidtab_t sidtab; 976cd6a6acSopenharmony_ci 986cd6a6acSopenharmony_ciextern policydb_t *policydbp; 996cd6a6acSopenharmony_ciextern int mlspol; 1006cd6a6acSopenharmony_ciextern int werror; 1016cd6a6acSopenharmony_ci 1026cd6a6acSopenharmony_cistatic int handle_unknown = SEPOL_DENY_UNKNOWN; 1036cd6a6acSopenharmony_cistatic const char *txtfile = "policy.conf"; 1046cd6a6acSopenharmony_cistatic const char *binfile = "policy"; 1056cd6a6acSopenharmony_ci 1066cd6a6acSopenharmony_ciunsigned int policyvers = 0; 1076cd6a6acSopenharmony_ci 1086cd6a6acSopenharmony_cistatic __attribute__((__noreturn__)) void usage(const char *progname) 1096cd6a6acSopenharmony_ci{ 1106cd6a6acSopenharmony_ci printf 1116cd6a6acSopenharmony_ci ("usage: %s [-b[F]] [-C] [-d] [-U handle_unknown (allow,deny,reject)] [-M] " 1126cd6a6acSopenharmony_ci "[-c policyvers (%d-%d)] [-o output_file|-] [-S] [-O] " 1136cd6a6acSopenharmony_ci "[-t target_platform (selinux,xen)] [-E] [-V] [input_file]\n", 1146cd6a6acSopenharmony_ci progname, POLICYDB_VERSION_MIN, POLICYDB_VERSION_MAX); 1156cd6a6acSopenharmony_ci exit(1); 1166cd6a6acSopenharmony_ci} 1176cd6a6acSopenharmony_ci 1186cd6a6acSopenharmony_ci#define FGETS(out, size, in) \ 1196cd6a6acSopenharmony_cido { \ 1206cd6a6acSopenharmony_ci if (fgets(out,size,in)==NULL) { \ 1216cd6a6acSopenharmony_ci fprintf(stderr, "fgets failed at line %d: %s\n", __LINE__, \ 1226cd6a6acSopenharmony_ci strerror(errno)); \ 1236cd6a6acSopenharmony_ci exit(1);\ 1246cd6a6acSopenharmony_ci } \ 1256cd6a6acSopenharmony_ci} while (0) 1266cd6a6acSopenharmony_ci 1276cd6a6acSopenharmony_cistatic int print_sid(sepol_security_id_t sid, 1286cd6a6acSopenharmony_ci context_struct_t * context 1296cd6a6acSopenharmony_ci __attribute__ ((unused)), void *data 1306cd6a6acSopenharmony_ci __attribute__ ((unused))) 1316cd6a6acSopenharmony_ci{ 1326cd6a6acSopenharmony_ci sepol_security_context_t scontext; 1336cd6a6acSopenharmony_ci size_t scontext_len; 1346cd6a6acSopenharmony_ci int rc; 1356cd6a6acSopenharmony_ci 1366cd6a6acSopenharmony_ci rc = sepol_sid_to_context(sid, &scontext, &scontext_len); 1376cd6a6acSopenharmony_ci if (rc) 1386cd6a6acSopenharmony_ci printf("sid %d -> error %d\n", sid, rc); 1396cd6a6acSopenharmony_ci else { 1406cd6a6acSopenharmony_ci printf("sid %d -> scontext %s\n", sid, scontext); 1416cd6a6acSopenharmony_ci free(scontext); 1426cd6a6acSopenharmony_ci } 1436cd6a6acSopenharmony_ci return 0; 1446cd6a6acSopenharmony_ci} 1456cd6a6acSopenharmony_ci 1466cd6a6acSopenharmony_cistruct val_to_name { 1476cd6a6acSopenharmony_ci unsigned int val; 1486cd6a6acSopenharmony_ci char *name; 1496cd6a6acSopenharmony_ci}; 1506cd6a6acSopenharmony_ci 1516cd6a6acSopenharmony_cistatic int find_perm(hashtab_key_t key, hashtab_datum_t datum, void *p) 1526cd6a6acSopenharmony_ci{ 1536cd6a6acSopenharmony_ci struct val_to_name *v = p; 1546cd6a6acSopenharmony_ci perm_datum_t *perdatum; 1556cd6a6acSopenharmony_ci 1566cd6a6acSopenharmony_ci perdatum = (perm_datum_t *) datum; 1576cd6a6acSopenharmony_ci 1586cd6a6acSopenharmony_ci if (v->val == perdatum->s.value) { 1596cd6a6acSopenharmony_ci v->name = key; 1606cd6a6acSopenharmony_ci return 1; 1616cd6a6acSopenharmony_ci } 1626cd6a6acSopenharmony_ci 1636cd6a6acSopenharmony_ci return 0; 1646cd6a6acSopenharmony_ci} 1656cd6a6acSopenharmony_ci 1666cd6a6acSopenharmony_ci#ifdef EQUIVTYPES 1676cd6a6acSopenharmony_cistatic int insert_type_rule(avtab_key_t * k, avtab_datum_t * d, 1686cd6a6acSopenharmony_ci struct avtab_node *type_rules) 1696cd6a6acSopenharmony_ci{ 1706cd6a6acSopenharmony_ci struct avtab_node *p, *c, *n; 1716cd6a6acSopenharmony_ci 1726cd6a6acSopenharmony_ci for (p = type_rules, c = type_rules->next; c; p = c, c = c->next) { 1736cd6a6acSopenharmony_ci /* 1746cd6a6acSopenharmony_ci * Find the insertion point, keeping the list 1756cd6a6acSopenharmony_ci * ordered by source type, then target type, then 1766cd6a6acSopenharmony_ci * target class. 1776cd6a6acSopenharmony_ci */ 1786cd6a6acSopenharmony_ci if (k->source_type < c->key.source_type) 1796cd6a6acSopenharmony_ci break; 1806cd6a6acSopenharmony_ci if (k->source_type == c->key.source_type && 1816cd6a6acSopenharmony_ci k->target_type < c->key.target_type) 1826cd6a6acSopenharmony_ci break; 1836cd6a6acSopenharmony_ci if (k->source_type == c->key.source_type && 1846cd6a6acSopenharmony_ci k->target_type == c->key.target_type && 1856cd6a6acSopenharmony_ci k->target_class < c->key.target_class) 1866cd6a6acSopenharmony_ci break; 1876cd6a6acSopenharmony_ci } 1886cd6a6acSopenharmony_ci 1896cd6a6acSopenharmony_ci /* Insert the rule */ 1906cd6a6acSopenharmony_ci n = malloc(sizeof(struct avtab_node)); 1916cd6a6acSopenharmony_ci if (!n) { 1926cd6a6acSopenharmony_ci fprintf(stderr, "out of memory\n"); 1936cd6a6acSopenharmony_ci exit(1); 1946cd6a6acSopenharmony_ci } 1956cd6a6acSopenharmony_ci 1966cd6a6acSopenharmony_ci n->key = *k; 1976cd6a6acSopenharmony_ci n->datum = *d; 1986cd6a6acSopenharmony_ci n->next = p->next; 1996cd6a6acSopenharmony_ci p->next = n; 2006cd6a6acSopenharmony_ci return 0; 2016cd6a6acSopenharmony_ci} 2026cd6a6acSopenharmony_ci 2036cd6a6acSopenharmony_cistatic int create_type_rules(avtab_key_t * k, avtab_datum_t * d, void *args) 2046cd6a6acSopenharmony_ci{ 2056cd6a6acSopenharmony_ci struct avtab_node *type_rules = args; 2066cd6a6acSopenharmony_ci 2076cd6a6acSopenharmony_ci if (d->specified & AVTAB_ALLOWED) { 2086cd6a6acSopenharmony_ci /* 2096cd6a6acSopenharmony_ci * Insert the rule into the lists for both 2106cd6a6acSopenharmony_ci * the source type and the target type. 2116cd6a6acSopenharmony_ci */ 2126cd6a6acSopenharmony_ci if (insert_type_rule(k, d, &type_rules[k->source_type - 1])) 2136cd6a6acSopenharmony_ci return -1; 2146cd6a6acSopenharmony_ci if (insert_type_rule(k, d, &type_rules[k->target_type - 1])) 2156cd6a6acSopenharmony_ci return -1; 2166cd6a6acSopenharmony_ci } 2176cd6a6acSopenharmony_ci 2186cd6a6acSopenharmony_ci return 0; 2196cd6a6acSopenharmony_ci} 2206cd6a6acSopenharmony_ci 2216cd6a6acSopenharmony_cistatic void free_type_rules(struct avtab_node *l) 2226cd6a6acSopenharmony_ci{ 2236cd6a6acSopenharmony_ci struct avtab_node *tmp; 2246cd6a6acSopenharmony_ci 2256cd6a6acSopenharmony_ci while (l) { 2266cd6a6acSopenharmony_ci tmp = l; 2276cd6a6acSopenharmony_ci l = l->next; 2286cd6a6acSopenharmony_ci free(tmp); 2296cd6a6acSopenharmony_ci } 2306cd6a6acSopenharmony_ci} 2316cd6a6acSopenharmony_ci 2326cd6a6acSopenharmony_cistatic int identify_equiv_types(void) 2336cd6a6acSopenharmony_ci{ 2346cd6a6acSopenharmony_ci struct avtab_node *type_rules, *l1, *l2; 2356cd6a6acSopenharmony_ci int i, j; 2366cd6a6acSopenharmony_ci 2376cd6a6acSopenharmony_ci /* 2386cd6a6acSopenharmony_ci * Create a list of access vector rules for each type 2396cd6a6acSopenharmony_ci * from the access vector table. 2406cd6a6acSopenharmony_ci */ 2416cd6a6acSopenharmony_ci type_rules = malloc(sizeof(struct avtab_node) * policydb.p_types.nprim); 2426cd6a6acSopenharmony_ci if (!type_rules) { 2436cd6a6acSopenharmony_ci fprintf(stderr, "out of memory\n"); 2446cd6a6acSopenharmony_ci exit(1); 2456cd6a6acSopenharmony_ci } 2466cd6a6acSopenharmony_ci memset(type_rules, 0, 2476cd6a6acSopenharmony_ci sizeof(struct avtab_node) * policydb.p_types.nprim); 2486cd6a6acSopenharmony_ci if (avtab_map(&policydb.te_avtab, create_type_rules, type_rules)) 2496cd6a6acSopenharmony_ci exit(1); 2506cd6a6acSopenharmony_ci 2516cd6a6acSopenharmony_ci /* 2526cd6a6acSopenharmony_ci * Compare the type lists and identify equivalent types. 2536cd6a6acSopenharmony_ci */ 2546cd6a6acSopenharmony_ci for (i = 0; i < policydb.p_types.nprim - 1; i++) { 2556cd6a6acSopenharmony_ci if (!type_rules[i].next) 2566cd6a6acSopenharmony_ci continue; 2576cd6a6acSopenharmony_ci for (j = i + 1; j < policydb.p_types.nprim; j++) { 2586cd6a6acSopenharmony_ci for (l1 = type_rules[i].next, l2 = type_rules[j].next; 2596cd6a6acSopenharmony_ci l1 && l2; l1 = l1->next, l2 = l2->next) { 2606cd6a6acSopenharmony_ci if (l2->key.source_type == (j + 1)) { 2616cd6a6acSopenharmony_ci if (l1->key.source_type != (i + 1)) 2626cd6a6acSopenharmony_ci break; 2636cd6a6acSopenharmony_ci } else { 2646cd6a6acSopenharmony_ci if (l1->key.source_type != 2656cd6a6acSopenharmony_ci l2->key.source_type) 2666cd6a6acSopenharmony_ci break; 2676cd6a6acSopenharmony_ci } 2686cd6a6acSopenharmony_ci if (l2->key.target_type == (j + 1)) { 2696cd6a6acSopenharmony_ci if (l1->key.target_type != (i + 1)) 2706cd6a6acSopenharmony_ci break; 2716cd6a6acSopenharmony_ci } else { 2726cd6a6acSopenharmony_ci if (l1->key.target_type != 2736cd6a6acSopenharmony_ci l2->key.target_type) 2746cd6a6acSopenharmony_ci break; 2756cd6a6acSopenharmony_ci } 2766cd6a6acSopenharmony_ci if (l1->key.target_class != l2->key.target_class 2776cd6a6acSopenharmony_ci || l1->datum.allowed != l2->datum.allowed) 2786cd6a6acSopenharmony_ci break; 2796cd6a6acSopenharmony_ci } 2806cd6a6acSopenharmony_ci if (l1 || l2) 2816cd6a6acSopenharmony_ci continue; 2826cd6a6acSopenharmony_ci free_type_rules(type_rules[j].next); 2836cd6a6acSopenharmony_ci type_rules[j].next = NULL; 2846cd6a6acSopenharmony_ci printf("Types %s and %s are equivalent.\n", 2856cd6a6acSopenharmony_ci policydb.p_type_val_to_name[i], 2866cd6a6acSopenharmony_ci policydb.p_type_val_to_name[j]); 2876cd6a6acSopenharmony_ci } 2886cd6a6acSopenharmony_ci free_type_rules(type_rules[i].next); 2896cd6a6acSopenharmony_ci type_rules[i].next = NULL; 2906cd6a6acSopenharmony_ci } 2916cd6a6acSopenharmony_ci 2926cd6a6acSopenharmony_ci free(type_rules); 2936cd6a6acSopenharmony_ci return 0; 2946cd6a6acSopenharmony_ci} 2956cd6a6acSopenharmony_ci#endif 2966cd6a6acSopenharmony_ci 2976cd6a6acSopenharmony_cistatic int display_bools(void) 2986cd6a6acSopenharmony_ci{ 2996cd6a6acSopenharmony_ci uint32_t i; 3006cd6a6acSopenharmony_ci 3016cd6a6acSopenharmony_ci for (i = 0; i < policydbp->p_bools.nprim; i++) { 3026cd6a6acSopenharmony_ci printf("%s : %d\n", policydbp->p_bool_val_to_name[i], 3036cd6a6acSopenharmony_ci policydbp->bool_val_to_struct[i]->state); 3046cd6a6acSopenharmony_ci } 3056cd6a6acSopenharmony_ci return 0; 3066cd6a6acSopenharmony_ci} 3076cd6a6acSopenharmony_ci 3086cd6a6acSopenharmony_cistatic void display_expr(const cond_expr_t * exp) 3096cd6a6acSopenharmony_ci{ 3106cd6a6acSopenharmony_ci 3116cd6a6acSopenharmony_ci const cond_expr_t *cur; 3126cd6a6acSopenharmony_ci for (cur = exp; cur != NULL; cur = cur->next) { 3136cd6a6acSopenharmony_ci switch (cur->expr_type) { 3146cd6a6acSopenharmony_ci case COND_BOOL: 3156cd6a6acSopenharmony_ci printf("%s ", 3166cd6a6acSopenharmony_ci policydbp->p_bool_val_to_name[cur->bool - 1]); 3176cd6a6acSopenharmony_ci break; 3186cd6a6acSopenharmony_ci case COND_NOT: 3196cd6a6acSopenharmony_ci printf("! "); 3206cd6a6acSopenharmony_ci break; 3216cd6a6acSopenharmony_ci case COND_OR: 3226cd6a6acSopenharmony_ci printf("|| "); 3236cd6a6acSopenharmony_ci break; 3246cd6a6acSopenharmony_ci case COND_AND: 3256cd6a6acSopenharmony_ci printf("&& "); 3266cd6a6acSopenharmony_ci break; 3276cd6a6acSopenharmony_ci case COND_XOR: 3286cd6a6acSopenharmony_ci printf("^ "); 3296cd6a6acSopenharmony_ci break; 3306cd6a6acSopenharmony_ci case COND_EQ: 3316cd6a6acSopenharmony_ci printf("== "); 3326cd6a6acSopenharmony_ci break; 3336cd6a6acSopenharmony_ci case COND_NEQ: 3346cd6a6acSopenharmony_ci printf("!= "); 3356cd6a6acSopenharmony_ci break; 3366cd6a6acSopenharmony_ci default: 3376cd6a6acSopenharmony_ci printf("error!"); 3386cd6a6acSopenharmony_ci break; 3396cd6a6acSopenharmony_ci } 3406cd6a6acSopenharmony_ci } 3416cd6a6acSopenharmony_ci} 3426cd6a6acSopenharmony_ci 3436cd6a6acSopenharmony_cistatic int display_cond_expressions(void) 3446cd6a6acSopenharmony_ci{ 3456cd6a6acSopenharmony_ci const cond_node_t *cur; 3466cd6a6acSopenharmony_ci 3476cd6a6acSopenharmony_ci for (cur = policydbp->cond_list; cur != NULL; cur = cur->next) { 3486cd6a6acSopenharmony_ci printf("expression: "); 3496cd6a6acSopenharmony_ci display_expr(cur->expr); 3506cd6a6acSopenharmony_ci printf("current state: %d\n", cur->cur_state); 3516cd6a6acSopenharmony_ci } 3526cd6a6acSopenharmony_ci return 0; 3536cd6a6acSopenharmony_ci} 3546cd6a6acSopenharmony_ci 3556cd6a6acSopenharmony_cistatic int change_bool(const char *name, int state) 3566cd6a6acSopenharmony_ci{ 3576cd6a6acSopenharmony_ci cond_bool_datum_t *bool; 3586cd6a6acSopenharmony_ci 3596cd6a6acSopenharmony_ci bool = hashtab_search(policydbp->p_bools.table, name); 3606cd6a6acSopenharmony_ci if (bool == NULL) { 3616cd6a6acSopenharmony_ci printf("Could not find bool %s\n", name); 3626cd6a6acSopenharmony_ci return -1; 3636cd6a6acSopenharmony_ci } 3646cd6a6acSopenharmony_ci bool->state = state; 3656cd6a6acSopenharmony_ci evaluate_conds(policydbp); 3666cd6a6acSopenharmony_ci return 0; 3676cd6a6acSopenharmony_ci} 3686cd6a6acSopenharmony_ci 3696cd6a6acSopenharmony_cistatic int check_level(hashtab_key_t key, hashtab_datum_t datum, void *arg __attribute__ ((unused))) 3706cd6a6acSopenharmony_ci{ 3716cd6a6acSopenharmony_ci level_datum_t *levdatum = (level_datum_t *) datum; 3726cd6a6acSopenharmony_ci 3736cd6a6acSopenharmony_ci if (!levdatum->isalias && !levdatum->defined) { 3746cd6a6acSopenharmony_ci fprintf(stderr, 3756cd6a6acSopenharmony_ci "Error: sensitivity %s was not used in a level definition!\n", 3766cd6a6acSopenharmony_ci key); 3776cd6a6acSopenharmony_ci return -1; 3786cd6a6acSopenharmony_ci } 3796cd6a6acSopenharmony_ci return 0; 3806cd6a6acSopenharmony_ci} 3816cd6a6acSopenharmony_ci 3826cd6a6acSopenharmony_ciint main(int argc, char **argv) 3836cd6a6acSopenharmony_ci{ 3846cd6a6acSopenharmony_ci policydb_t parse_policy; 3856cd6a6acSopenharmony_ci sepol_security_class_t tclass; 3866cd6a6acSopenharmony_ci sepol_security_id_t ssid, tsid, *sids, oldsid, newsid, tasksid; 3876cd6a6acSopenharmony_ci sepol_security_context_t scontext; 3886cd6a6acSopenharmony_ci struct sepol_av_decision avd; 3896cd6a6acSopenharmony_ci class_datum_t *cladatum; 3906cd6a6acSopenharmony_ci const char *file = txtfile; 3916cd6a6acSopenharmony_ci char ans[80 + 1], *path, *fstype; 3926cd6a6acSopenharmony_ci const char *outfile = NULL; 3936cd6a6acSopenharmony_ci size_t scontext_len, pathlen; 3946cd6a6acSopenharmony_ci unsigned int i; 3956cd6a6acSopenharmony_ci unsigned int protocol, port; 3966cd6a6acSopenharmony_ci unsigned int binary = 0, debug = 0, sort = 0, cil = 0, conf = 0, optimize = 0; 3976cd6a6acSopenharmony_ci struct val_to_name v; 3986cd6a6acSopenharmony_ci int ret, ch, fd, target = SEPOL_TARGET_SELINUX; 3996cd6a6acSopenharmony_ci unsigned int nel, uret; 4006cd6a6acSopenharmony_ci struct stat sb; 4016cd6a6acSopenharmony_ci void *map; 4026cd6a6acSopenharmony_ci FILE *outfp = NULL; 4036cd6a6acSopenharmony_ci char *name; 4046cd6a6acSopenharmony_ci int state; 4056cd6a6acSopenharmony_ci int show_version = 0; 4066cd6a6acSopenharmony_ci char *reason_buf = NULL; 4076cd6a6acSopenharmony_ci unsigned int reason; 4086cd6a6acSopenharmony_ci int flags; 4096cd6a6acSopenharmony_ci struct policy_file pf; 4106cd6a6acSopenharmony_ci const struct option long_options[] = { 4116cd6a6acSopenharmony_ci {"output", required_argument, NULL, 'o'}, 4126cd6a6acSopenharmony_ci {"target", required_argument, NULL, 't'}, 4136cd6a6acSopenharmony_ci {"binary", no_argument, NULL, 'b'}, 4146cd6a6acSopenharmony_ci {"debug", no_argument, NULL, 'd'}, 4156cd6a6acSopenharmony_ci {"version", no_argument, NULL, 'V'}, 4166cd6a6acSopenharmony_ci {"handle-unknown", required_argument, NULL, 'U'}, 4176cd6a6acSopenharmony_ci {"mls", no_argument, NULL, 'M'}, 4186cd6a6acSopenharmony_ci {"cil", no_argument, NULL, 'C'}, 4196cd6a6acSopenharmony_ci {"conf",no_argument, NULL, 'F'}, 4206cd6a6acSopenharmony_ci {"sort", no_argument, NULL, 'S'}, 4216cd6a6acSopenharmony_ci {"optimize", no_argument, NULL, 'O'}, 4226cd6a6acSopenharmony_ci {"werror", no_argument, NULL, 'E'}, 4236cd6a6acSopenharmony_ci {"help", no_argument, NULL, 'h'}, 4246cd6a6acSopenharmony_ci {NULL, 0, NULL, 0} 4256cd6a6acSopenharmony_ci }; 4266cd6a6acSopenharmony_ci 4276cd6a6acSopenharmony_ci while ((ch = getopt_long(argc, argv, "o:t:dbU:MCFSVc:OEh", long_options, NULL)) != -1) { 4286cd6a6acSopenharmony_ci switch (ch) { 4296cd6a6acSopenharmony_ci case 'o': 4306cd6a6acSopenharmony_ci outfile = optarg; 4316cd6a6acSopenharmony_ci break; 4326cd6a6acSopenharmony_ci case 't': 4336cd6a6acSopenharmony_ci if (!strcasecmp(optarg, "Xen")) 4346cd6a6acSopenharmony_ci target = SEPOL_TARGET_XEN; 4356cd6a6acSopenharmony_ci else if (!strcasecmp(optarg, "SELinux")) 4366cd6a6acSopenharmony_ci target = SEPOL_TARGET_SELINUX; 4376cd6a6acSopenharmony_ci else{ 4386cd6a6acSopenharmony_ci fprintf(stderr, "%s: Unknown target platform:" 4396cd6a6acSopenharmony_ci "%s\n", argv[0], optarg); 4406cd6a6acSopenharmony_ci exit(1); 4416cd6a6acSopenharmony_ci } 4426cd6a6acSopenharmony_ci break; 4436cd6a6acSopenharmony_ci case 'b': 4446cd6a6acSopenharmony_ci binary = 1; 4456cd6a6acSopenharmony_ci file = binfile; 4466cd6a6acSopenharmony_ci break; 4476cd6a6acSopenharmony_ci case 'd': 4486cd6a6acSopenharmony_ci debug = 1; 4496cd6a6acSopenharmony_ci break; 4506cd6a6acSopenharmony_ci case 'V': 4516cd6a6acSopenharmony_ci show_version = 1; 4526cd6a6acSopenharmony_ci break; 4536cd6a6acSopenharmony_ci case 'U': 4546cd6a6acSopenharmony_ci if (!strcasecmp(optarg, "deny")) { 4556cd6a6acSopenharmony_ci handle_unknown = DENY_UNKNOWN; 4566cd6a6acSopenharmony_ci break; 4576cd6a6acSopenharmony_ci } 4586cd6a6acSopenharmony_ci if (!strcasecmp(optarg, "allow")) { 4596cd6a6acSopenharmony_ci handle_unknown = ALLOW_UNKNOWN; 4606cd6a6acSopenharmony_ci break; 4616cd6a6acSopenharmony_ci } 4626cd6a6acSopenharmony_ci if (!strcasecmp(optarg, "reject")) { 4636cd6a6acSopenharmony_ci handle_unknown = REJECT_UNKNOWN; 4646cd6a6acSopenharmony_ci break; 4656cd6a6acSopenharmony_ci } 4666cd6a6acSopenharmony_ci usage(argv[0]); 4676cd6a6acSopenharmony_ci case 'S': 4686cd6a6acSopenharmony_ci sort = 1; 4696cd6a6acSopenharmony_ci break; 4706cd6a6acSopenharmony_ci case 'O': 4716cd6a6acSopenharmony_ci optimize = 1; 4726cd6a6acSopenharmony_ci break; 4736cd6a6acSopenharmony_ci case 'M': 4746cd6a6acSopenharmony_ci mlspol = 1; 4756cd6a6acSopenharmony_ci break; 4766cd6a6acSopenharmony_ci case 'C': 4776cd6a6acSopenharmony_ci cil = 1; 4786cd6a6acSopenharmony_ci break; 4796cd6a6acSopenharmony_ci case 'F': 4806cd6a6acSopenharmony_ci conf = 1; 4816cd6a6acSopenharmony_ci break; 4826cd6a6acSopenharmony_ci case 'c':{ 4836cd6a6acSopenharmony_ci long int n; 4846cd6a6acSopenharmony_ci errno = 0; 4856cd6a6acSopenharmony_ci n = strtol(optarg, NULL, 10); 4866cd6a6acSopenharmony_ci if (errno) { 4876cd6a6acSopenharmony_ci fprintf(stderr, 4886cd6a6acSopenharmony_ci "Invalid policyvers specified: %s\n", 4896cd6a6acSopenharmony_ci optarg); 4906cd6a6acSopenharmony_ci usage(argv[0]); 4916cd6a6acSopenharmony_ci exit(1); 4926cd6a6acSopenharmony_ci } 4936cd6a6acSopenharmony_ci if (n < POLICYDB_VERSION_MIN 4946cd6a6acSopenharmony_ci || n > POLICYDB_VERSION_MAX) { 4956cd6a6acSopenharmony_ci fprintf(stderr, 4966cd6a6acSopenharmony_ci "policyvers value %ld not in range %d-%d\n", 4976cd6a6acSopenharmony_ci n, POLICYDB_VERSION_MIN, 4986cd6a6acSopenharmony_ci POLICYDB_VERSION_MAX); 4996cd6a6acSopenharmony_ci usage(argv[0]); 5006cd6a6acSopenharmony_ci exit(1); 5016cd6a6acSopenharmony_ci } 5026cd6a6acSopenharmony_ci policyvers = n; 5036cd6a6acSopenharmony_ci break; 5046cd6a6acSopenharmony_ci } 5056cd6a6acSopenharmony_ci case 'E': 5066cd6a6acSopenharmony_ci werror = 1; 5076cd6a6acSopenharmony_ci break; 5086cd6a6acSopenharmony_ci case 'h': 5096cd6a6acSopenharmony_ci default: 5106cd6a6acSopenharmony_ci usage(argv[0]); 5116cd6a6acSopenharmony_ci } 5126cd6a6acSopenharmony_ci } 5136cd6a6acSopenharmony_ci 5146cd6a6acSopenharmony_ci if (show_version) { 5156cd6a6acSopenharmony_ci printf("%d (compatibility range %d-%d)\n", 5166cd6a6acSopenharmony_ci policyvers ? policyvers : POLICYDB_VERSION_MAX , 5176cd6a6acSopenharmony_ci POLICYDB_VERSION_MAX, POLICYDB_VERSION_MIN); 5186cd6a6acSopenharmony_ci exit(0); 5196cd6a6acSopenharmony_ci } 5206cd6a6acSopenharmony_ci 5216cd6a6acSopenharmony_ci if (optind != argc) { 5226cd6a6acSopenharmony_ci file = argv[optind++]; 5236cd6a6acSopenharmony_ci if (optind != argc) 5246cd6a6acSopenharmony_ci usage(argv[0]); 5256cd6a6acSopenharmony_ci } 5266cd6a6acSopenharmony_ci /* Set policydb and sidtab used by libsepol service functions 5276cd6a6acSopenharmony_ci to my structures, so that I can directly populate and 5286cd6a6acSopenharmony_ci manipulate them. */ 5296cd6a6acSopenharmony_ci sepol_set_policydb(&policydb); 5306cd6a6acSopenharmony_ci sepol_set_sidtab(&sidtab); 5316cd6a6acSopenharmony_ci 5326cd6a6acSopenharmony_ci if (cil && conf) { 5336cd6a6acSopenharmony_ci fprintf(stderr, "Can't convert to CIL and policy.conf at the same time\n"); 5346cd6a6acSopenharmony_ci exit(1); 5356cd6a6acSopenharmony_ci } 5366cd6a6acSopenharmony_ci 5376cd6a6acSopenharmony_ci if (binary) { 5386cd6a6acSopenharmony_ci fd = open(file, O_RDONLY); 5396cd6a6acSopenharmony_ci if (fd < 0) { 5406cd6a6acSopenharmony_ci fprintf(stderr, "Can't open '%s': %s\n", 5416cd6a6acSopenharmony_ci file, strerror(errno)); 5426cd6a6acSopenharmony_ci exit(1); 5436cd6a6acSopenharmony_ci } 5446cd6a6acSopenharmony_ci if (fstat(fd, &sb) < 0) { 5456cd6a6acSopenharmony_ci fprintf(stderr, "Can't stat '%s': %s\n", 5466cd6a6acSopenharmony_ci file, strerror(errno)); 5476cd6a6acSopenharmony_ci exit(1); 5486cd6a6acSopenharmony_ci } 5496cd6a6acSopenharmony_ci map = 5506cd6a6acSopenharmony_ci mmap(NULL, sb.st_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, 5516cd6a6acSopenharmony_ci fd, 0); 5526cd6a6acSopenharmony_ci if (map == MAP_FAILED) { 5536cd6a6acSopenharmony_ci fprintf(stderr, "Can't map '%s': %s\n", 5546cd6a6acSopenharmony_ci file, strerror(errno)); 5556cd6a6acSopenharmony_ci exit(1); 5566cd6a6acSopenharmony_ci } 5576cd6a6acSopenharmony_ci policy_file_init(&pf); 5586cd6a6acSopenharmony_ci pf.type = PF_USE_MEMORY; 5596cd6a6acSopenharmony_ci pf.data = map; 5606cd6a6acSopenharmony_ci pf.len = sb.st_size; 5616cd6a6acSopenharmony_ci if (policydb_init(&policydb)) { 5626cd6a6acSopenharmony_ci fprintf(stderr, "%s: policydb_init: Out of memory!\n", 5636cd6a6acSopenharmony_ci argv[0]); 5646cd6a6acSopenharmony_ci exit(1); 5656cd6a6acSopenharmony_ci } 5666cd6a6acSopenharmony_ci ret = policydb_read(&policydb, &pf, 1); 5676cd6a6acSopenharmony_ci if (ret) { 5686cd6a6acSopenharmony_ci fprintf(stderr, 5696cd6a6acSopenharmony_ci "%s: error(s) encountered while parsing configuration\n", 5706cd6a6acSopenharmony_ci argv[0]); 5716cd6a6acSopenharmony_ci exit(1); 5726cd6a6acSopenharmony_ci } 5736cd6a6acSopenharmony_ci policydbp = &policydb; 5746cd6a6acSopenharmony_ci 5756cd6a6acSopenharmony_ci /* Check Policy Consistency */ 5766cd6a6acSopenharmony_ci if (policydbp->mls) { 5776cd6a6acSopenharmony_ci if (!mlspol) { 5786cd6a6acSopenharmony_ci fprintf(stderr, "%s: MLS policy, but non-MLS" 5796cd6a6acSopenharmony_ci " is specified\n", argv[0]); 5806cd6a6acSopenharmony_ci exit(1); 5816cd6a6acSopenharmony_ci } 5826cd6a6acSopenharmony_ci } else { 5836cd6a6acSopenharmony_ci if (mlspol) { 5846cd6a6acSopenharmony_ci fprintf(stderr, "%s: non-MLS policy, but MLS" 5856cd6a6acSopenharmony_ci " is specified\n", argv[0]); 5866cd6a6acSopenharmony_ci exit(1); 5876cd6a6acSopenharmony_ci } 5886cd6a6acSopenharmony_ci } 5896cd6a6acSopenharmony_ci 5906cd6a6acSopenharmony_ci if (policydbp->policyvers <= POLICYDB_VERSION_PERMISSIVE) { 5916cd6a6acSopenharmony_ci if (policyvers > policydbp->policyvers) { 5926cd6a6acSopenharmony_ci fprintf(stderr, "Binary policies with version <= %u cannot be upgraded\n", POLICYDB_VERSION_PERMISSIVE); 5936cd6a6acSopenharmony_ci } else if (policyvers) { 5946cd6a6acSopenharmony_ci policydbp->policyvers = policyvers; 5956cd6a6acSopenharmony_ci } 5966cd6a6acSopenharmony_ci } else { 5976cd6a6acSopenharmony_ci policydbp->policyvers = policyvers ? policyvers : POLICYDB_VERSION_MAX; 5986cd6a6acSopenharmony_ci } 5996cd6a6acSopenharmony_ci } else { 6006cd6a6acSopenharmony_ci if (conf) { 6016cd6a6acSopenharmony_ci fprintf(stderr, "Can only generate policy.conf from binary policy\n"); 6026cd6a6acSopenharmony_ci exit(1); 6036cd6a6acSopenharmony_ci } 6046cd6a6acSopenharmony_ci if (policydb_init(&parse_policy)) 6056cd6a6acSopenharmony_ci exit(1); 6066cd6a6acSopenharmony_ci /* We build this as a base policy first since that is all the parser understands */ 6076cd6a6acSopenharmony_ci parse_policy.policy_type = POLICY_BASE; 6086cd6a6acSopenharmony_ci policydb_set_target_platform(&parse_policy, target); 6096cd6a6acSopenharmony_ci 6106cd6a6acSopenharmony_ci /* Let sepol know if we are dealing with MLS support */ 6116cd6a6acSopenharmony_ci parse_policy.mls = mlspol; 6126cd6a6acSopenharmony_ci parse_policy.handle_unknown = handle_unknown; 6136cd6a6acSopenharmony_ci 6146cd6a6acSopenharmony_ci policydbp = &parse_policy; 6156cd6a6acSopenharmony_ci 6166cd6a6acSopenharmony_ci if (read_source_policy(policydbp, file, "checkpolicy") < 0) 6176cd6a6acSopenharmony_ci exit(1); 6186cd6a6acSopenharmony_ci 6196cd6a6acSopenharmony_ci if (hashtab_map(policydbp->p_levels.table, check_level, NULL)) 6206cd6a6acSopenharmony_ci exit(1); 6216cd6a6acSopenharmony_ci 6226cd6a6acSopenharmony_ci /* Linking takes care of optional avrule blocks */ 6236cd6a6acSopenharmony_ci if (link_modules(NULL, policydbp, NULL, 0, 0)) { 6246cd6a6acSopenharmony_ci fprintf(stderr, "Error while resolving optionals\n"); 6256cd6a6acSopenharmony_ci exit(1); 6266cd6a6acSopenharmony_ci } 6276cd6a6acSopenharmony_ci 6286cd6a6acSopenharmony_ci if (!cil) { 6296cd6a6acSopenharmony_ci if (policydb_init(&policydb)) { 6306cd6a6acSopenharmony_ci fprintf(stderr, "%s: policydb_init failed\n", argv[0]); 6316cd6a6acSopenharmony_ci exit(1); 6326cd6a6acSopenharmony_ci } 6336cd6a6acSopenharmony_ci if (expand_module(NULL, policydbp, &policydb, 0, 1)) { 6346cd6a6acSopenharmony_ci fprintf(stderr, "Error while expanding policy\n"); 6356cd6a6acSopenharmony_ci exit(1); 6366cd6a6acSopenharmony_ci } 6376cd6a6acSopenharmony_ci policydb_destroy(policydbp); 6386cd6a6acSopenharmony_ci policydbp = &policydb; 6396cd6a6acSopenharmony_ci } 6406cd6a6acSopenharmony_ci 6416cd6a6acSopenharmony_ci policydbp->policyvers = policyvers ? policyvers : POLICYDB_VERSION_MAX; 6426cd6a6acSopenharmony_ci } 6436cd6a6acSopenharmony_ci 6446cd6a6acSopenharmony_ci if (policydb_load_isids(&policydb, &sidtab)) 6456cd6a6acSopenharmony_ci exit(1); 6466cd6a6acSopenharmony_ci 6476cd6a6acSopenharmony_ci if (optimize && policydbp->policy_type == POLICY_KERN) { 6486cd6a6acSopenharmony_ci ret = policydb_optimize(policydbp); 6496cd6a6acSopenharmony_ci if (ret) { 6506cd6a6acSopenharmony_ci fprintf(stderr, "%s: error optimizing policy\n", argv[0]); 6516cd6a6acSopenharmony_ci exit(1); 6526cd6a6acSopenharmony_ci } 6536cd6a6acSopenharmony_ci } 6546cd6a6acSopenharmony_ci 6556cd6a6acSopenharmony_ci if (outfile) { 6566cd6a6acSopenharmony_ci if (!strcmp(outfile, "-")) { 6576cd6a6acSopenharmony_ci outfp = stdout; 6586cd6a6acSopenharmony_ci outfile = "<STDOUT>"; 6596cd6a6acSopenharmony_ci } else { 6606cd6a6acSopenharmony_ci outfp = fopen(outfile, "w"); 6616cd6a6acSopenharmony_ci if (!outfp) { 6626cd6a6acSopenharmony_ci perror(outfile); 6636cd6a6acSopenharmony_ci exit(1); 6646cd6a6acSopenharmony_ci } 6656cd6a6acSopenharmony_ci } 6666cd6a6acSopenharmony_ci 6676cd6a6acSopenharmony_ci if (!cil) { 6686cd6a6acSopenharmony_ci if (!conf) { 6696cd6a6acSopenharmony_ci policydb.policy_type = POLICY_KERN; 6706cd6a6acSopenharmony_ci 6716cd6a6acSopenharmony_ci policy_file_init(&pf); 6726cd6a6acSopenharmony_ci pf.type = PF_USE_STDIO; 6736cd6a6acSopenharmony_ci pf.fp = outfp; 6746cd6a6acSopenharmony_ci if (sort) { 6756cd6a6acSopenharmony_ci ret = policydb_sort_ocontexts(&policydb); 6766cd6a6acSopenharmony_ci if (ret) { 6776cd6a6acSopenharmony_ci fprintf(stderr, "%s: error sorting ocontexts\n", 6786cd6a6acSopenharmony_ci argv[0]); 6796cd6a6acSopenharmony_ci exit(1); 6806cd6a6acSopenharmony_ci } 6816cd6a6acSopenharmony_ci } 6826cd6a6acSopenharmony_ci ret = policydb_write(&policydb, &pf); 6836cd6a6acSopenharmony_ci } else { 6846cd6a6acSopenharmony_ci ret = sepol_kernel_policydb_to_conf(outfp, policydbp); 6856cd6a6acSopenharmony_ci } 6866cd6a6acSopenharmony_ci if (ret) { 6876cd6a6acSopenharmony_ci fprintf(stderr, "%s: error writing %s\n", 6886cd6a6acSopenharmony_ci argv[0], outfile); 6896cd6a6acSopenharmony_ci exit(1); 6906cd6a6acSopenharmony_ci } 6916cd6a6acSopenharmony_ci } else { 6926cd6a6acSopenharmony_ci if (binary) { 6936cd6a6acSopenharmony_ci ret = sepol_kernel_policydb_to_cil(outfp, policydbp); 6946cd6a6acSopenharmony_ci } else { 6956cd6a6acSopenharmony_ci ret = sepol_module_policydb_to_cil(outfp, policydbp, 1); 6966cd6a6acSopenharmony_ci } 6976cd6a6acSopenharmony_ci if (ret) { 6986cd6a6acSopenharmony_ci fprintf(stderr, "%s: error writing %s\n", argv[0], outfile); 6996cd6a6acSopenharmony_ci exit(1); 7006cd6a6acSopenharmony_ci } 7016cd6a6acSopenharmony_ci } 7026cd6a6acSopenharmony_ci 7036cd6a6acSopenharmony_ci if (outfp != stdout) { 7046cd6a6acSopenharmony_ci if(fclose(outfp)) { 7056cd6a6acSopenharmony_ci fprintf(stderr, "%s: error closing %s: %s\n", argv[0], outfile, strerror(errno)); 7066cd6a6acSopenharmony_ci exit(1); 7076cd6a6acSopenharmony_ci } 7086cd6a6acSopenharmony_ci } 7096cd6a6acSopenharmony_ci } else if (cil) { 7106cd6a6acSopenharmony_ci fprintf(stderr, "%s: No file to write CIL was specified\n", argv[0]); 7116cd6a6acSopenharmony_ci exit(1); 7126cd6a6acSopenharmony_ci } 7136cd6a6acSopenharmony_ci 7146cd6a6acSopenharmony_ci if (!debug) { 7156cd6a6acSopenharmony_ci policydb_destroy(&policydb); 7166cd6a6acSopenharmony_ci sepol_sidtab_destroy(&sidtab); 7176cd6a6acSopenharmony_ci exit(0); 7186cd6a6acSopenharmony_ci } 7196cd6a6acSopenharmony_ci 7206cd6a6acSopenharmony_ci menu: 7216cd6a6acSopenharmony_ci printf("\nSelect an option:\n"); 7226cd6a6acSopenharmony_ci printf("0) Call compute_access_vector\n"); 7236cd6a6acSopenharmony_ci printf("1) Call sid_to_context\n"); 7246cd6a6acSopenharmony_ci printf("2) Call context_to_sid\n"); 7256cd6a6acSopenharmony_ci printf("3) Call transition_sid\n"); 7266cd6a6acSopenharmony_ci printf("4) Call member_sid\n"); 7276cd6a6acSopenharmony_ci printf("5) Call change_sid\n"); 7286cd6a6acSopenharmony_ci printf("6) Call list_sids\n"); 7296cd6a6acSopenharmony_ci printf("7) Call load_policy\n"); 7306cd6a6acSopenharmony_ci printf("8) Call fs_sid\n"); 7316cd6a6acSopenharmony_ci printf("9) Call port_sid\n"); 7326cd6a6acSopenharmony_ci printf("a) Call netif_sid\n"); 7336cd6a6acSopenharmony_ci printf("b) Call node_sid\n"); 7346cd6a6acSopenharmony_ci printf("c) Call fs_use\n"); 7356cd6a6acSopenharmony_ci printf("d) Call genfs_sid\n"); 7366cd6a6acSopenharmony_ci printf("e) Call get_user_sids\n"); 7376cd6a6acSopenharmony_ci printf("f) display conditional bools\n"); 7386cd6a6acSopenharmony_ci printf("g) display conditional expressions\n"); 7396cd6a6acSopenharmony_ci printf("h) change a boolean value\n"); 7406cd6a6acSopenharmony_ci printf("i) display constraint expressions\n"); 7416cd6a6acSopenharmony_ci printf("j) display validatetrans expressions\n"); 7426cd6a6acSopenharmony_ci printf("k) Call ibpkey_sid\n"); 7436cd6a6acSopenharmony_ci printf("l) Call ibendport_sid\n"); 7446cd6a6acSopenharmony_ci#ifdef EQUIVTYPES 7456cd6a6acSopenharmony_ci printf("z) Show equivalent types\n"); 7466cd6a6acSopenharmony_ci#endif 7476cd6a6acSopenharmony_ci printf("m) Show menu again\n"); 7486cd6a6acSopenharmony_ci printf("q) Exit\n"); 7496cd6a6acSopenharmony_ci while (1) { 7506cd6a6acSopenharmony_ci printf("\nChoose: "); 7516cd6a6acSopenharmony_ci FGETS(ans, sizeof(ans), stdin); 7526cd6a6acSopenharmony_ci switch (ans[0]) { 7536cd6a6acSopenharmony_ci case '0': 7546cd6a6acSopenharmony_ci printf("source sid? "); 7556cd6a6acSopenharmony_ci FGETS(ans, sizeof(ans), stdin); 7566cd6a6acSopenharmony_ci ssid = atoi(ans); 7576cd6a6acSopenharmony_ci 7586cd6a6acSopenharmony_ci printf("target sid? "); 7596cd6a6acSopenharmony_ci FGETS(ans, sizeof(ans), stdin); 7606cd6a6acSopenharmony_ci tsid = atoi(ans); 7616cd6a6acSopenharmony_ci 7626cd6a6acSopenharmony_ci printf("target class? "); 7636cd6a6acSopenharmony_ci FGETS(ans, sizeof(ans), stdin); 7646cd6a6acSopenharmony_ci if (isdigit(ans[0])) { 7656cd6a6acSopenharmony_ci tclass = atoi(ans); 7666cd6a6acSopenharmony_ci if (!tclass 7676cd6a6acSopenharmony_ci || tclass > policydb.p_classes.nprim) { 7686cd6a6acSopenharmony_ci printf("\nNo such class.\n"); 7696cd6a6acSopenharmony_ci break; 7706cd6a6acSopenharmony_ci } 7716cd6a6acSopenharmony_ci cladatum = 7726cd6a6acSopenharmony_ci policydb.class_val_to_struct[tclass - 1]; 7736cd6a6acSopenharmony_ci } else { 7746cd6a6acSopenharmony_ci ans[strlen(ans) - 1] = 0; 7756cd6a6acSopenharmony_ci cladatum = 7766cd6a6acSopenharmony_ci (class_datum_t *) hashtab_search(policydb. 7776cd6a6acSopenharmony_ci p_classes. 7786cd6a6acSopenharmony_ci table, 7796cd6a6acSopenharmony_ci ans); 7806cd6a6acSopenharmony_ci if (!cladatum) { 7816cd6a6acSopenharmony_ci printf("\nNo such class\n"); 7826cd6a6acSopenharmony_ci break; 7836cd6a6acSopenharmony_ci } 7846cd6a6acSopenharmony_ci tclass = cladatum->s.value; 7856cd6a6acSopenharmony_ci } 7866cd6a6acSopenharmony_ci 7876cd6a6acSopenharmony_ci if (!cladatum->comdatum && !cladatum->permissions.nprim) { 7886cd6a6acSopenharmony_ci printf 7896cd6a6acSopenharmony_ci ("\nNo access vector definition for that class\n"); 7906cd6a6acSopenharmony_ci break; 7916cd6a6acSopenharmony_ci } 7926cd6a6acSopenharmony_ci ret = sepol_compute_av(ssid, tsid, tclass, 0, &avd); 7936cd6a6acSopenharmony_ci switch (ret) { 7946cd6a6acSopenharmony_ci case 0: 7956cd6a6acSopenharmony_ci printf("\nallowed {"); 7966cd6a6acSopenharmony_ci for (i = 1; i <= sizeof(avd.allowed) * 8; i++) { 7976cd6a6acSopenharmony_ci if (avd.allowed & (UINT32_C(1) << (i - 1))) { 7986cd6a6acSopenharmony_ci v.val = i; 7996cd6a6acSopenharmony_ci ret = 8006cd6a6acSopenharmony_ci hashtab_map(cladatum-> 8016cd6a6acSopenharmony_ci permissions. 8026cd6a6acSopenharmony_ci table, 8036cd6a6acSopenharmony_ci find_perm, &v); 8046cd6a6acSopenharmony_ci if (!ret && cladatum->comdatum) { 8056cd6a6acSopenharmony_ci ret = 8066cd6a6acSopenharmony_ci hashtab_map 8076cd6a6acSopenharmony_ci (cladatum-> 8086cd6a6acSopenharmony_ci comdatum-> 8096cd6a6acSopenharmony_ci permissions.table, 8106cd6a6acSopenharmony_ci find_perm, &v); 8116cd6a6acSopenharmony_ci } 8126cd6a6acSopenharmony_ci if (ret) 8136cd6a6acSopenharmony_ci printf(" %s", v.name); 8146cd6a6acSopenharmony_ci } 8156cd6a6acSopenharmony_ci } 8166cd6a6acSopenharmony_ci printf(" }\n"); 8176cd6a6acSopenharmony_ci break; 8186cd6a6acSopenharmony_ci case -EINVAL: 8196cd6a6acSopenharmony_ci printf("\ninvalid sid\n"); 8206cd6a6acSopenharmony_ci break; 8216cd6a6acSopenharmony_ci default: 8226cd6a6acSopenharmony_ci printf("return code 0x%x\n", ret); 8236cd6a6acSopenharmony_ci } 8246cd6a6acSopenharmony_ci break; 8256cd6a6acSopenharmony_ci case '1': 8266cd6a6acSopenharmony_ci printf("sid? "); 8276cd6a6acSopenharmony_ci FGETS(ans, sizeof(ans), stdin); 8286cd6a6acSopenharmony_ci ssid = atoi(ans); 8296cd6a6acSopenharmony_ci ret = sepol_sid_to_context(ssid, 8306cd6a6acSopenharmony_ci &scontext, &scontext_len); 8316cd6a6acSopenharmony_ci switch (ret) { 8326cd6a6acSopenharmony_ci case 0: 8336cd6a6acSopenharmony_ci printf("\nscontext %s\n", scontext); 8346cd6a6acSopenharmony_ci free(scontext); 8356cd6a6acSopenharmony_ci break; 8366cd6a6acSopenharmony_ci case -EINVAL: 8376cd6a6acSopenharmony_ci printf("\ninvalid sid\n"); 8386cd6a6acSopenharmony_ci break; 8396cd6a6acSopenharmony_ci case -ENOMEM: 8406cd6a6acSopenharmony_ci printf("\nout of memory\n"); 8416cd6a6acSopenharmony_ci break; 8426cd6a6acSopenharmony_ci default: 8436cd6a6acSopenharmony_ci printf("return code 0x%x\n", ret); 8446cd6a6acSopenharmony_ci } 8456cd6a6acSopenharmony_ci break; 8466cd6a6acSopenharmony_ci case '2': 8476cd6a6acSopenharmony_ci printf("scontext? "); 8486cd6a6acSopenharmony_ci FGETS(ans, sizeof(ans), stdin); 8496cd6a6acSopenharmony_ci scontext_len = strlen(ans); 8506cd6a6acSopenharmony_ci ans[scontext_len - 1] = 0; 8516cd6a6acSopenharmony_ci ret = sepol_context_to_sid(ans, scontext_len, &ssid); 8526cd6a6acSopenharmony_ci switch (ret) { 8536cd6a6acSopenharmony_ci case 0: 8546cd6a6acSopenharmony_ci printf("\nsid %d\n", ssid); 8556cd6a6acSopenharmony_ci break; 8566cd6a6acSopenharmony_ci case -EINVAL: 8576cd6a6acSopenharmony_ci printf("\ninvalid context\n"); 8586cd6a6acSopenharmony_ci break; 8596cd6a6acSopenharmony_ci case -ENOMEM: 8606cd6a6acSopenharmony_ci printf("\nout of memory\n"); 8616cd6a6acSopenharmony_ci break; 8626cd6a6acSopenharmony_ci default: 8636cd6a6acSopenharmony_ci printf("return code 0x%x\n", ret); 8646cd6a6acSopenharmony_ci } 8656cd6a6acSopenharmony_ci break; 8666cd6a6acSopenharmony_ci case '3': 8676cd6a6acSopenharmony_ci case '4': 8686cd6a6acSopenharmony_ci case '5': 8696cd6a6acSopenharmony_ci ch = ans[0]; 8706cd6a6acSopenharmony_ci 8716cd6a6acSopenharmony_ci printf("source sid? "); 8726cd6a6acSopenharmony_ci FGETS(ans, sizeof(ans), stdin); 8736cd6a6acSopenharmony_ci ssid = atoi(ans); 8746cd6a6acSopenharmony_ci printf("target sid? "); 8756cd6a6acSopenharmony_ci FGETS(ans, sizeof(ans), stdin); 8766cd6a6acSopenharmony_ci tsid = atoi(ans); 8776cd6a6acSopenharmony_ci 8786cd6a6acSopenharmony_ci printf("object class? "); 8796cd6a6acSopenharmony_ci FGETS(ans, sizeof(ans), stdin); 8806cd6a6acSopenharmony_ci if (isdigit(ans[0])) { 8816cd6a6acSopenharmony_ci tclass = atoi(ans); 8826cd6a6acSopenharmony_ci if (!tclass 8836cd6a6acSopenharmony_ci || tclass > policydb.p_classes.nprim) { 8846cd6a6acSopenharmony_ci printf("\nNo such class.\n"); 8856cd6a6acSopenharmony_ci break; 8866cd6a6acSopenharmony_ci } 8876cd6a6acSopenharmony_ci } else { 8886cd6a6acSopenharmony_ci ans[strlen(ans) - 1] = 0; 8896cd6a6acSopenharmony_ci cladatum = 8906cd6a6acSopenharmony_ci (class_datum_t *) hashtab_search(policydb. 8916cd6a6acSopenharmony_ci p_classes. 8926cd6a6acSopenharmony_ci table, 8936cd6a6acSopenharmony_ci ans); 8946cd6a6acSopenharmony_ci if (!cladatum) { 8956cd6a6acSopenharmony_ci printf("\nNo such class\n"); 8966cd6a6acSopenharmony_ci break; 8976cd6a6acSopenharmony_ci } 8986cd6a6acSopenharmony_ci tclass = cladatum->s.value; 8996cd6a6acSopenharmony_ci } 9006cd6a6acSopenharmony_ci 9016cd6a6acSopenharmony_ci if (ch == '3') 9026cd6a6acSopenharmony_ci ret = 9036cd6a6acSopenharmony_ci sepol_transition_sid(ssid, tsid, tclass, 9046cd6a6acSopenharmony_ci &ssid); 9056cd6a6acSopenharmony_ci else if (ch == '4') 9066cd6a6acSopenharmony_ci ret = 9076cd6a6acSopenharmony_ci sepol_member_sid(ssid, tsid, tclass, &ssid); 9086cd6a6acSopenharmony_ci else 9096cd6a6acSopenharmony_ci ret = 9106cd6a6acSopenharmony_ci sepol_change_sid(ssid, tsid, tclass, &ssid); 9116cd6a6acSopenharmony_ci switch (ret) { 9126cd6a6acSopenharmony_ci case 0: 9136cd6a6acSopenharmony_ci printf("\nsid %d\n", ssid); 9146cd6a6acSopenharmony_ci break; 9156cd6a6acSopenharmony_ci case -EINVAL: 9166cd6a6acSopenharmony_ci printf("\ninvalid sid\n"); 9176cd6a6acSopenharmony_ci break; 9186cd6a6acSopenharmony_ci case -ENOMEM: 9196cd6a6acSopenharmony_ci printf("\nout of memory\n"); 9206cd6a6acSopenharmony_ci break; 9216cd6a6acSopenharmony_ci default: 9226cd6a6acSopenharmony_ci printf("return code 0x%x\n", ret); 9236cd6a6acSopenharmony_ci } 9246cd6a6acSopenharmony_ci break; 9256cd6a6acSopenharmony_ci case '6': 9266cd6a6acSopenharmony_ci sepol_sidtab_map(&sidtab, print_sid, 0); 9276cd6a6acSopenharmony_ci break; 9286cd6a6acSopenharmony_ci case '7': 9296cd6a6acSopenharmony_ci printf("pathname? "); 9306cd6a6acSopenharmony_ci FGETS(ans, sizeof(ans), stdin); 9316cd6a6acSopenharmony_ci pathlen = strlen(ans); 9326cd6a6acSopenharmony_ci ans[pathlen - 1] = 0; 9336cd6a6acSopenharmony_ci fd = open(ans, O_RDONLY); 9346cd6a6acSopenharmony_ci if (fd < 0) { 9356cd6a6acSopenharmony_ci fprintf(stderr, "Can't open '%s': %s\n", 9366cd6a6acSopenharmony_ci ans, strerror(errno)); 9376cd6a6acSopenharmony_ci break; 9386cd6a6acSopenharmony_ci } 9396cd6a6acSopenharmony_ci if (fstat(fd, &sb) < 0) { 9406cd6a6acSopenharmony_ci fprintf(stderr, "Can't stat '%s': %s\n", 9416cd6a6acSopenharmony_ci ans, strerror(errno)); 9426cd6a6acSopenharmony_ci break; 9436cd6a6acSopenharmony_ci } 9446cd6a6acSopenharmony_ci map = 9456cd6a6acSopenharmony_ci mmap(NULL, sb.st_size, PROT_READ | PROT_WRITE, 9466cd6a6acSopenharmony_ci MAP_PRIVATE, fd, 0); 9476cd6a6acSopenharmony_ci if (map == MAP_FAILED) { 9486cd6a6acSopenharmony_ci fprintf(stderr, "Can't map '%s': %s\n", 9496cd6a6acSopenharmony_ci ans, strerror(errno)); 9506cd6a6acSopenharmony_ci break; 9516cd6a6acSopenharmony_ci } 9526cd6a6acSopenharmony_ci ret = sepol_load_policy(map, sb.st_size); 9536cd6a6acSopenharmony_ci switch (ret) { 9546cd6a6acSopenharmony_ci case 0: 9556cd6a6acSopenharmony_ci printf("\nsuccess\n"); 9566cd6a6acSopenharmony_ci break; 9576cd6a6acSopenharmony_ci case -EINVAL: 9586cd6a6acSopenharmony_ci printf("\ninvalid policy\n"); 9596cd6a6acSopenharmony_ci break; 9606cd6a6acSopenharmony_ci case -ENOMEM: 9616cd6a6acSopenharmony_ci printf("\nout of memory\n"); 9626cd6a6acSopenharmony_ci break; 9636cd6a6acSopenharmony_ci default: 9646cd6a6acSopenharmony_ci printf("return code 0x%x\n", ret); 9656cd6a6acSopenharmony_ci } 9666cd6a6acSopenharmony_ci break; 9676cd6a6acSopenharmony_ci case '8': 9686cd6a6acSopenharmony_ci printf("fs kdevname? "); 9696cd6a6acSopenharmony_ci FGETS(ans, sizeof(ans), stdin); 9706cd6a6acSopenharmony_ci ans[strlen(ans) - 1] = 0; 9716cd6a6acSopenharmony_ci ret = sepol_fs_sid(ans, &ssid, &tsid); 9726cd6a6acSopenharmony_ci if (ret) { 9736cd6a6acSopenharmony_ci printf("unknown fs kdevname\n"); 9746cd6a6acSopenharmony_ci } else { 9756cd6a6acSopenharmony_ci printf("fs_sid %d default_file_sid %d\n", ssid, tsid); 9766cd6a6acSopenharmony_ci } 9776cd6a6acSopenharmony_ci break; 9786cd6a6acSopenharmony_ci case '9': 9796cd6a6acSopenharmony_ci printf("protocol? "); 9806cd6a6acSopenharmony_ci FGETS(ans, sizeof(ans), stdin); 9816cd6a6acSopenharmony_ci ans[strlen(ans) - 1] = 0; 9826cd6a6acSopenharmony_ci if (!strcmp(ans, "tcp") || !strcmp(ans, "TCP")) 9836cd6a6acSopenharmony_ci protocol = IPPROTO_TCP; 9846cd6a6acSopenharmony_ci else if (!strcmp(ans, "udp") || !strcmp(ans, "UDP")) 9856cd6a6acSopenharmony_ci protocol = IPPROTO_UDP; 9866cd6a6acSopenharmony_ci else if (!strcmp(ans, "dccp") || !strcmp(ans, "DCCP")) 9876cd6a6acSopenharmony_ci protocol = IPPROTO_DCCP; 9886cd6a6acSopenharmony_ci else if (!strcmp(ans, "sctp") || !strcmp(ans, "SCTP")) 9896cd6a6acSopenharmony_ci protocol = IPPROTO_SCTP; 9906cd6a6acSopenharmony_ci else { 9916cd6a6acSopenharmony_ci printf("unknown protocol\n"); 9926cd6a6acSopenharmony_ci break; 9936cd6a6acSopenharmony_ci } 9946cd6a6acSopenharmony_ci printf("port? "); 9956cd6a6acSopenharmony_ci FGETS(ans, sizeof(ans), stdin); 9966cd6a6acSopenharmony_ci port = atoi(ans); 9976cd6a6acSopenharmony_ci sepol_port_sid(0, 0, protocol, port, &ssid); 9986cd6a6acSopenharmony_ci printf("sid %d\n", ssid); 9996cd6a6acSopenharmony_ci break; 10006cd6a6acSopenharmony_ci case 'a': 10016cd6a6acSopenharmony_ci printf("netif name? "); 10026cd6a6acSopenharmony_ci FGETS(ans, sizeof(ans), stdin); 10036cd6a6acSopenharmony_ci ans[strlen(ans) - 1] = 0; 10046cd6a6acSopenharmony_ci ret = sepol_netif_sid(ans, &ssid, &tsid); 10056cd6a6acSopenharmony_ci if (ret) { 10066cd6a6acSopenharmony_ci printf("unknown name\n"); 10076cd6a6acSopenharmony_ci } else { 10086cd6a6acSopenharmony_ci printf("if_sid %d default_msg_sid %d\n", ssid, tsid); 10096cd6a6acSopenharmony_ci } 10106cd6a6acSopenharmony_ci break; 10116cd6a6acSopenharmony_ci case 'b':{ 10126cd6a6acSopenharmony_ci char *p; 10136cd6a6acSopenharmony_ci int family, len; 10146cd6a6acSopenharmony_ci struct in_addr addr4; 10156cd6a6acSopenharmony_ci struct in6_addr addr6; 10166cd6a6acSopenharmony_ci 10176cd6a6acSopenharmony_ci printf("protocol family? "); 10186cd6a6acSopenharmony_ci FGETS(ans, sizeof(ans), stdin); 10196cd6a6acSopenharmony_ci ans[strlen(ans) - 1] = 0; 10206cd6a6acSopenharmony_ci if (!strcasecmp(ans, "ipv4")) 10216cd6a6acSopenharmony_ci family = AF_INET; 10226cd6a6acSopenharmony_ci else if (!strcasecmp(ans, "ipv6")) 10236cd6a6acSopenharmony_ci family = AF_INET6; 10246cd6a6acSopenharmony_ci else { 10256cd6a6acSopenharmony_ci printf("unknown protocol family\n"); 10266cd6a6acSopenharmony_ci break; 10276cd6a6acSopenharmony_ci } 10286cd6a6acSopenharmony_ci 10296cd6a6acSopenharmony_ci printf("node address? "); 10306cd6a6acSopenharmony_ci FGETS(ans, sizeof(ans), stdin); 10316cd6a6acSopenharmony_ci ans[strlen(ans) - 1] = 0; 10326cd6a6acSopenharmony_ci 10336cd6a6acSopenharmony_ci if (family == AF_INET) { 10346cd6a6acSopenharmony_ci p = (char *)&addr4; 10356cd6a6acSopenharmony_ci len = sizeof(addr4); 10366cd6a6acSopenharmony_ci } else { 10376cd6a6acSopenharmony_ci p = (char *)&addr6; 10386cd6a6acSopenharmony_ci len = sizeof(addr6); 10396cd6a6acSopenharmony_ci } 10406cd6a6acSopenharmony_ci 10416cd6a6acSopenharmony_ci if (inet_pton(family, ans, p) < 1) { 10426cd6a6acSopenharmony_ci printf("error parsing address\n"); 10436cd6a6acSopenharmony_ci break; 10446cd6a6acSopenharmony_ci } 10456cd6a6acSopenharmony_ci 10466cd6a6acSopenharmony_ci sepol_node_sid(family, p, len, &ssid); 10476cd6a6acSopenharmony_ci printf("sid %d\n", ssid); 10486cd6a6acSopenharmony_ci break; 10496cd6a6acSopenharmony_ci } 10506cd6a6acSopenharmony_ci case 'c': 10516cd6a6acSopenharmony_ci printf("fstype? "); 10526cd6a6acSopenharmony_ci FGETS(ans, sizeof(ans), stdin); 10536cd6a6acSopenharmony_ci ans[strlen(ans) - 1] = 0; 10546cd6a6acSopenharmony_ci sepol_fs_use(ans, &uret, &ssid); 10556cd6a6acSopenharmony_ci switch (uret) { 10566cd6a6acSopenharmony_ci case SECURITY_FS_USE_XATTR: 10576cd6a6acSopenharmony_ci printf("use xattr\n"); 10586cd6a6acSopenharmony_ci break; 10596cd6a6acSopenharmony_ci case SECURITY_FS_USE_TRANS: 10606cd6a6acSopenharmony_ci printf("use transition SIDs\n"); 10616cd6a6acSopenharmony_ci break; 10626cd6a6acSopenharmony_ci case SECURITY_FS_USE_TASK: 10636cd6a6acSopenharmony_ci printf("use task SIDs\n"); 10646cd6a6acSopenharmony_ci break; 10656cd6a6acSopenharmony_ci case SECURITY_FS_USE_GENFS: 10666cd6a6acSopenharmony_ci printf("use genfs\n"); 10676cd6a6acSopenharmony_ci break; 10686cd6a6acSopenharmony_ci case SECURITY_FS_USE_NONE: 10696cd6a6acSopenharmony_ci printf("no labeling support\n"); 10706cd6a6acSopenharmony_ci break; 10716cd6a6acSopenharmony_ci } 10726cd6a6acSopenharmony_ci printf("sid %d\n", ssid); 10736cd6a6acSopenharmony_ci break; 10746cd6a6acSopenharmony_ci case 'd': 10756cd6a6acSopenharmony_ci printf("fstype? "); 10766cd6a6acSopenharmony_ci FGETS(ans, sizeof(ans), stdin); 10776cd6a6acSopenharmony_ci ans[strlen(ans) - 1] = 0; 10786cd6a6acSopenharmony_ci fstype = strdup(ans); 10796cd6a6acSopenharmony_ci printf("path? "); 10806cd6a6acSopenharmony_ci FGETS(ans, sizeof(ans), stdin); 10816cd6a6acSopenharmony_ci ans[strlen(ans) - 1] = 0; 10826cd6a6acSopenharmony_ci path = strdup(ans); 10836cd6a6acSopenharmony_ci printf("object class? "); 10846cd6a6acSopenharmony_ci FGETS(ans, sizeof(ans), stdin); 10856cd6a6acSopenharmony_ci if (isdigit(ans[0])) { 10866cd6a6acSopenharmony_ci tclass = atoi(ans); 10876cd6a6acSopenharmony_ci if (!tclass 10886cd6a6acSopenharmony_ci || tclass > policydb.p_classes.nprim) { 10896cd6a6acSopenharmony_ci printf("\nNo such class.\n"); 10906cd6a6acSopenharmony_ci break; 10916cd6a6acSopenharmony_ci } 10926cd6a6acSopenharmony_ci } else { 10936cd6a6acSopenharmony_ci ans[strlen(ans) - 1] = 0; 10946cd6a6acSopenharmony_ci cladatum = 10956cd6a6acSopenharmony_ci (class_datum_t *) hashtab_search(policydb. 10966cd6a6acSopenharmony_ci p_classes. 10976cd6a6acSopenharmony_ci table, 10986cd6a6acSopenharmony_ci ans); 10996cd6a6acSopenharmony_ci if (!cladatum) { 11006cd6a6acSopenharmony_ci printf("\nNo such class\n"); 11016cd6a6acSopenharmony_ci break; 11026cd6a6acSopenharmony_ci } 11036cd6a6acSopenharmony_ci tclass = cladatum->s.value; 11046cd6a6acSopenharmony_ci } 11056cd6a6acSopenharmony_ci sepol_genfs_sid(fstype, path, tclass, &ssid); 11066cd6a6acSopenharmony_ci printf("sid %d\n", ssid); 11076cd6a6acSopenharmony_ci free(fstype); 11086cd6a6acSopenharmony_ci free(path); 11096cd6a6acSopenharmony_ci break; 11106cd6a6acSopenharmony_ci case 'e': 11116cd6a6acSopenharmony_ci printf("from SID? "); 11126cd6a6acSopenharmony_ci FGETS(ans, sizeof(ans), stdin); 11136cd6a6acSopenharmony_ci ans[strlen(ans) - 1] = 0; 11146cd6a6acSopenharmony_ci ssid = atoi(ans); 11156cd6a6acSopenharmony_ci 11166cd6a6acSopenharmony_ci printf("username? "); 11176cd6a6acSopenharmony_ci FGETS(ans, sizeof(ans), stdin); 11186cd6a6acSopenharmony_ci ans[strlen(ans) - 1] = 0; 11196cd6a6acSopenharmony_ci 11206cd6a6acSopenharmony_ci ret = sepol_get_user_sids(ssid, ans, &sids, &nel); 11216cd6a6acSopenharmony_ci switch (ret) { 11226cd6a6acSopenharmony_ci case 0: 11236cd6a6acSopenharmony_ci if (!nel) 11246cd6a6acSopenharmony_ci printf("\nnone\n"); 11256cd6a6acSopenharmony_ci for (i = 0; i < nel; i++) 11266cd6a6acSopenharmony_ci print_sid(sids[i], NULL, NULL); 11276cd6a6acSopenharmony_ci free(sids); 11286cd6a6acSopenharmony_ci break; 11296cd6a6acSopenharmony_ci case -ENOMEM: 11306cd6a6acSopenharmony_ci printf("\nout of memory\n"); 11316cd6a6acSopenharmony_ci break; 11326cd6a6acSopenharmony_ci case -EINVAL: 11336cd6a6acSopenharmony_ci printf("\ninvalid argument\n"); 11346cd6a6acSopenharmony_ci break; 11356cd6a6acSopenharmony_ci default: 11366cd6a6acSopenharmony_ci printf("\nerror\n"); 11376cd6a6acSopenharmony_ci break; 11386cd6a6acSopenharmony_ci } 11396cd6a6acSopenharmony_ci break; 11406cd6a6acSopenharmony_ci case 'f': 11416cd6a6acSopenharmony_ci display_bools(); 11426cd6a6acSopenharmony_ci break; 11436cd6a6acSopenharmony_ci case 'g': 11446cd6a6acSopenharmony_ci display_cond_expressions(); 11456cd6a6acSopenharmony_ci break; 11466cd6a6acSopenharmony_ci case 'h': 11476cd6a6acSopenharmony_ci printf("name? "); 11486cd6a6acSopenharmony_ci FGETS(ans, sizeof(ans), stdin); 11496cd6a6acSopenharmony_ci ans[strlen(ans) - 1] = 0; 11506cd6a6acSopenharmony_ci 11516cd6a6acSopenharmony_ci name = strdup(ans); 11526cd6a6acSopenharmony_ci if (name == NULL) { 11536cd6a6acSopenharmony_ci fprintf(stderr, "couldn't strdup string.\n"); 11546cd6a6acSopenharmony_ci break; 11556cd6a6acSopenharmony_ci } 11566cd6a6acSopenharmony_ci 11576cd6a6acSopenharmony_ci printf("state? "); 11586cd6a6acSopenharmony_ci FGETS(ans, sizeof(ans), stdin); 11596cd6a6acSopenharmony_ci ans[strlen(ans) - 1] = 0; 11606cd6a6acSopenharmony_ci 11616cd6a6acSopenharmony_ci if (atoi(ans)) 11626cd6a6acSopenharmony_ci state = 1; 11636cd6a6acSopenharmony_ci else 11646cd6a6acSopenharmony_ci state = 0; 11656cd6a6acSopenharmony_ci 11666cd6a6acSopenharmony_ci change_bool(name, state); 11676cd6a6acSopenharmony_ci free(name); 11686cd6a6acSopenharmony_ci break; 11696cd6a6acSopenharmony_ci case 'i': 11706cd6a6acSopenharmony_ci printf("source sid? "); 11716cd6a6acSopenharmony_ci FGETS(ans, sizeof(ans), stdin); 11726cd6a6acSopenharmony_ci ssid = atoi(ans); 11736cd6a6acSopenharmony_ci 11746cd6a6acSopenharmony_ci printf("target sid? "); 11756cd6a6acSopenharmony_ci FGETS(ans, sizeof(ans), stdin); 11766cd6a6acSopenharmony_ci tsid = atoi(ans); 11776cd6a6acSopenharmony_ci 11786cd6a6acSopenharmony_ci printf("target class? "); 11796cd6a6acSopenharmony_ci FGETS(ans, sizeof(ans), stdin); 11806cd6a6acSopenharmony_ci if (isdigit(ans[0])) { 11816cd6a6acSopenharmony_ci tclass = atoi(ans); 11826cd6a6acSopenharmony_ci if (!tclass 11836cd6a6acSopenharmony_ci || tclass > policydb.p_classes.nprim) { 11846cd6a6acSopenharmony_ci printf("\nNo such class.\n"); 11856cd6a6acSopenharmony_ci break; 11866cd6a6acSopenharmony_ci } 11876cd6a6acSopenharmony_ci } else { 11886cd6a6acSopenharmony_ci ans[strlen(ans) - 1] = 0; 11896cd6a6acSopenharmony_ci cladatum = 11906cd6a6acSopenharmony_ci (class_datum_t *) hashtab_search(policydb. 11916cd6a6acSopenharmony_ci p_classes. 11926cd6a6acSopenharmony_ci table, 11936cd6a6acSopenharmony_ci ans); 11946cd6a6acSopenharmony_ci if (!cladatum) { 11956cd6a6acSopenharmony_ci printf("\nNo such class\n"); 11966cd6a6acSopenharmony_ci break; 11976cd6a6acSopenharmony_ci } 11986cd6a6acSopenharmony_ci tclass = cladatum->s.value; 11996cd6a6acSopenharmony_ci } 12006cd6a6acSopenharmony_ci 12016cd6a6acSopenharmony_ci flags = SHOW_GRANTED; 12026cd6a6acSopenharmony_ci if (sepol_compute_av_reason_buffer(ssid, tsid, 12036cd6a6acSopenharmony_ci tclass, 0, &avd, &reason, 12046cd6a6acSopenharmony_ci &reason_buf, flags)) { 12056cd6a6acSopenharmony_ci printf("\nconstraint error\n"); 12066cd6a6acSopenharmony_ci break; 12076cd6a6acSopenharmony_ci } 12086cd6a6acSopenharmony_ci if (reason_buf) { 12096cd6a6acSopenharmony_ci printf("\nConstraint expressions:\n%s", 12106cd6a6acSopenharmony_ci reason_buf); 12116cd6a6acSopenharmony_ci free(reason_buf); 12126cd6a6acSopenharmony_ci } else { 12136cd6a6acSopenharmony_ci printf("\nNo constraints found.\n"); 12146cd6a6acSopenharmony_ci } 12156cd6a6acSopenharmony_ci break; 12166cd6a6acSopenharmony_ci case 'j': 12176cd6a6acSopenharmony_ci printf("old sid? "); 12186cd6a6acSopenharmony_ci FGETS(ans, sizeof(ans), stdin); 12196cd6a6acSopenharmony_ci oldsid = atoi(ans); 12206cd6a6acSopenharmony_ci 12216cd6a6acSopenharmony_ci printf("new sid? "); 12226cd6a6acSopenharmony_ci FGETS(ans, sizeof(ans), stdin); 12236cd6a6acSopenharmony_ci newsid = atoi(ans); 12246cd6a6acSopenharmony_ci 12256cd6a6acSopenharmony_ci printf("task sid? "); 12266cd6a6acSopenharmony_ci FGETS(ans, sizeof(ans), stdin); 12276cd6a6acSopenharmony_ci tasksid = atoi(ans); 12286cd6a6acSopenharmony_ci 12296cd6a6acSopenharmony_ci printf("target class? "); 12306cd6a6acSopenharmony_ci FGETS(ans, sizeof(ans), stdin); 12316cd6a6acSopenharmony_ci if (isdigit(ans[0])) { 12326cd6a6acSopenharmony_ci tclass = atoi(ans); 12336cd6a6acSopenharmony_ci if (!tclass 12346cd6a6acSopenharmony_ci || tclass > policydb.p_classes.nprim) { 12356cd6a6acSopenharmony_ci printf("\nNo such class.\n"); 12366cd6a6acSopenharmony_ci break; 12376cd6a6acSopenharmony_ci } 12386cd6a6acSopenharmony_ci } else { 12396cd6a6acSopenharmony_ci ans[strlen(ans) - 1] = 0; 12406cd6a6acSopenharmony_ci cladatum = 12416cd6a6acSopenharmony_ci (class_datum_t *) hashtab_search(policydb. 12426cd6a6acSopenharmony_ci p_classes. 12436cd6a6acSopenharmony_ci table, 12446cd6a6acSopenharmony_ci ans); 12456cd6a6acSopenharmony_ci if (!cladatum) { 12466cd6a6acSopenharmony_ci printf("\nNo such class\n"); 12476cd6a6acSopenharmony_ci break; 12486cd6a6acSopenharmony_ci } 12496cd6a6acSopenharmony_ci tclass = cladatum->s.value; 12506cd6a6acSopenharmony_ci } 12516cd6a6acSopenharmony_ci 12526cd6a6acSopenharmony_ci flags = SHOW_GRANTED; 12536cd6a6acSopenharmony_ci if (sepol_validate_transition_reason_buffer(oldsid, 12546cd6a6acSopenharmony_ci newsid, tasksid, tclass, 12556cd6a6acSopenharmony_ci &reason_buf, flags)) { 12566cd6a6acSopenharmony_ci printf("\nvalidatetrans error\n"); 12576cd6a6acSopenharmony_ci break; 12586cd6a6acSopenharmony_ci } 12596cd6a6acSopenharmony_ci if (reason_buf) { 12606cd6a6acSopenharmony_ci printf("\nValidatetrans expressions:\n%s", 12616cd6a6acSopenharmony_ci reason_buf); 12626cd6a6acSopenharmony_ci free(reason_buf); 12636cd6a6acSopenharmony_ci } else { 12646cd6a6acSopenharmony_ci printf( 12656cd6a6acSopenharmony_ci "\nNo validatetrans expressions found.\n"); 12666cd6a6acSopenharmony_ci } 12676cd6a6acSopenharmony_ci break; 12686cd6a6acSopenharmony_ci case 'k': 12696cd6a6acSopenharmony_ci { 12706cd6a6acSopenharmony_ci char *p; 12716cd6a6acSopenharmony_ci struct in6_addr addr6; 12726cd6a6acSopenharmony_ci uint64_t subnet_prefix; 12736cd6a6acSopenharmony_ci unsigned int pkey; 12746cd6a6acSopenharmony_ci 12756cd6a6acSopenharmony_ci printf("subnet prefix? "); 12766cd6a6acSopenharmony_ci FGETS(ans, sizeof(ans), stdin); 12776cd6a6acSopenharmony_ci ans[strlen(ans) - 1] = 0; 12786cd6a6acSopenharmony_ci p = (char *)&addr6; 12796cd6a6acSopenharmony_ci 12806cd6a6acSopenharmony_ci if (inet_pton(AF_INET6, ans, p) < 1) { 12816cd6a6acSopenharmony_ci printf("error parsing subnet prefix\n"); 12826cd6a6acSopenharmony_ci break; 12836cd6a6acSopenharmony_ci } 12846cd6a6acSopenharmony_ci 12856cd6a6acSopenharmony_ci memcpy(&subnet_prefix, p, sizeof(subnet_prefix)); 12866cd6a6acSopenharmony_ci printf("pkey? "); 12876cd6a6acSopenharmony_ci FGETS(ans, sizeof(ans), stdin); 12886cd6a6acSopenharmony_ci pkey = atoi(ans); 12896cd6a6acSopenharmony_ci sepol_ibpkey_sid(subnet_prefix, pkey, &ssid); 12906cd6a6acSopenharmony_ci printf("sid %d\n", ssid); 12916cd6a6acSopenharmony_ci } 12926cd6a6acSopenharmony_ci break; 12936cd6a6acSopenharmony_ci case 'l': 12946cd6a6acSopenharmony_ci printf("device name (eg. mlx4_0)? "); 12956cd6a6acSopenharmony_ci FGETS(ans, sizeof(ans), stdin); 12966cd6a6acSopenharmony_ci ans[strlen(ans) - 1] = 0; 12976cd6a6acSopenharmony_ci 12986cd6a6acSopenharmony_ci name = strdup(ans); 12996cd6a6acSopenharmony_ci if (!name) { 13006cd6a6acSopenharmony_ci fprintf(stderr, "couldn't strdup string.\n"); 13016cd6a6acSopenharmony_ci break; 13026cd6a6acSopenharmony_ci } 13036cd6a6acSopenharmony_ci 13046cd6a6acSopenharmony_ci printf("port? "); 13056cd6a6acSopenharmony_ci FGETS(ans, sizeof(ans), stdin); 13066cd6a6acSopenharmony_ci port = atoi(ans); 13076cd6a6acSopenharmony_ci sepol_ibendport_sid(name, port, &ssid); 13086cd6a6acSopenharmony_ci printf("sid %d\n", ssid); 13096cd6a6acSopenharmony_ci free(name); 13106cd6a6acSopenharmony_ci break; 13116cd6a6acSopenharmony_ci#ifdef EQUIVTYPES 13126cd6a6acSopenharmony_ci case 'z': 13136cd6a6acSopenharmony_ci identify_equiv_types(); 13146cd6a6acSopenharmony_ci break; 13156cd6a6acSopenharmony_ci#endif 13166cd6a6acSopenharmony_ci case 'm': 13176cd6a6acSopenharmony_ci goto menu; 13186cd6a6acSopenharmony_ci case 'q': 13196cd6a6acSopenharmony_ci exit(0); 13206cd6a6acSopenharmony_ci break; 13216cd6a6acSopenharmony_ci default: 13226cd6a6acSopenharmony_ci printf("\nUnknown option %s.\n", ans); 13236cd6a6acSopenharmony_ci } 13246cd6a6acSopenharmony_ci } 13256cd6a6acSopenharmony_ci 13266cd6a6acSopenharmony_ci return 0; 13276cd6a6acSopenharmony_ci} 13286cd6a6acSopenharmony_ci 13296cd6a6acSopenharmony_ci/* FLASK */ 1330