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