Home | History | Annotate | Download | only in src
      1 #include <stdio.h>
      2 #include <stdlib.h>
      3 #include <ctype.h>
      4 #include <errno.h>
      5 
      6 #include <sepol/policydb/policydb.h>
      7 #include <sepol/policydb/conditional.h>
      8 
      9 #include "debug.h"
     10 #include "private.h"
     11 #include "dso.h"
     12 
     13 /* -- Deprecated -- */
     14 
     15 static char *strtrim(char *dest, char *source, int size)
     16 {
     17 	int i = 0;
     18 	char *ptr = source;
     19 	i = 0;
     20 	while (isspace(*ptr) && i < size) {
     21 		ptr++;
     22 		i++;
     23 	}
     24 	strncpy(dest, ptr, size);
     25 	for (i = strlen(dest) - 1; i > 0; i--) {
     26 		if (!isspace(dest[i]))
     27 			break;
     28 	}
     29 	dest[i + 1] = '\0';
     30 	return dest;
     31 }
     32 
     33 static int process_boolean(char *buffer, char *name, int namesize, int *val)
     34 {
     35 	char name1[BUFSIZ];
     36 	char *ptr = NULL;
     37 	char *tok = strtok_r(buffer, "=", &ptr);
     38 	if (tok) {
     39 		strncpy(name1, tok, BUFSIZ - 1);
     40 		strtrim(name, name1, namesize - 1);
     41 		if (name[0] == '#')
     42 			return 0;
     43 		tok = strtok_r(NULL, "\0", &ptr);
     44 		if (tok) {
     45 			while (isspace(*tok))
     46 				tok++;
     47 			*val = -1;
     48 			if (isdigit(tok[0]))
     49 				*val = atoi(tok);
     50 			else if (!strncasecmp(tok, "true", sizeof("true") - 1))
     51 				*val = 1;
     52 			else if (!strncasecmp
     53 				 (tok, "false", sizeof("false") - 1))
     54 				*val = 0;
     55 			if (*val != 0 && *val != 1) {
     56 				ERR(NULL, "illegal value for boolean "
     57 				    "%s=%s", name, tok);
     58 				return -1;
     59 			}
     60 
     61 		}
     62 	}
     63 	return 1;
     64 }
     65 
     66 static int load_booleans(struct policydb *policydb, const char *path,
     67 			 int *changesp)
     68 {
     69 	FILE *boolf;
     70 	char *buffer = NULL;
     71 	size_t size = 0;
     72 	char localbools[BUFSIZ];
     73 	char name[BUFSIZ];
     74 	int val;
     75 	int errors = 0, changes = 0;
     76 	struct cond_bool_datum *datum;
     77 
     78 	boolf = fopen(path, "r");
     79 	if (boolf == NULL)
     80 		goto localbool;
     81 
     82 #ifdef DARWIN
     83         if ((buffer = (char *)malloc(255 * sizeof(char))) == NULL) {
     84           ERR(NULL, "out of memory");
     85 	  return -1;
     86 	}
     87 
     88         while(fgets(buffer, 255, boolf) != NULL) {
     89 #else
     90 	while (getline(&buffer, &size, boolf) > 0) {
     91 #endif
     92 		int ret = process_boolean(buffer, name, sizeof(name), &val);
     93 		if (ret == -1)
     94 			errors++;
     95 		if (ret == 1) {
     96 			datum = hashtab_search(policydb->p_bools.table, name);
     97 			if (!datum) {
     98 				ERR(NULL, "unknown boolean %s", name);
     99 				errors++;
    100 				continue;
    101 			}
    102 			if (datum->state != val) {
    103 				datum->state = val;
    104 				changes++;
    105 			}
    106 		}
    107 	}
    108 	fclose(boolf);
    109       localbool:
    110 	snprintf(localbools, sizeof(localbools), "%s.local", path);
    111 	boolf = fopen(localbools, "r");
    112 	if (boolf != NULL) {
    113 
    114 #ifdef DARWIN
    115 
    116 	  while(fgets(buffer, 255, boolf) != NULL) {
    117 #else
    118 
    119 	    while (getline(&buffer, &size, boolf) > 0) {
    120 #endif
    121 			int ret =
    122 			    process_boolean(buffer, name, sizeof(name), &val);
    123 			if (ret == -1)
    124 				errors++;
    125 			if (ret == 1) {
    126 				datum =
    127 				    hashtab_search(policydb->p_bools.table,
    128 						   name);
    129 				if (!datum) {
    130 					ERR(NULL, "unknown boolean %s", name);
    131 					errors++;
    132 					continue;
    133 				}
    134 				if (datum->state != val) {
    135 					datum->state = val;
    136 					changes++;
    137 				}
    138 			}
    139 		}
    140 		fclose(boolf);
    141 	}
    142 	free(buffer);
    143 	if (errors)
    144 		errno = EINVAL;
    145 	*changesp = changes;
    146 	return errors ? -1 : 0;
    147 }
    148 
    149 int sepol_genbools(void *data, size_t len, char *booleans)
    150 {
    151 	struct policydb policydb;
    152 	struct policy_file pf;
    153 	int rc, changes = 0;
    154 
    155 	if (policydb_init(&policydb))
    156 		goto err;
    157 	if (policydb_from_image(NULL, data, len, &policydb) < 0)
    158 		goto err;
    159 
    160 	if (load_booleans(&policydb, booleans, &changes) < 0) {
    161 		WARN(NULL, "error while reading %s", booleans);
    162 	}
    163 
    164 	if (!changes)
    165 		goto out;
    166 
    167 	if (evaluate_conds(&policydb) < 0) {
    168 		ERR(NULL, "error while re-evaluating conditionals");
    169 		errno = EINVAL;
    170 		goto err_destroy;
    171 	}
    172 
    173 	policy_file_init(&pf);
    174 	pf.type = PF_USE_MEMORY;
    175 	pf.data = data;
    176 	pf.len = len;
    177 	rc = policydb_write(&policydb, &pf);
    178 	if (rc) {
    179 		ERR(NULL, "unable to write new binary policy image");
    180 		errno = EINVAL;
    181 		goto err_destroy;
    182 	}
    183 
    184       out:
    185 	policydb_destroy(&policydb);
    186 	return 0;
    187 
    188       err_destroy:
    189 	policydb_destroy(&policydb);
    190 
    191       err:
    192 	return -1;
    193 }
    194 
    195 int hidden sepol_genbools_policydb(policydb_t * policydb, const char *booleans)
    196 {
    197 	int rc, changes = 0;
    198 
    199 	rc = load_booleans(policydb, booleans, &changes);
    200 	if (!rc && changes)
    201 		rc = evaluate_conds(policydb);
    202 	if (rc)
    203 		errno = EINVAL;
    204 	return rc;
    205 }
    206 
    207 /* -- End Deprecated -- */
    208 
    209 int sepol_genbools_array(void *data, size_t len, char **names, int *values,
    210 			 int nel)
    211 {
    212 	struct policydb policydb;
    213 	struct policy_file pf;
    214 	int rc, i, errors = 0;
    215 	struct cond_bool_datum *datum;
    216 
    217 	/* Create policy database from image */
    218 	if (policydb_init(&policydb))
    219 		goto err;
    220 	if (policydb_from_image(NULL, data, len, &policydb) < 0)
    221 		goto err;
    222 
    223 	for (i = 0; i < nel; i++) {
    224 		datum = hashtab_search(policydb.p_bools.table, names[i]);
    225 		if (!datum) {
    226 			ERR(NULL, "boolean %s no longer in policy", names[i]);
    227 			errors++;
    228 			continue;
    229 		}
    230 		if (values[i] != 0 && values[i] != 1) {
    231 			ERR(NULL, "illegal value %d for boolean %s",
    232 			    values[i], names[i]);
    233 			errors++;
    234 			continue;
    235 		}
    236 		datum->state = values[i];
    237 	}
    238 
    239 	if (evaluate_conds(&policydb) < 0) {
    240 		ERR(NULL, "error while re-evaluating conditionals");
    241 		errno = EINVAL;
    242 		goto err_destroy;
    243 	}
    244 
    245 	policy_file_init(&pf);
    246 	pf.type = PF_USE_MEMORY;
    247 	pf.data = data;
    248 	pf.len = len;
    249 	rc = policydb_write(&policydb, &pf);
    250 	if (rc) {
    251 		ERR(NULL, "unable to write binary policy");
    252 		errno = EINVAL;
    253 		goto err_destroy;
    254 	}
    255 	if (errors) {
    256 		errno = EINVAL;
    257 		goto err_destroy;
    258 	}
    259 
    260 	policydb_destroy(&policydb);
    261 	return 0;
    262 
    263       err_destroy:
    264 	policydb_destroy(&policydb);
    265 
    266       err:
    267 	return -1;
    268 }
    269