1f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts#include <stdio.h> 2f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts#include <stdarg.h> 3f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts#include <ctype.h> 4f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts#include <stdio.h> 5f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts#include <stdlib.h> 6f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts#include <unistd.h> 7f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts#include <string.h> 8f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts#include <errno.h> 9f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts#include <stdint.h> 10f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts#include <search.h> 1161846291746a3a3559f615ef3665312ccd2228c2William Roberts#include <stdbool.h> 12f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts#include <sepol/sepol.h> 13f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts#include <sepol/policydb/policydb.h> 1481e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts#include <pcre.h> 15f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 16f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts#define TABLE_SIZE 1024 17f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts#define KVP_NUM_OF_RULES (sizeof(rules) / sizeof(key_map)) 18f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts#define log_set_verbose() do { logging_verbose = 1; log_info("Enabling verbose\n"); } while(0) 19f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts#define log_error(fmt, ...) log_msg(stderr, "Error: ", fmt, ##__VA_ARGS__) 20f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts#define log_warn(fmt, ...) log_msg(stderr, "Warning: ", fmt, ##__VA_ARGS__) 21f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts#define log_info(fmt, ...) if (logging_verbose ) { log_msg(stdout, "Info: ", fmt, ##__VA_ARGS__); } 22f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 2381e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts/** 2481e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts * Initializes an empty, static list. 2581e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts */ 2681e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts#define list_init(free_fn) { .head = NULL, .tail = NULL, .freefn = free_fn } 2781e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts 2881e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts/** 2981e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts * given an item in the list, finds the offset for the container 3081e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts * it was stored in. 3181e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts * 3281e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts * @element The element from the list 3381e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts * @type The container type ie what you allocated that has the list_element structure in it. 3481e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts * @name The name of the field that is the list_element 3581e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts * 3681e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts */ 3781e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts#define list_entry(element, type, name) \ 3881e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts (type *)(((uint8_t *)element) - (uint8_t *)&(((type *)NULL)->name)) 3981e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts 4081e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts/** 4181e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts * Iterates over the list, do not free elements from the list when using this. 4281e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts * @list The list head to walk 4381e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts * @var The variable name for the cursor 4481e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts */ 4581e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts#define list_for_each(list, var) \ 4681e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts for(var = (list)->head; var != NULL; var = var->next) 4781e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts 4881e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts 49f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Robertstypedef struct hash_entry hash_entry; 50f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Robertstypedef enum key_dir key_dir; 51f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Robertstypedef enum data_type data_type; 52f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Robertstypedef enum rule_map_switch rule_map_switch; 530ae3a8a2d50799d0b91d992434cdd4d3151b0348William Robertstypedef enum map_match map_match; 54f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Robertstypedef struct key_map key_map; 55f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Robertstypedef struct kvp kvp; 56f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Robertstypedef struct rule_map rule_map; 57f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Robertstypedef struct policy_info policy_info; 5881e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Robertstypedef struct list_element list_element; 5981e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Robertstypedef struct list list; 6081e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Robertstypedef struct key_map_regex key_map_regex; 6181e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Robertstypedef struct file_info file_info; 62f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 630ae3a8a2d50799d0b91d992434cdd4d3151b0348William Robertsenum map_match { 640ae3a8a2d50799d0b91d992434cdd4d3151b0348William Roberts map_no_matches, 650ae3a8a2d50799d0b91d992434cdd4d3151b0348William Roberts map_input_matched, 660ae3a8a2d50799d0b91d992434cdd4d3151b0348William Roberts map_matched 670ae3a8a2d50799d0b91d992434cdd4d3151b0348William Roberts}; 680ae3a8a2d50799d0b91d992434cdd4d3151b0348William Roberts 690b820042e4bb9bb93790e0cf0812fd97d15ce7a5Stephen Smalleyconst char *map_match_str[] = { 700b820042e4bb9bb93790e0cf0812fd97d15ce7a5Stephen Smalley "do not match", 710b820042e4bb9bb93790e0cf0812fd97d15ce7a5Stephen Smalley "match on all inputs", 720b820042e4bb9bb93790e0cf0812fd97d15ce7a5Stephen Smalley "match on everything" 730b820042e4bb9bb93790e0cf0812fd97d15ce7a5Stephen Smalley}; 740b820042e4bb9bb93790e0cf0812fd97d15ce7a5Stephen Smalley 75f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts/** 76f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts * Whether or not the "key" from a key vaue pair is considered an 77f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts * input or an output. 78f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts */ 79f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Robertsenum key_dir { 80f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts dir_in, dir_out 81f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts}; 82f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 8381e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Robertsstruct list_element { 8481e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts list_element *next; 8581e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts}; 8681e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts 8781e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Robertsstruct list { 8881e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts list_element *head; 8981e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts list_element *tail; 9081e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts void (*freefn)(list_element *e); 9181e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts}; 9281e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts 9381e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Robertsstruct key_map_regex { 9481e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts pcre *compiled; 9581e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts pcre_extra *extra; 96f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts}; 97f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 98f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts/** 99f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts * The workhorse of the logic. This struct maps key value pairs to 100f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts * an associated set of meta data maintained in rule_map_new() 101f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts */ 102f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Robertsstruct key_map { 103f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts char *name; 104f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts key_dir dir; 105f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts char *data; 10681e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts key_map_regex regex; 1077bbdaefc7fe3364e39cdc8e7d1ab52e0de92327cWilliam Roberts bool (*fn_validate)(char *value, char **errmsg); 108f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts}; 109f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 110f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts/** 111f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts * Key value pair struct, this represents the raw kvp values coming 112f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts * from the rules files. 113f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts */ 114f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Robertsstruct kvp { 115f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts char *key; 116f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts char *value; 117f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts}; 118f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 119f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts/** 120f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts * Rules are made up of meta data and an associated set of kvp stored in a 121f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts * key_map array. 122f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts */ 123f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Robertsstruct rule_map { 12481e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts bool is_never_allow; 12581e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts list violations; 12681e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts list_element listify; 127f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts char *key; /** key value before hashing */ 128610a4b1c32490ac9f6f7ca0fafba8c182a542934William Roberts size_t length; /** length of the key map */ 129f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts int lineno; /** Line number rule was encounter on */ 13081e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts char *filename; /** File it was found in */ 131f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts key_map m[]; /** key value mapping */ 132f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts}; 133f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 134f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Robertsstruct hash_entry { 13581e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts list_element listify; 136f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts rule_map *r; /** The rule map to store at that location */ 137f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts}; 138f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 139f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts/** 140f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts * Data associated for a policy file 141f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts */ 142f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Robertsstruct policy_info { 143f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 144f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts char *policy_file_name; /** policy file path name */ 145f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts FILE *policy_file; /** file handle to the policy file */ 146f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts sepol_policydb_t *db; 147f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts sepol_policy_file_t *pf; 148f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts sepol_handle_t *handle; 149f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts sepol_context_t *con; 150f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts}; 151f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 15281e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Robertsstruct file_info { 15381e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts FILE *file; /** file itself */ 15481e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts const char *name; /** name of file. do not free, these are not alloc'd */ 15581e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts list_element listify; 15681e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts}; 15781e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts 15881e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Robertsstatic void input_file_list_freefn(list_element *e); 15981e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Robertsstatic void line_order_list_freefn(list_element *e); 16081e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Robertsstatic void rule_map_free(rule_map *rm, bool is_in_htable); 16181e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts 162f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts/** Set to !0 to enable verbose logging */ 163f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Robertsstatic int logging_verbose = 0; 164f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 165f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts/** file handle to the output file */ 16681e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Robertsstatic file_info out_file; 167f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 16881e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Robertsstatic list input_file_list = list_init(input_file_list_freefn); 169f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 170f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Robertsstatic policy_info pol = { 171f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts .policy_file_name = NULL, 172f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts .policy_file = NULL, 173f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts .db = NULL, 174f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts .pf = NULL, 175f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts .handle = NULL, 176f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts .con = NULL 177f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts}; 178f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 179f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts/** 18081e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts * Head pointer to a linked list of 18181e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts * rule map table entries (hash_entry), used for 18281e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts * preserving the order of entries 18381e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts * based on "first encounter" 18481e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts */ 18581e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Robertsstatic list line_order_list = list_init(line_order_list_freefn); 18681e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts 18781e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts/* 18881e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts * List of hash_entrys for never allow rules. 18981e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts */ 19081e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Robertsstatic list nallow_list = list_init(line_order_list_freefn); 19181e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts 1927bbdaefc7fe3364e39cdc8e7d1ab52e0de92327cWilliam Roberts/* validation call backs */ 1937bbdaefc7fe3364e39cdc8e7d1ab52e0de92327cWilliam Robertsstatic bool validate_bool(char *value, char **errmsg); 1947bbdaefc7fe3364e39cdc8e7d1ab52e0de92327cWilliam Robertsstatic bool validate_levelFrom(char *value, char **errmsg); 1957bbdaefc7fe3364e39cdc8e7d1ab52e0de92327cWilliam Robertsstatic bool validate_selinux_type(char *value, char **errmsg); 1967bbdaefc7fe3364e39cdc8e7d1ab52e0de92327cWilliam Robertsstatic bool validate_selinux_level(char *value, char **errmsg); 1977bbdaefc7fe3364e39cdc8e7d1ab52e0de92327cWilliam Roberts 19881e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts/** 199f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts * The heart of the mapping process, this must be updated if a new key value pair is added 200f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts * to a rule. 201f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts */ 202f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Robertskey_map rules[] = { 203f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts /*Inputs*/ 204d7eedeb89c9d59562e9e2d82102fd4b3adba7f30William Roberts { .name = "isSystemServer", .dir = dir_in, .fn_validate = validate_bool }, 205d7eedeb89c9d59562e9e2d82102fd4b3adba7f30William Roberts { .name = "isAutoPlayApp", .dir = dir_in, .fn_validate = validate_bool }, 206d7eedeb89c9d59562e9e2d82102fd4b3adba7f30William Roberts { .name = "isOwner", .dir = dir_in, .fn_validate = validate_bool }, 207d7eedeb89c9d59562e9e2d82102fd4b3adba7f30William Roberts { .name = "user", .dir = dir_in, }, 208d7eedeb89c9d59562e9e2d82102fd4b3adba7f30William Roberts { .name = "seinfo", .dir = dir_in, }, 209d7eedeb89c9d59562e9e2d82102fd4b3adba7f30William Roberts { .name = "name", .dir = dir_in, }, 210d7eedeb89c9d59562e9e2d82102fd4b3adba7f30William Roberts { .name = "path", .dir = dir_in, }, 211d7eedeb89c9d59562e9e2d82102fd4b3adba7f30William Roberts { .name = "isPrivApp", .dir = dir_in, .fn_validate = validate_bool }, 212f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts /*Outputs*/ 213d7eedeb89c9d59562e9e2d82102fd4b3adba7f30William Roberts { .name = "domain", .dir = dir_out, .fn_validate = validate_selinux_type }, 214d7eedeb89c9d59562e9e2d82102fd4b3adba7f30William Roberts { .name = "type", .dir = dir_out, .fn_validate = validate_selinux_type }, 215d7eedeb89c9d59562e9e2d82102fd4b3adba7f30William Roberts { .name = "levelFromUid", .dir = dir_out, .fn_validate = validate_bool }, 216d7eedeb89c9d59562e9e2d82102fd4b3adba7f30William Roberts { .name = "levelFrom", .dir = dir_out, .fn_validate = validate_levelFrom }, 217d7eedeb89c9d59562e9e2d82102fd4b3adba7f30William Roberts { .name = "level", .dir = dir_out, .fn_validate = validate_selinux_level }, 218fff2980a1ac2aca5966f6b54fa030309a0d98e0cWilliam Roberts}; 219f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 220f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts/** 22181e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts * Appends to the end of the list. 22281e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts * @list The list to append to 22381e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts * @e the element to append 224f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts */ 22581e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Robertsvoid list_append(list *list, list_element *e) { 22681e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts 22781e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts memset(e, 0, sizeof(*e)); 22881e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts 22981e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts if (list->head == NULL ) { 23081e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts list->head = list->tail = e; 23181e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts return; 23281e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts } 23381e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts 23481e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts list->tail->next = e; 23581e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts list->tail = e; 23681e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts return; 23781e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts} 238f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 239f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts/** 24081e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts * Free's all the elements in the specified list. 24181e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts * @list The list to free 242f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts */ 24381e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Robertsstatic void list_free(list *list) { 24481e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts 24581e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts list_element *tmp; 24681e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts list_element *cursor = list->head; 24781e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts 24881e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts while (cursor) { 24981e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts tmp = cursor; 25081e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts cursor = cursor->next; 25181e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts if (list->freefn) { 25281e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts list->freefn(tmp); 25381e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts } 25481e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts } 25581e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts} 25681e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts 25781e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts/* 25881e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts * called when the lists are freed 25981e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts */ 26081e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Robertsstatic void line_order_list_freefn(list_element *e) { 26181e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts hash_entry *h = list_entry(e, typeof(*h), listify); 26281e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts rule_map_free(h->r, true); 26381e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts free(h); 26481e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts} 26581e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts 26681e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Robertsstatic void input_file_list_freefn(list_element *e) { 26781e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts file_info *f = list_entry(e, typeof(*f), listify); 26881e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts 26981e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts if (f->file) { 27081e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts fclose(f->file); 27181e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts } 27281e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts free(f); 27381e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts} 274f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 275f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts/** 276f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts * Send a logging message to a file 277f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts * @param out 278f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts * Output file to send message too 279f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts * @param prefix 280f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts * A special prefix to write to the file, such as "Error:" 281f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts * @param fmt 282f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts * The printf style formatter to use, such as "%d" 283f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts */ 2841e8c061b053cdfd808c7a7649c78df4c33ded63dWilliam Robertsstatic void __attribute__ ((format(printf, 3, 4))) 2851e8c061b053cdfd808c7a7649c78df4c33ded63dWilliam Robertslog_msg(FILE *out, const char *prefix, const char *fmt, ...) { 2861e8c061b053cdfd808c7a7649c78df4c33ded63dWilliam Roberts 287f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts fprintf(out, "%s", prefix); 288f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts va_list args; 289f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts va_start(args, fmt); 290f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts vfprintf(out, fmt, args); 291f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts va_end(args); 292f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts} 293f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 294f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts/** 295f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts * Checks for a type in the policy. 296f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts * @param db 297f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts * The policy db to search 298f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts * @param type 299f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts * The type to search for 300f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts * @return 301f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts * 1 if the type is found, 0 otherwise. 302f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts * @warning 303f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts * This function always returns 1 if libsepol is not linked 304f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts * statically to this executable and LINK_SEPOL_STATIC is not 305f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts * defined. 306f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts */ 307ffd053ba93f2ddc0f97c8461a722035972f61f03William Robertsstatic int check_type(sepol_policydb_t *db, char *type) { 308f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 309f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts int rc = 1; 310f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts#if defined(LINK_SEPOL_STATIC) 311f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts policydb_t *d = (policydb_t *)db; 312f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts hashtab_datum_t dat; 313f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts dat = hashtab_search(d->p_types.table, type); 314f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts rc = (dat == NULL) ? 0 : 1; 315f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts#endif 316f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts return rc; 317f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts} 318f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 31981e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Robertsstatic bool match_regex(key_map *assert, const key_map *check) { 32081e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts 32181e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts char *tomatch = check->data; 32281e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts 32381e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts int ret = pcre_exec(assert->regex.compiled, assert->regex.extra, tomatch, 32481e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts strlen(tomatch), 0, 0, NULL, 0); 32581e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts 32681e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts /* 0 from pcre_exec means matched */ 32781e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts return !ret; 32881e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts} 32981e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts 33081e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Robertsstatic bool compile_regex(key_map *km, const char **errbuf, int *erroff) { 33181e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts 33281e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts size_t size; 33381e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts char *anchored; 33481e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts 33581e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts /* 33681e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts * Explicitly anchor all regex's 33781e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts * The size is the length of the string to anchor (km->data), the anchor 33881e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts * characters ^ and $ and the null byte. Hence strlen(km->data) + 3 33981e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts */ 34081e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts size = strlen(km->data) + 3; 34181e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts anchored = alloca(size); 34281e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts sprintf(anchored, "^%s$", km->data); 34381e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts 34481e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts km->regex.compiled = pcre_compile(anchored, PCRE_DOTALL, errbuf, erroff, 34581e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts NULL ); 34681e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts if (!km->regex.compiled) { 34781e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts return false; 34881e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts } 34981e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts 35081e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts km->regex.extra = pcre_study(km->regex.compiled, 0, errbuf); 35181e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts return true; 35281e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts} 35381e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts 3547bbdaefc7fe3364e39cdc8e7d1ab52e0de92327cWilliam Robertsstatic bool validate_bool(char *value, char **errmsg) { 3557bbdaefc7fe3364e39cdc8e7d1ab52e0de92327cWilliam Roberts 3567bbdaefc7fe3364e39cdc8e7d1ab52e0de92327cWilliam Roberts if (!strcmp("true", value) || !strcmp("false", value)) { 3577bbdaefc7fe3364e39cdc8e7d1ab52e0de92327cWilliam Roberts return true; 3587bbdaefc7fe3364e39cdc8e7d1ab52e0de92327cWilliam Roberts } 3597bbdaefc7fe3364e39cdc8e7d1ab52e0de92327cWilliam Roberts 3607bbdaefc7fe3364e39cdc8e7d1ab52e0de92327cWilliam Roberts *errmsg = "Expecting \"true\" or \"false\""; 3617bbdaefc7fe3364e39cdc8e7d1ab52e0de92327cWilliam Roberts return false; 3627bbdaefc7fe3364e39cdc8e7d1ab52e0de92327cWilliam Roberts} 3637bbdaefc7fe3364e39cdc8e7d1ab52e0de92327cWilliam Roberts 3647bbdaefc7fe3364e39cdc8e7d1ab52e0de92327cWilliam Robertsstatic bool validate_levelFrom(char *value, char **errmsg) { 3657bbdaefc7fe3364e39cdc8e7d1ab52e0de92327cWilliam Roberts 3667bbdaefc7fe3364e39cdc8e7d1ab52e0de92327cWilliam Roberts if(strcasecmp(value, "none") && strcasecmp(value, "all") && 3677bbdaefc7fe3364e39cdc8e7d1ab52e0de92327cWilliam Roberts strcasecmp(value, "app") && strcasecmp(value, "user")) { 3687bbdaefc7fe3364e39cdc8e7d1ab52e0de92327cWilliam Roberts *errmsg = "Expecting one of: \"none\", \"all\", \"app\" or \"user\""; 3697bbdaefc7fe3364e39cdc8e7d1ab52e0de92327cWilliam Roberts return false; 3707bbdaefc7fe3364e39cdc8e7d1ab52e0de92327cWilliam Roberts } 3717bbdaefc7fe3364e39cdc8e7d1ab52e0de92327cWilliam Roberts return true; 3727bbdaefc7fe3364e39cdc8e7d1ab52e0de92327cWilliam Roberts} 3737bbdaefc7fe3364e39cdc8e7d1ab52e0de92327cWilliam Roberts 3747bbdaefc7fe3364e39cdc8e7d1ab52e0de92327cWilliam Robertsstatic bool validate_selinux_type(char *value, char **errmsg) { 3757bbdaefc7fe3364e39cdc8e7d1ab52e0de92327cWilliam Roberts 3767bbdaefc7fe3364e39cdc8e7d1ab52e0de92327cWilliam Roberts /* 3777bbdaefc7fe3364e39cdc8e7d1ab52e0de92327cWilliam Roberts * No policy file present means we cannot check 3787bbdaefc7fe3364e39cdc8e7d1ab52e0de92327cWilliam Roberts * SE Linux types 3797bbdaefc7fe3364e39cdc8e7d1ab52e0de92327cWilliam Roberts */ 3807bbdaefc7fe3364e39cdc8e7d1ab52e0de92327cWilliam Roberts if (!pol.policy_file) { 3817bbdaefc7fe3364e39cdc8e7d1ab52e0de92327cWilliam Roberts return true; 3827bbdaefc7fe3364e39cdc8e7d1ab52e0de92327cWilliam Roberts } 3837bbdaefc7fe3364e39cdc8e7d1ab52e0de92327cWilliam Roberts 3847bbdaefc7fe3364e39cdc8e7d1ab52e0de92327cWilliam Roberts if(!check_type(pol.db, value)) { 3857bbdaefc7fe3364e39cdc8e7d1ab52e0de92327cWilliam Roberts *errmsg = "Expecting a valid SELinux type"; 3867bbdaefc7fe3364e39cdc8e7d1ab52e0de92327cWilliam Roberts return false; 3877bbdaefc7fe3364e39cdc8e7d1ab52e0de92327cWilliam Roberts } 3887bbdaefc7fe3364e39cdc8e7d1ab52e0de92327cWilliam Roberts 3897bbdaefc7fe3364e39cdc8e7d1ab52e0de92327cWilliam Roberts return true; 3907bbdaefc7fe3364e39cdc8e7d1ab52e0de92327cWilliam Roberts} 3917bbdaefc7fe3364e39cdc8e7d1ab52e0de92327cWilliam Roberts 3927bbdaefc7fe3364e39cdc8e7d1ab52e0de92327cWilliam Robertsstatic bool validate_selinux_level(char *value, char **errmsg) { 3937bbdaefc7fe3364e39cdc8e7d1ab52e0de92327cWilliam Roberts 3947bbdaefc7fe3364e39cdc8e7d1ab52e0de92327cWilliam Roberts /* 3957bbdaefc7fe3364e39cdc8e7d1ab52e0de92327cWilliam Roberts * No policy file present means we cannot check 3967bbdaefc7fe3364e39cdc8e7d1ab52e0de92327cWilliam Roberts * SE Linux MLS 3977bbdaefc7fe3364e39cdc8e7d1ab52e0de92327cWilliam Roberts */ 3987bbdaefc7fe3364e39cdc8e7d1ab52e0de92327cWilliam Roberts if (!pol.policy_file) { 3997bbdaefc7fe3364e39cdc8e7d1ab52e0de92327cWilliam Roberts return true; 4007bbdaefc7fe3364e39cdc8e7d1ab52e0de92327cWilliam Roberts } 4017bbdaefc7fe3364e39cdc8e7d1ab52e0de92327cWilliam Roberts 4027bbdaefc7fe3364e39cdc8e7d1ab52e0de92327cWilliam Roberts int ret = sepol_mls_check(pol.handle, pol.db, value); 4037bbdaefc7fe3364e39cdc8e7d1ab52e0de92327cWilliam Roberts if (ret < 0) { 4047bbdaefc7fe3364e39cdc8e7d1ab52e0de92327cWilliam Roberts *errmsg = "Expecting a valid SELinux MLS value"; 4057bbdaefc7fe3364e39cdc8e7d1ab52e0de92327cWilliam Roberts return false; 4067bbdaefc7fe3364e39cdc8e7d1ab52e0de92327cWilliam Roberts } 4077bbdaefc7fe3364e39cdc8e7d1ab52e0de92327cWilliam Roberts 4087bbdaefc7fe3364e39cdc8e7d1ab52e0de92327cWilliam Roberts return true; 4097bbdaefc7fe3364e39cdc8e7d1ab52e0de92327cWilliam Roberts} 4107bbdaefc7fe3364e39cdc8e7d1ab52e0de92327cWilliam Roberts 411f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts/** 412f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts * Validates a key_map against a set of enforcement rules, this 413f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts * function exits the application on a type that cannot be properly 414f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts * checked 415f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts * 416f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts * @param m 417f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts * The key map to check 418f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts * @param lineno 419f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts * The line number in the source file for the corresponding key map 420fff2980a1ac2aca5966f6b54fa030309a0d98e0cWilliam Roberts * @return 42181e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts * true if valid, false if invalid 422f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts */ 42381e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Robertsstatic bool key_map_validate(key_map *m, const char *filename, int lineno, 42481e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts bool is_neverallow) { 425f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 42681e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts int erroff; 42781e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts const char *errbuf; 42881e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts bool rc = true; 429f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts char *key = m->name; 430f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts char *value = m->data; 4317bbdaefc7fe3364e39cdc8e7d1ab52e0de92327cWilliam Roberts char *errmsg = NULL; 432f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 4330ae3a8a2d50799d0b91d992434cdd4d3151b0348William Roberts log_info("Validating %s=%s\n", key, value); 4340ae3a8a2d50799d0b91d992434cdd4d3151b0348William Roberts 43581e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts /* 43681e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts * Neverallows are completely skipped from sanity checking so you can match 43781e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts * un-unspecified inputs. 43881e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts */ 43981e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts if (is_neverallow) { 44081e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts if (!m->regex.compiled) { 44181e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts rc = compile_regex(m, &errbuf, &erroff); 44281e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts if (!rc) { 44381e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts log_error("Invalid regex on line %d : %s PCRE error: %s at offset %d", 44481e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts lineno, value, errbuf, erroff); 44581e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts } 44681e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts } 44781e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts goto out; 44881e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts } 44981e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts 4507bbdaefc7fe3364e39cdc8e7d1ab52e0de92327cWilliam Roberts /* If the key has a validation routine, call it */ 4517bbdaefc7fe3364e39cdc8e7d1ab52e0de92327cWilliam Roberts if (m->fn_validate) { 4527bbdaefc7fe3364e39cdc8e7d1ab52e0de92327cWilliam Roberts rc = m->fn_validate(value, &errmsg); 45338084146e0fd665b68c8c4ff131cae9d07ef5993Stephen Smalley 4547bbdaefc7fe3364e39cdc8e7d1ab52e0de92327cWilliam Roberts if (!rc) { 4557bbdaefc7fe3364e39cdc8e7d1ab52e0de92327cWilliam Roberts log_error("Could not validate key \"%s\" for value \"%s\" on line: %d in file: \"%s\": %s\n", key, value, 4567bbdaefc7fe3364e39cdc8e7d1ab52e0de92327cWilliam Roberts lineno, filename, errmsg); 457f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts } 458f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts } 459f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 4600ae3a8a2d50799d0b91d992434cdd4d3151b0348William Robertsout: 4610ae3a8a2d50799d0b91d992434cdd4d3151b0348William Roberts log_info("Key map validate returning: %d\n", rc); 4620ae3a8a2d50799d0b91d992434cdd4d3151b0348William Roberts return rc; 463f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts} 464f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 465f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts/** 466f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts * Prints a rule map back to a file 467f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts * @param fp 468f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts * The file handle to print too 469f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts * @param r 470f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts * The rule map to print 471f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts */ 472f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Robertsstatic void rule_map_print(FILE *fp, rule_map *r) { 473f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 474610a4b1c32490ac9f6f7ca0fafba8c182a542934William Roberts size_t i; 475f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts key_map *m; 476f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 477f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts for (i = 0; i < r->length; i++) { 478f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts m = &(r->m[i]); 479f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts if (i < r->length - 1) 480f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts fprintf(fp, "%s=%s ", m->name, m->data); 481f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts else 482f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts fprintf(fp, "%s=%s", m->name, m->data); 483f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts } 484f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts} 485f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 486f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts/** 487f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts * Compare two rule maps for equality 488f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts * @param rmA 489f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts * a rule map to check 490f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts * @param rmB 491f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts * a rule map to check 492f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts * @return 493ae23a1f36a9372bb23ebe21c8267d4192cb45a30William Roberts * a map_match enum indicating the result 494f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts */ 4950ae3a8a2d50799d0b91d992434cdd4d3151b0348William Robertsstatic map_match rule_map_cmp(rule_map *rmA, rule_map *rmB) { 496f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 497610a4b1c32490ac9f6f7ca0fafba8c182a542934William Roberts size_t i; 498610a4b1c32490ac9f6f7ca0fafba8c182a542934William Roberts size_t j; 499f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts int inputs_found = 0; 500f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts int num_of_matched_inputs = 0; 501f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts int input_mode = 0; 502610a4b1c32490ac9f6f7ca0fafba8c182a542934William Roberts size_t matches = 0; 503f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts key_map *mA; 504f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts key_map *mB; 505f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 506f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts for (i = 0; i < rmA->length; i++) { 507f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts mA = &(rmA->m[i]); 508f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 509f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts for (j = 0; j < rmB->length; j++) { 510f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts mB = &(rmB->m[j]); 511f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts input_mode = 0; 512f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 513f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts if (strcmp(mA->name, mB->name)) 514f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts continue; 515f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 516f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts if (strcmp(mA->data, mB->data)) 517f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts continue; 518f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 519f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts if (mB->dir != mA->dir) 520f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts continue; 521f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts else if (mB->dir == dir_in) { 522f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts input_mode = 1; 523f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts inputs_found++; 524f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts } 525f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 5260ae3a8a2d50799d0b91d992434cdd4d3151b0348William Roberts if (input_mode) { 5271e8c061b053cdfd808c7a7649c78df4c33ded63dWilliam Roberts log_info("Matched input lines: name=%s data=%s\n", mA->name, mA->data); 528f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts num_of_matched_inputs++; 5290ae3a8a2d50799d0b91d992434cdd4d3151b0348William Roberts } 530f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 531f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts /* Match found, move on */ 5321e8c061b053cdfd808c7a7649c78df4c33ded63dWilliam Roberts log_info("Matched lines: name=%s data=%s", mA->name, mA->data); 533f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts matches++; 534f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts break; 535f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts } 536f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts } 537f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 538f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts /* If they all matched*/ 5390ae3a8a2d50799d0b91d992434cdd4d3151b0348William Roberts if (matches == rmA->length) { 5400ae3a8a2d50799d0b91d992434cdd4d3151b0348William Roberts log_info("Rule map cmp MATCH\n"); 5410ae3a8a2d50799d0b91d992434cdd4d3151b0348William Roberts return map_matched; 5420ae3a8a2d50799d0b91d992434cdd4d3151b0348William Roberts } 543f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 544f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts /* They didn't all match but the input's did */ 5450ae3a8a2d50799d0b91d992434cdd4d3151b0348William Roberts else if (num_of_matched_inputs == inputs_found) { 5460ae3a8a2d50799d0b91d992434cdd4d3151b0348William Roberts log_info("Rule map cmp INPUT MATCH\n"); 5470ae3a8a2d50799d0b91d992434cdd4d3151b0348William Roberts return map_input_matched; 5480ae3a8a2d50799d0b91d992434cdd4d3151b0348William Roberts } 549f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 550f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts /* They didn't all match, and the inputs didn't match, ie it didn't 551f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts * match */ 5520ae3a8a2d50799d0b91d992434cdd4d3151b0348William Roberts else { 5530ae3a8a2d50799d0b91d992434cdd4d3151b0348William Roberts log_info("Rule map cmp NO MATCH\n"); 5540ae3a8a2d50799d0b91d992434cdd4d3151b0348William Roberts return map_no_matches; 5550ae3a8a2d50799d0b91d992434cdd4d3151b0348William Roberts } 556f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts} 557f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 558f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts/** 559f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts * Frees a rule map 560f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts * @param rm 561f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts * rule map to be freed. 5627d65b547d3959b9f98334cf0da6afe9ab418b17aWilliam Roberts * @is_in_htable 5637d65b547d3959b9f98334cf0da6afe9ab418b17aWilliam Roberts * True if the rule map has been added to the hash table, false 5647d65b547d3959b9f98334cf0da6afe9ab418b17aWilliam Roberts * otherwise. 5657d65b547d3959b9f98334cf0da6afe9ab418b17aWilliam Roberts */ 5667d65b547d3959b9f98334cf0da6afe9ab418b17aWilliam Robertsstatic void rule_map_free(rule_map *rm, bool is_in_htable) { 567f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 568610a4b1c32490ac9f6f7ca0fafba8c182a542934William Roberts size_t i; 569610a4b1c32490ac9f6f7ca0fafba8c182a542934William Roberts size_t len = rm->length; 570f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts for (i = 0; i < len; i++) { 571f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts key_map *m = &(rm->m[i]); 572f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts free(m->data); 57381e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts 57481e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts if (m->regex.compiled) { 57581e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts pcre_free(m->regex.compiled); 57681e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts } 57781e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts 57881e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts if (m->regex.extra) { 57981e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts pcre_free_study(m->regex.extra); 58081e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts } 581f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts } 582f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 5837d65b547d3959b9f98334cf0da6afe9ab418b17aWilliam Roberts /* 5847d65b547d3959b9f98334cf0da6afe9ab418b17aWilliam Roberts * hdestroy() frees comparsion keys for non glibc 5857d65b547d3959b9f98334cf0da6afe9ab418b17aWilliam Roberts * on GLIBC we always free on NON-GLIBC we free if 5867d65b547d3959b9f98334cf0da6afe9ab418b17aWilliam Roberts * it is not in the htable. 5877d65b547d3959b9f98334cf0da6afe9ab418b17aWilliam Roberts */ 5887d65b547d3959b9f98334cf0da6afe9ab418b17aWilliam Roberts if (rm->key) { 5895dbfdc0b0fec04d670912c4eed179983f98abe8arpcraig#ifdef __GLIBC__ 5907d65b547d3959b9f98334cf0da6afe9ab418b17aWilliam Roberts /* silence unused warning */ 5917d65b547d3959b9f98334cf0da6afe9ab418b17aWilliam Roberts (void)is_in_htable; 592f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts free(rm->key); 5937d65b547d3959b9f98334cf0da6afe9ab418b17aWilliam Roberts#else 5947d65b547d3959b9f98334cf0da6afe9ab418b17aWilliam Roberts if (!is_in_htable) { 5957d65b547d3959b9f98334cf0da6afe9ab418b17aWilliam Roberts free(rm->key); 5967d65b547d3959b9f98334cf0da6afe9ab418b17aWilliam Roberts } 5975dbfdc0b0fec04d670912c4eed179983f98abe8arpcraig#endif 5987d65b547d3959b9f98334cf0da6afe9ab418b17aWilliam Roberts } 599f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 60081e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts free(rm->filename); 601f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts free(rm); 602f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts} 603f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 604f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Robertsstatic void free_kvp(kvp *k) { 605f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts free(k->key); 606f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts free(k->value); 607f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts} 608f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 609f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts/** 61061846291746a3a3559f615ef3665312ccd2228c2William Roberts * Checks a rule_map for any variation of KVP's that shouldn't be allowed. 61181e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts * It builds an assertion failure list for each rule map. 61261846291746a3a3559f615ef3665312ccd2228c2William Roberts * Note that this function logs all errors. 61361846291746a3a3559f615ef3665312ccd2228c2William Roberts * 61461846291746a3a3559f615ef3665312ccd2228c2William Roberts * Current Checks: 61561846291746a3a3559f615ef3665312ccd2228c2William Roberts * 1. That a specified name entry should have a specified seinfo entry as well. 61681e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts * 2. That no rule violates a neverallow 61761846291746a3a3559f615ef3665312ccd2228c2William Roberts * @param rm 61861846291746a3a3559f615ef3665312ccd2228c2William Roberts * The rule map to check for validity. 61961846291746a3a3559f615ef3665312ccd2228c2William Roberts */ 62081e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Robertsstatic void rule_map_validate(rule_map *rm) { 62161846291746a3a3559f615ef3665312ccd2228c2William Roberts 62281e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts size_t i, j; 62381e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts const key_map *rule; 62481e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts key_map *nrule; 62581e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts hash_entry *e; 62681e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts rule_map *assert; 62781e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts list_element *cursor; 62881e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts 62981e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts list_for_each(&nallow_list, cursor) { 63081e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts e = list_entry(cursor, typeof(*e), listify); 63181e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts assert = e->r; 63281e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts 63381e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts size_t cnt = 0; 63481e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts 63581e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts for (j = 0; j < assert->length; j++) { 63681e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts nrule = &(assert->m[j]); 63781e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts 63881e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts // mark that nrule->name is for a null check 63981e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts bool is_null_check = !strcmp(nrule->data, "\"\""); 64061846291746a3a3559f615ef3665312ccd2228c2William Roberts 64181e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts for (i = 0; i < rm->length; i++) { 64281e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts rule = &(rm->m[i]); 64361846291746a3a3559f615ef3665312ccd2228c2William Roberts 64481e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts if (!strcmp(rule->name, nrule->name)) { 64581e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts 64681e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts /* the name was found, (data cannot be false) then it was specified */ 64781e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts is_null_check = false; 64881e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts 64981e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts if (match_regex(nrule, rule)) { 65081e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts cnt++; 65181e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts } 65281e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts } 65381e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts } 65481e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts 65581e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts /* 65681e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts * the nrule was marked in a null check and we never found a match on nrule, thus 65781e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts * it matched and we update the cnt 65881e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts */ 65981e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts if (is_null_check) { 66081e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts cnt++; 66181e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts } 66261846291746a3a3559f615ef3665312ccd2228c2William Roberts } 66381e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts if (cnt == assert->length) { 66481e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts list_append(&rm->violations, &assert->listify); 66561846291746a3a3559f615ef3665312ccd2228c2William Roberts } 66661846291746a3a3559f615ef3665312ccd2228c2William Roberts } 66761846291746a3a3559f615ef3665312ccd2228c2William Roberts} 66861846291746a3a3559f615ef3665312ccd2228c2William Roberts 66961846291746a3a3559f615ef3665312ccd2228c2William Roberts/** 670f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts * Given a set of key value pairs, this will construct a new rule map. 671f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts * On error this function calls exit. 672f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts * @param keys 673f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts * Keys from a rule line to map 674f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts * @param num_of_keys 675f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts * The length of the keys array 676f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts * @param lineno 677f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts * The line number the keys were extracted from 678f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts * @return 679f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts * A rule map pointer. 680f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts */ 68181e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Robertsstatic rule_map *rule_map_new(kvp keys[], size_t num_of_keys, int lineno, 68281e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts const char *filename, bool is_never_allow) { 683f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 684610a4b1c32490ac9f6f7ca0fafba8c182a542934William Roberts size_t i = 0, j = 0; 685f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts rule_map *new_map = NULL; 686f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts kvp *k = NULL; 687f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts key_map *r = NULL, *x = NULL; 688534fb0711d95615a77af23ffe643e8b720a527e6Stephen Smalley bool seen[KVP_NUM_OF_RULES]; 689534fb0711d95615a77af23ffe643e8b720a527e6Stephen Smalley 690534fb0711d95615a77af23ffe643e8b720a527e6Stephen Smalley for (i = 0; i < KVP_NUM_OF_RULES; i++) 691534fb0711d95615a77af23ffe643e8b720a527e6Stephen Smalley seen[i] = false; 692f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 693f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts new_map = calloc(1, (num_of_keys * sizeof(key_map)) + sizeof(rule_map)); 694f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts if (!new_map) 695f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts goto oom; 696f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 69781e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts new_map->is_never_allow = is_never_allow; 698f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts new_map->length = num_of_keys; 699f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts new_map->lineno = lineno; 70081e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts new_map->filename = strdup(filename); 70181e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts if (!new_map->filename) { 70281e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts goto oom; 70381e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts } 704f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 705f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts /* For all the keys in a rule line*/ 706f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts for (i = 0; i < num_of_keys; i++) { 707f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts k = &(keys[i]); 708f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts r = &(new_map->m[i]); 709f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 710f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts for (j = 0; j < KVP_NUM_OF_RULES; j++) { 711f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts x = &(rules[j]); 712f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 713f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts /* Only assign key name to map name */ 714f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts if (strcasecmp(k->key, x->name)) { 715f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts if (i == KVP_NUM_OF_RULES) { 716f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts log_error("No match for key: %s\n", k->key); 717f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts goto err; 718f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts } 719f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts continue; 720f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts } 721f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 722534fb0711d95615a77af23ffe643e8b720a527e6Stephen Smalley if (seen[j]) { 723534fb0711d95615a77af23ffe643e8b720a527e6Stephen Smalley log_error("Duplicated key: %s\n", k->key); 724534fb0711d95615a77af23ffe643e8b720a527e6Stephen Smalley goto err; 725534fb0711d95615a77af23ffe643e8b720a527e6Stephen Smalley } 726534fb0711d95615a77af23ffe643e8b720a527e6Stephen Smalley seen[j] = true; 727534fb0711d95615a77af23ffe643e8b720a527e6Stephen Smalley 728f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts memcpy(r, x, sizeof(key_map)); 729f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 730f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts /* Assign rule map value to one from file */ 731f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts r->data = strdup(k->value); 732f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts if (!r->data) 733f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts goto oom; 734f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 735f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts /* Enforce type check*/ 7360ae3a8a2d50799d0b91d992434cdd4d3151b0348William Roberts log_info("Validating keys!\n"); 73781e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts if (!key_map_validate(r, filename, lineno, new_map->is_never_allow)) { 738f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts log_error("Could not validate\n"); 739f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts goto err; 740f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts } 741f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 74281e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts /* 74381e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts * Only build key off of inputs with the exception of neverallows. 74481e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts * Neverallows are keyed off of all key value pairs, 74581e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts */ 74681e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts if (r->dir == dir_in || new_map->is_never_allow) { 747f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts char *tmp; 748b3ab56c2bf35214b6ef81027b0a08c09e3dc916fWilliam Roberts int key_len = strlen(k->key); 749b3ab56c2bf35214b6ef81027b0a08c09e3dc916fWilliam Roberts int val_len = strlen(k->value); 750b3ab56c2bf35214b6ef81027b0a08c09e3dc916fWilliam Roberts int l = (new_map->key) ? strlen(new_map->key) : 0; 751b3ab56c2bf35214b6ef81027b0a08c09e3dc916fWilliam Roberts l = l + key_len + val_len; 752f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts l += 1; 753f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 754f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts tmp = realloc(new_map->key, l); 755f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts if (!tmp) 756f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts goto oom; 757f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 758b3ab56c2bf35214b6ef81027b0a08c09e3dc916fWilliam Roberts if (!new_map->key) 759b3ab56c2bf35214b6ef81027b0a08c09e3dc916fWilliam Roberts memset(tmp, 0, l); 760b3ab56c2bf35214b6ef81027b0a08c09e3dc916fWilliam Roberts 761f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts new_map->key = tmp; 762f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 763b3ab56c2bf35214b6ef81027b0a08c09e3dc916fWilliam Roberts strncat(new_map->key, k->key, key_len); 764b3ab56c2bf35214b6ef81027b0a08c09e3dc916fWilliam Roberts strncat(new_map->key, k->value, val_len); 765f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts } 766f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts break; 767f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts } 768f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts free_kvp(k); 769f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts } 770f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 771f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts if (new_map->key == NULL) { 772f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts log_error("Strange, no keys found, input file corrupt perhaps?\n"); 773f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts goto err; 774f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts } 775f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 776f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts return new_map; 777f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 778f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Robertsoom: 779f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts log_error("Out of memory!\n"); 780f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Robertserr: 781f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts if(new_map) { 7827d65b547d3959b9f98334cf0da6afe9ab418b17aWilliam Roberts rule_map_free(new_map, false); 783f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts for (; i < num_of_keys; i++) { 784f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts k = &(keys[i]); 785f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts free_kvp(k); 786f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts } 787f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts } 788534fb0711d95615a77af23ffe643e8b720a527e6Stephen Smalley return NULL; 789f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts} 790f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 791f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts/** 792f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts * Print the usage of the program 793f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts */ 794f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Robertsstatic void usage() { 795f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts printf( 796f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts "checkseapp [options] <input file>\n" 797f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts "Processes an seapp_contexts file specified by argument <input file> (default stdin) " 798ae23a1f36a9372bb23ebe21c8267d4192cb45a30William Roberts "and allows later declarations to override previous ones on a match.\n" 799f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts "Options:\n" 800f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts "-h - print this help message\n" 801f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts "-v - enable verbose debugging informations\n" 802632972117a754dc64102cf81154ae6aed86febf3William Roberts "-p policy file - specify policy file for strict checking of output selectors against the policy\n" 80381e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts "-o output file - specify output file or - for stdout. No argument runs in silent mode and outputs nothing\n"); 804f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts} 805f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 806f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Robertsstatic void init() { 807f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 80881e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts bool has_out_file; 80981e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts list_element *cursor; 81081e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts file_info *tmp; 81181e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts 81281e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts /* input files if the list is empty, use stdin */ 81381e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts if (!input_file_list.head) { 81481e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts log_info("Using stdin for input\n"); 81581e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts tmp = malloc(sizeof(*tmp)); 81681e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts if (!tmp) { 81781e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts log_error("oom"); 818f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts exit(EXIT_FAILURE); 819f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts } 82081e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts tmp->name = "stdin"; 82181e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts tmp->file = stdin; 82281e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts list_append(&input_file_list, &(tmp->listify)); 823f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts } 82481e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts else { 82581e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts list_for_each(&input_file_list, cursor) { 82681e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts tmp = list_entry(cursor, typeof(*tmp), listify); 82781e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts 82881e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts log_info("Opening input file: \"%s\"\n", tmp->name); 82981e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts tmp->file = fopen(tmp->name, "r"); 83081e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts if (!tmp->file) { 83181e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts log_error("Could not open file: %s error: %s\n", tmp->name, 83281e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts strerror(errno)); 83381e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts exit(EXIT_FAILURE); 83481e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts } 835f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts } 836f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts } 837f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 83881e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts has_out_file = out_file.name != NULL; 83981e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts 84081e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts /* If output file is -, then use stdout, else open the path */ 84181e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts if (has_out_file && !strcmp(out_file.name, "-")) { 84281e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts out_file.file = stdout; 84381e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts out_file.name = "stdout"; 84481e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts } 84581e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts else if (has_out_file) { 84681e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts out_file.file = fopen(out_file.name, "w+"); 84781e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts } 848f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 84981e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts if (has_out_file && !out_file.file) { 85081e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts log_error("Could not open file: \"%s\" error: \"%s\"\n", out_file.name, 85181e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts strerror(errno)); 85281e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts exit(EXIT_FAILURE); 85381e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts } 85481e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts 85581e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts if (pol.policy_file_name) { 856f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts log_info("Opening policy file: %s\n", pol.policy_file_name); 857f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts pol.policy_file = fopen(pol.policy_file_name, "rb"); 858f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts if (!pol.policy_file) { 859f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts log_error("Could not open file: %s error: %s\n", 860f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts pol.policy_file_name, strerror(errno)); 861f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts exit(EXIT_FAILURE); 862f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts } 863f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 864f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts pol.handle = sepol_handle_create(); 865f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts if (!pol.handle) { 866f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts log_error("Could not create sepolicy handle: %s\n", 867f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts strerror(errno)); 868f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts exit(EXIT_FAILURE); 869f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts } 870f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 871f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts if (sepol_policy_file_create(&pol.pf) < 0) { 872f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts log_error("Could not create sepolicy file: %s!\n", 873f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts strerror(errno)); 874f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts exit(EXIT_FAILURE); 875f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts } 876f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 877f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts sepol_policy_file_set_fp(pol.pf, pol.policy_file); 878f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts sepol_policy_file_set_handle(pol.pf, pol.handle); 879f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 880f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts if (sepol_policydb_create(&pol.db) < 0) { 881f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts log_error("Could not create sepolicy db: %s!\n", 882f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts strerror(errno)); 883f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts exit(EXIT_FAILURE); 884f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts } 885f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 886f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts if (sepol_policydb_read(pol.db, pol.pf) < 0) { 887f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts log_error("Could not lod policy file to db: %s!\n", 888f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts strerror(errno)); 889f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts exit(EXIT_FAILURE); 890f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts } 891f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts } 892f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 89381e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts list_for_each(&input_file_list, cursor) { 89481e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts tmp = list_entry(cursor, typeof(*tmp), listify); 89581e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts log_info("Input file set to: \"%s\"\n", tmp->name); 89681e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts } 89781e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts 89881e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts log_info("Policy file set to: \"%s\"\n", 89981e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts (pol.policy_file_name == NULL) ? "None" : pol.policy_file_name); 90081e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts log_info("Output file set to: \"%s\"\n", out_file.name); 901f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 9020ae3a8a2d50799d0b91d992434cdd4d3151b0348William Roberts#if !defined(LINK_SEPOL_STATIC) 903a53ccf39c2793cb5a5894948de41242feea1ea31William Roberts log_warn("LINK_SEPOL_STATIC is not defined\n""Not checking types!"); 9040ae3a8a2d50799d0b91d992434cdd4d3151b0348William Roberts#endif 9050ae3a8a2d50799d0b91d992434cdd4d3151b0348William Roberts 906f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts} 907f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 908f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts/** 909f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts * Handle parsing and setting the global flags for the command line 910f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts * options. This function calls exit on failure. 911f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts * @param argc 912f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts * argument count 913f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts * @param argv 914f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts * argument list 915f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts */ 916f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Robertsstatic void handle_options(int argc, char *argv[]) { 917f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 918f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts int c; 91981e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts file_info *input_file; 920f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 921f26b6d427cce74bf22e3a45e2fcbe3f3bab6441cWilliam Roberts while ((c = getopt(argc, argv, "ho:p:v")) != -1) { 922f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts switch (c) { 923f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts case 'h': 924f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts usage(); 925f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts exit(EXIT_SUCCESS); 926f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts case 'o': 92781e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts out_file.name = optarg; 928f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts break; 929f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts case 'p': 930f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts pol.policy_file_name = optarg; 931f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts break; 932f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts case 'v': 933f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts log_set_verbose(); 934f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts break; 935f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts case '?': 936f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts if (optopt == 'o' || optopt == 'p') 937f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts log_error("Option -%c requires an argument.\n", optopt); 938f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts else if (isprint (optopt)) 939f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts log_error("Unknown option `-%c'.\n", optopt); 940f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts else { 941f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts log_error( 942f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts "Unknown option character `\\x%x'.\n", 943f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts optopt); 944f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts } 945f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts default: 946f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts exit(EXIT_FAILURE); 947f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts } 948f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts } 949f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 95081e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts for (c = optind; c < argc; c++) { 951f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 95281e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts input_file = calloc(1, sizeof(*input_file)); 95381e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts if (!input_file) { 95481e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts log_error("oom"); 95581e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts exit(EXIT_FAILURE); 95681e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts } 95781e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts input_file->name = argv[c]; 95881e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts list_append(&input_file_list, &input_file->listify); 959f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts } 960f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts} 961f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 962f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts/** 963f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts * Adds a rule to the hash table and to the ordered list if needed. 964f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts * @param rm 965f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts * The rule map to add. 966f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts */ 967f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Robertsstatic void rule_add(rule_map *rm) { 968f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 9690ae3a8a2d50799d0b91d992434cdd4d3151b0348William Roberts map_match cmp; 970f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts ENTRY e; 971f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts ENTRY *f; 972f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts hash_entry *entry; 973f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts hash_entry *tmp; 97481e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts list *list_to_addto; 975f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 976f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts e.key = rm->key; 977f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 9780ae3a8a2d50799d0b91d992434cdd4d3151b0348William Roberts log_info("Searching for key: %s\n", e.key); 979f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts /* Check to see if it has already been added*/ 980f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts f = hsearch(e, FIND); 981f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 982f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts /* 983f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts * Since your only hashing on a partial key, the inputs we need to handle 984f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts * when you want to override the outputs for a given input set, as well as 985f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts * checking for duplicate entries. 986f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts */ 987f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts if(f) { 9880ae3a8a2d50799d0b91d992434cdd4d3151b0348William Roberts log_info("Existing entry found!\n"); 989f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts tmp = (hash_entry *)f->data; 990f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts cmp = rule_map_cmp(rm, tmp->r); 9910b820042e4bb9bb93790e0cf0812fd97d15ce7a5Stephen Smalley log_error("Duplicate line detected in file: %s\n" 9920b820042e4bb9bb93790e0cf0812fd97d15ce7a5Stephen Smalley "Lines %d and %d %s!\n", 99381e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts rm->filename, tmp->r->lineno, rm->lineno, 9940b820042e4bb9bb93790e0cf0812fd97d15ce7a5Stephen Smalley map_match_str[cmp]); 9957d65b547d3959b9f98334cf0da6afe9ab418b17aWilliam Roberts rule_map_free(rm, false); 9960b820042e4bb9bb93790e0cf0812fd97d15ce7a5Stephen Smalley goto err; 997f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts } 998f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts /* It wasn't found, just add the rule map to the table */ 999f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts else { 1000f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 1001f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts entry = malloc(sizeof(hash_entry)); 1002f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts if (!entry) 1003f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts goto oom; 1004f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 1005f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts entry->r = rm; 1006f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts e.data = entry; 1007f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 1008f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts f = hsearch(e, ENTER); 1009f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts if(f == NULL) { 1010f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts goto oom; 1011f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts } 1012f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 1013f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts /* new entries must be added to the ordered list */ 1014f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts entry->r = rm; 101581e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts list_to_addto = rm->is_never_allow ? &nallow_list : &line_order_list; 101681e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts list_append(list_to_addto, &entry->listify); 1017f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts } 1018f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 1019f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts return; 1020f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Robertsoom: 1021f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts if (e.key) 1022f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts free(e.key); 1023f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts if (entry) 1024f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts free(entry); 1025f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts if (rm) 1026f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts free(rm); 1027f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts log_error("Out of memory in function: %s\n", __FUNCTION__); 1028f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Robertserr: 1029f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts exit(EXIT_FAILURE); 1030f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts} 1031f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 103281e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Robertsstatic void parse_file(file_info *in_file) { 1033f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 103481e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts char *p; 1035f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts size_t len; 103681e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts char *token; 103781e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts char *saveptr; 103881e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts bool is_never_allow; 103981e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts bool found_whitespace; 104081e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts 104181e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts size_t lineno = 0; 104281e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts char *name = NULL; 104381e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts char *value = NULL; 1044610a4b1c32490ac9f6f7ca0fafba8c182a542934William Roberts size_t token_cnt = 0; 1045f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 104681e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts char line_buf[BUFSIZ]; 104781e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts kvp keys[KVP_NUM_OF_RULES]; 1048f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 104981e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts while (fgets(line_buf, sizeof(line_buf) - 1, in_file->file)) { 1050f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts lineno++; 105181e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts is_never_allow = false; 105281e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts found_whitespace = false; 105381e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts log_info("Got line %zu\n", lineno); 1054f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts len = strlen(line_buf); 1055f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts if (line_buf[len - 1] == '\n') 1056f6647eb9f40a6a3d6dc3c1374d583e176a735498Alice Chu line_buf[len - 1] = '\0'; 1057f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts p = line_buf; 105881e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts 105981e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts /* neverallow lines must start with neverallow (ie ^neverallow) */ 106081e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts if (!strncasecmp(p, "neverallow", strlen("neverallow"))) { 106181e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts p += strlen("neverallow"); 106281e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts is_never_allow = true; 106381e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts } 106481e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts 106581e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts /* strip trailing whitespace skip comments */ 106681e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts while (isspace(*p)) { 1067f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts p++; 106881e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts found_whitespace = true; 106981e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts } 1070f6647eb9f40a6a3d6dc3c1374d583e176a735498Alice Chu if (*p == '#' || *p == '\0') 1071f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts continue; 1072f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 1073f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts token = strtok_r(p, " \t", &saveptr); 1074f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts if (!token) 1075f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts goto err; 1076f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 1077f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts token_cnt = 0; 1078f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts memset(keys, 0, sizeof(kvp) * KVP_NUM_OF_RULES); 1079f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts while (1) { 10800ae3a8a2d50799d0b91d992434cdd4d3151b0348William Roberts 1081f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts name = token; 1082f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts value = strchr(name, '='); 1083f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts if (!value) 1084f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts goto err; 1085f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts *value++ = 0; 1086f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 1087f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts keys[token_cnt].key = strdup(name); 1088f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts if (!keys[token_cnt].key) 1089f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts goto oom; 1090f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 1091f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts keys[token_cnt].value = strdup(value); 1092f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts if (!keys[token_cnt].value) 1093f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts goto oom; 1094f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 1095f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts token_cnt++; 1096f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 1097f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts token = strtok_r(NULL, " \t", &saveptr); 1098f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts if (!token) 1099f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts break; 1100f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 1101f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts } /*End token parsing */ 1102f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 110381e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts rule_map *r = rule_map_new(keys, token_cnt, lineno, in_file->name, is_never_allow); 1104534fb0711d95615a77af23ffe643e8b720a527e6Stephen Smalley if (!r) 1105534fb0711d95615a77af23ffe643e8b720a527e6Stephen Smalley goto err; 1106f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts rule_add(r); 1107f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 1108f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts } /* End file parsing */ 1109f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts return; 1110f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 1111f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Robertserr: 1112d5c3e5000937d0456101b18de0309223654304bcWilliam Roberts log_error("Reading file: \"%s\" line: %zu name: \"%s\" value: \"%s\"\n", 111381e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts in_file->name, lineno, name, value); 111481e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts if(found_whitespace && name && !strcasecmp(name, "neverallow")) { 111581e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts log_error("perhaps whitespace before neverallow\n"); 111681e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts } 1117f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts exit(EXIT_FAILURE); 1118f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Robertsoom: 1119f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts log_error("In function %s: Out of memory\n", __FUNCTION__); 1120f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts exit(EXIT_FAILURE); 1121f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts} 1122f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 1123f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts/** 112481e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts * Parses the seapp_contexts file and neverallow file 112581e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts * and adds them to the hash table and ordered list entries 112681e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts * when it encounters them. 112781e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts * Calls exit on failure. 112881e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts */ 112981e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Robertsstatic void parse() { 113081e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts 113181e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts file_info *current; 113281e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts list_element *cursor; 113381e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts list_for_each(&input_file_list, cursor) { 113481e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts current = list_entry(cursor, typeof(*current), listify); 113581e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts parse_file(current); 113681e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts } 113781e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts} 113881e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts 113981e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Robertsstatic void validate() { 114081e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts 114181e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts list_element *cursor, *v; 114281e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts bool found_issues = false; 114381e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts hash_entry *e; 114481e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts rule_map *r; 114581e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts list_for_each(&line_order_list, cursor) { 114681e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts e = list_entry(cursor, typeof(*e), listify); 114781e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts rule_map_validate(e->r); 114881e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts } 114981e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts 115081e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts list_for_each(&line_order_list, cursor) { 115181e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts e = list_entry(cursor, typeof(*e), listify); 115281e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts r = e->r; 115381e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts list_for_each(&r->violations, v) { 115481e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts found_issues = true; 115581e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts log_error("Rule in File \"%s\" on line %d: \"", e->r->filename, e->r->lineno); 115681e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts rule_map_print(stderr, e->r); 115781e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts r = list_entry(v, rule_map, listify); 115881e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts fprintf(stderr, "\" violates neverallow in File \"%s\" on line %d: \"", r->filename, r->lineno); 115981e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts rule_map_print(stderr, r); 116081e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts fprintf(stderr, "\"\n"); 116181e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts } 116281e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts } 116381e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts 116481e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts if (found_issues) { 116581e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts exit(EXIT_FAILURE); 116681e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts } 116781e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts} 116881e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts 116981e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts/** 1170f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts * Should be called after parsing to cause the printing of the rule_maps 1171f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts * stored in the ordered list, head first, which preserves the "first encountered" 1172f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts * ordering. 1173f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts */ 1174f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Robertsstatic void output() { 1175f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 117681e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts hash_entry *e; 117781e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts list_element *cursor; 1178f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 117981e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts if (!out_file.file) { 118081e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts log_info("No output file, not outputting.\n"); 118181e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts return; 118281e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts } 118381e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts 118481e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts list_for_each(&line_order_list, cursor) { 118581e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts e = list_entry(cursor, hash_entry, listify); 118681e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts rule_map_print(out_file.file, e->r); 118781e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts fprintf(out_file.file, "\n"); 1188f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts } 1189f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts} 1190f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 1191f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts/** 1192f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts * This function is registered to the at exit handler and should clean up 1193f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts * the programs dynamic resources, such as memory and fd's. 1194f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts */ 1195f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Robertsstatic void cleanup() { 1196f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 1197f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts /* Only close this when it was opened by me and not the crt */ 119881e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts if (out_file.name && strcmp(out_file.name, "stdout") && out_file.file) { 119981e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts log_info("Closing file: %s\n", out_file.name); 120081e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts fclose(out_file.file); 1201f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts } 1202f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 1203f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts if (pol.policy_file) { 1204f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 1205f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts log_info("Closing file: %s\n", pol.policy_file_name); 1206f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts fclose(pol.policy_file); 1207f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 1208f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts if (pol.db) 1209f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts sepol_policydb_free(pol.db); 1210f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 1211f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts if (pol.pf) 1212f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts sepol_policy_file_free(pol.pf); 1213f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 1214f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts if (pol.handle) 1215f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts sepol_handle_destroy(pol.handle); 1216f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts } 1217f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 121881e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts log_info("Freeing lists\n"); 121981e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts list_free(&input_file_list); 122081e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts list_free(&line_order_list); 122181e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts list_free(&nallow_list); 1222f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts hdestroy(); 1223f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts} 1224f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts 1225f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Robertsint main(int argc, char *argv[]) { 1226f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts if (!hcreate(TABLE_SIZE)) { 1227f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts log_error("Could not create hash table: %s\n", strerror(errno)); 1228f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts exit(EXIT_FAILURE); 1229f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts } 1230f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts atexit(cleanup); 1231f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts handle_options(argc, argv); 1232f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts init(); 1233f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts log_info("Starting to parse\n"); 1234f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts parse(); 1235f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts log_info("Parsing completed, generating output\n"); 123681e1f90cd13b262f9e3021f64ae3574b8f5cd5d0William Roberts validate(); 1237f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts output(); 1238f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts log_info("Success, generated output\n"); 1239f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts exit(EXIT_SUCCESS); 1240f0e0a94e032e55c13bc54f1cffe243f04872278eWilliam Roberts} 1241