xref: /aosp_15_r20/external/selinux/libsemanage/tests/test_fcontext.c (revision 2d543d20722ada2425b5bdab9d0d1d29470e7bba)
1 /*
2  * Authors: Jan Zarsky <[email protected]>
3  *
4  * Copyright (C) 2019 Red Hat, Inc.
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19  */
20 
21 #include "utilities.h"
22 #include "test_fcontext.h"
23 
24 char FCONTEXTS[] =
25     "/etc/selinux(/.*) -s system_u:object_r:first_t:s0\n"
26     "/etc/selinux/targeted -- system_u:object_r:second_t:s0\n"
27     "/etc/selinux(/.*) -b system_u:object_r:third_t:s0\n";
28 unsigned int FCONTEXTS_LEN = sizeof(FCONTEXTS);
29 
30 #define FCONTEXTS_COUNT 3
31 
32 #define FCONTEXT1_EXPR "/etc/selinux(/.*)"
33 #define FCONTEXT1_TYPE SEMANAGE_FCONTEXT_SOCK
34 #define FCONTEXT1_CON "system_u:object_r:first_t:s0"
35 
36 #define FCONTEXT2_EXPR "/etc/selinux/targeted"
37 #define FCONTEXT2_TYPE SEMANAGE_FCONTEXT_REG
38 #define FCONTEXT2_CON "system_u:object_r:second_t:s0"
39 
40 #define FCONTEXT3_EXPR "/etc/selinux(/.*)"
41 #define FCONTEXT3_TYPE SEMANAGE_FCONTEXT_BLOCK
42 #define FCONTEXT3_CON "system_u:object_r:third_t:s0"
43 
44 #define FCONTEXT_NONEXISTENT_EXPR "/asdf"
45 #define FCONTEXT_NONEXISTENT_TYPE SEMANAGE_FCONTEXT_ALL
46 
47 /* fcontext_record.h */
48 static void test_fcontext_compare(void);
49 static void test_fcontext_compare2(void);
50 static void test_fcontext_key_create(void);
51 static void test_fcontext_key_extract(void);
52 static void test_fcontext_get_set_expr(void);
53 static void test_fcontext_get_set_type(void);
54 static void test_fcontext_get_type_str(void);
55 static void test_fcontext_get_set_con(void);
56 static void test_fcontext_create(void);
57 static void test_fcontext_clone(void);
58 
59 /* fcontext_policy.h */
60 static void test_fcontext_query(void);
61 static void test_fcontext_exists(void);
62 static void test_fcontext_count(void);
63 static void test_fcontext_iterate(void);
64 static void test_fcontext_list(void);
65 
66 /* fcontext_local.h */
67 static void test_fcontext_modify_del_local(void);
68 static void test_fcontext_query_local(void);
69 static void test_fcontext_exists_local(void);
70 static void test_fcontext_count_local(void);
71 static void test_fcontext_iterate_local(void);
72 static void test_fcontext_list_local(void);
73 
74 extern semanage_handle_t *sh;
75 
write_file_contexts(const char * data,unsigned int data_len)76 static int write_file_contexts(const char *data, unsigned int data_len)
77 {
78 	FILE *fptr = fopen("test-policy/store/active/file_contexts", "w+");
79 
80 	if (!fptr) {
81 		perror("fopen");
82 		return -1;
83 	}
84 
85 	if (fwrite(data, data_len, 1, fptr) != 1) {
86 		perror("fwrite");
87 		fclose(fptr);
88 		return -1;
89 	}
90 
91 	fclose(fptr);
92 
93 	return 0;
94 }
95 
fcontext_test_init(void)96 int fcontext_test_init(void)
97 {
98 	if (create_test_store() < 0) {
99 		fprintf(stderr, "Could not create test store\n");
100 		return 1;
101 	}
102 
103 	if (write_test_policy_from_file("test_fcontext.policy") < 0) {
104 		fprintf(stderr, "Could not write test policy\n");
105 		return 1;
106 	}
107 
108 	if (write_file_contexts(FCONTEXTS, FCONTEXTS_LEN) < 0) {
109 		fprintf(stderr, "Could not write file contexts\n");
110 		return 1;
111 	}
112 
113 	return 0;
114 }
115 
fcontext_test_cleanup(void)116 int fcontext_test_cleanup(void)
117 {
118 	if (destroy_test_store() < 0) {
119 		fprintf(stderr, "Could not destroy test store\n");
120 		return 1;
121 	}
122 
123 	return 0;
124 }
125 
fcontext_add_tests(CU_pSuite suite)126 int fcontext_add_tests(CU_pSuite suite)
127 {
128 	CU_add_test(suite, "test_fcontext_compare", test_fcontext_compare);
129 	CU_add_test(suite, "test_fcontext_compare2", test_fcontext_compare2);
130 	CU_add_test(suite, "test_fcontext_key_create",
131 		    test_fcontext_key_create);
132 	CU_add_test(suite, "test_fcontext_key_extract",
133 		    test_fcontext_key_extract);
134 	CU_add_test(suite, "test_fcontext_get_set_expr",
135 		    test_fcontext_get_set_expr);
136 	CU_add_test(suite, "test_fcontext_get_set_type",
137 		    test_fcontext_get_set_type);
138 	CU_add_test(suite, "test_fcontext_get_type_str",
139 		    test_fcontext_get_type_str);
140 	CU_add_test(suite, "test_fcontext_get_set_con",
141 		    test_fcontext_get_set_con);
142 	CU_add_test(suite, "test_fcontext_create", test_fcontext_create);
143 	CU_add_test(suite, "test_fcontext_clone", test_fcontext_clone);
144 
145 	CU_add_test(suite, "test_fcontext_query", test_fcontext_query);
146 	CU_add_test(suite, "test_fcontext_exists", test_fcontext_exists);
147 	CU_add_test(suite, "test_fcontext_count", test_fcontext_count);
148 	CU_add_test(suite, "test_fcontext_iterate", test_fcontext_iterate);
149 	CU_add_test(suite, "test_fcontext_list", test_fcontext_list);
150 	CU_add_test(suite, "test_fcontext_modify_del_local",
151 		    test_fcontext_modify_del_local);
152 	CU_add_test(suite, "test_fcontext_query_local",
153 		    test_fcontext_query_local);
154 	CU_add_test(suite, "test_fcontext_exists_local",
155 		    test_fcontext_exists_local);
156 	CU_add_test(suite, "test_fcontext_count_local",
157 		    test_fcontext_count_local);
158 	CU_add_test(suite, "test_fcontext_iterate_local",
159 		    test_fcontext_iterate_local);
160 	CU_add_test(suite, "test_fcontext_list_local",
161 		    test_fcontext_list_local);
162 
163 	return 0;
164 }
165 
166 /* Helpers */
167 
get_fcontext_nth(int idx)168 static semanage_fcontext_t *get_fcontext_nth(int idx)
169 {
170 	semanage_fcontext_t **records;
171 	semanage_fcontext_t *fcontext;
172 	unsigned int count;
173 
174 	if (idx == I_NULL)
175 		return NULL;
176 
177 	CU_ASSERT_FATAL(semanage_fcontext_list(sh, &records, &count) >= 0);
178 	CU_ASSERT_FATAL(count >= (unsigned int) idx + 1);
179 
180 	fcontext = records[idx];
181 
182 	for (unsigned int i = 0; i < count; i++)
183 		if (i != (unsigned int) idx)
184 			semanage_fcontext_free(records[i]);
185 
186 	free(records);
187 
188 	return fcontext;
189 }
190 
get_fcontext_key_nth(int idx)191 static semanage_fcontext_key_t *get_fcontext_key_nth(int idx)
192 {
193 	semanage_fcontext_key_t *key;
194 	semanage_fcontext_t *fcontext;
195 
196 	if (idx == I_NULL)
197 		return NULL;
198 
199 	fcontext = get_fcontext_nth(idx);
200 
201 	CU_ASSERT_FATAL(semanage_fcontext_key_extract(sh, fcontext, &key) >= 0);
202 	CU_ASSERT_PTR_NOT_NULL_FATAL(key);
203 
204 	semanage_fcontext_free(fcontext);
205 
206 	return key;
207 }
208 
add_local_fcontext(int fcontext_idx)209 static void add_local_fcontext(int fcontext_idx)
210 {
211 	semanage_fcontext_t *fcontext;
212 	semanage_fcontext_key_t *key = NULL;
213 
214 	CU_ASSERT_FATAL(fcontext_idx != I_NULL);
215 
216 	fcontext = get_fcontext_nth(fcontext_idx);
217 
218 	CU_ASSERT_FATAL(semanage_fcontext_key_extract(sh, fcontext, &key) >= 0);
219 	CU_ASSERT_PTR_NOT_NULL_FATAL(key);
220 
221 	CU_ASSERT_FATAL(semanage_fcontext_modify_local(sh, key, fcontext) >= 0);
222 
223 	/* cleanup */
224 	semanage_fcontext_key_free(key);
225 	semanage_fcontext_free(fcontext);
226 }
227 
delete_local_fcontext(int fcontext_idx)228 static void delete_local_fcontext(int fcontext_idx)
229 {
230 	semanage_fcontext_key_t *key = NULL;
231 
232 	CU_ASSERT_FATAL(fcontext_idx != I_NULL);
233 
234 	key = get_fcontext_key_nth(fcontext_idx);
235 
236 	CU_ASSERT_FATAL(semanage_fcontext_del_local(sh, key) >= 0);
237 
238 	semanage_fcontext_key_free(key);
239 }
240 
get_fcontext_key_from_str(const char * str,int type)241 static semanage_fcontext_key_t *get_fcontext_key_from_str(const char *str, int type)
242 {
243 	semanage_fcontext_key_t *key;
244 	int res;
245 
246 	if (str == NULL)
247 		return NULL;
248 
249 	res = semanage_fcontext_key_create(sh, str, type, &key);
250 
251 	CU_ASSERT_FATAL(res >= 0);
252 	CU_ASSERT_PTR_NOT_NULL_FATAL(key);
253 
254 	return key;
255 }
256 
257 /* Function semanage_fcontext_compare */
test_fcontext_compare(void)258 static void test_fcontext_compare(void)
259 {
260 	semanage_fcontext_t *fcontext;
261 	semanage_fcontext_key_t *key1;
262 	semanage_fcontext_key_t *key2;
263 	semanage_fcontext_key_t *key3;
264 
265 	/* setup */
266 	setup_handle(SH_CONNECT);
267 
268 	fcontext = get_fcontext_nth(I_FIRST);
269 
270 	key1 = get_fcontext_key_nth(I_FIRST);
271 	key2 = get_fcontext_key_nth(I_SECOND);
272 	key3 = get_fcontext_key_nth(I_THIRD);
273 
274 	/* test */
275 	CU_ASSERT(semanage_fcontext_compare(fcontext, key1) == 0);
276 	CU_ASSERT(semanage_fcontext_compare(fcontext, key2) < 0);
277 	CU_ASSERT(semanage_fcontext_compare(fcontext, key3) > 0);
278 
279 	/* cleanup */
280 	semanage_fcontext_free(fcontext);
281 	semanage_fcontext_key_free(key1);
282 	semanage_fcontext_key_free(key2);
283 	semanage_fcontext_key_free(key3);
284 	cleanup_handle(SH_CONNECT);
285 }
286 
287 /* Function semanage_fcontext_compare2 */
test_fcontext_compare2(void)288 static void test_fcontext_compare2(void)
289 {
290 	semanage_fcontext_t *fcontext;
291 	semanage_fcontext_t *fcontext1;
292 	semanage_fcontext_t *fcontext2;
293 	semanage_fcontext_t *fcontext3;
294 
295 	/* setup */
296 	setup_handle(SH_CONNECT);
297 
298 	fcontext = get_fcontext_nth(I_FIRST);
299 	fcontext1 = get_fcontext_nth(I_FIRST);
300 	fcontext2 = get_fcontext_nth(I_SECOND);
301 	fcontext3 = get_fcontext_nth(I_THIRD);
302 
303 	/* test */
304 	CU_ASSERT(semanage_fcontext_compare2(fcontext, fcontext1) == 0);
305 	CU_ASSERT(semanage_fcontext_compare2(fcontext, fcontext2) < 0);
306 	CU_ASSERT(semanage_fcontext_compare2(fcontext, fcontext3) > 0);
307 
308 	/* cleanup */
309 	semanage_fcontext_free(fcontext);
310 	semanage_fcontext_free(fcontext1);
311 	semanage_fcontext_free(fcontext2);
312 	semanage_fcontext_free(fcontext3);
313 	cleanup_handle(SH_CONNECT);
314 }
315 
316 /* Function semanage_fcontext_key_create */
test_fcontext_key_create(void)317 static void test_fcontext_key_create(void)
318 {
319 	semanage_fcontext_key_t *key = NULL;
320 
321 	/* setup */
322 	setup_handle(SH_CONNECT);
323 
324 	/* test */
325 	CU_ASSERT(semanage_fcontext_key_create(sh, "", SEMANAGE_FCONTEXT_ALL,
326 					       &key) >= 0);
327 	CU_ASSERT_PTR_NOT_NULL(key);
328 
329 	semanage_fcontext_key_free(key);
330 
331 	key = NULL;
332 
333 	CU_ASSERT(semanage_fcontext_key_create(sh, "testfcontext",
334 					     SEMANAGE_FCONTEXT_ALL, &key) >= 0);
335 	CU_ASSERT_PTR_NOT_NULL(key);
336 
337 	semanage_fcontext_key_free(key);
338 
339 	/* cleanup */
340 	cleanup_handle(SH_CONNECT);
341 }
342 
343 /* Function semanage_fcontext_key_extract */
test_fcontext_key_extract(void)344 static void test_fcontext_key_extract(void)
345 {
346 	semanage_fcontext_t *fcontext;
347 	semanage_fcontext_key_t *key;
348 
349 	/* setup */
350 	setup_handle(SH_CONNECT);
351 	fcontext = get_fcontext_nth(I_FIRST);
352 
353 	/* test */
354 	CU_ASSERT(semanage_fcontext_key_extract(sh, fcontext, &key) >= 0);
355 	CU_ASSERT_PTR_NOT_NULL(key);
356 
357 	/* cleanup */
358 	semanage_fcontext_key_free(key);
359 	semanage_fcontext_free(fcontext);
360 	cleanup_handle(SH_CONNECT);
361 }
362 
363 /* Function semanage_fcontext_get_expr, semanage_fcontext_set_expr */
test_fcontext_get_set_expr(void)364 static void test_fcontext_get_set_expr(void)
365 {
366 	semanage_fcontext_t *fcontext;
367 	const char *expr = NULL;
368 	const char *expr_exp = "/asdf";
369 
370 	/* setup */
371 	setup_handle(SH_CONNECT);
372 	fcontext = get_fcontext_nth(I_FIRST);
373 
374 	/* test */
375 	CU_ASSERT(semanage_fcontext_set_expr(sh, fcontext, expr_exp) >= 0);
376 	expr = semanage_fcontext_get_expr(fcontext);
377 	CU_ASSERT_PTR_NOT_NULL(expr);
378 	assert(expr);
379 	CU_ASSERT_STRING_EQUAL(expr, expr_exp);
380 
381 	/* cleanup */
382 	semanage_fcontext_free(fcontext);
383 	cleanup_handle(SH_CONNECT);
384 }
385 
386 /* Function semanage_fcontext_get_type, semanage_fcontext_set_type */
test_fcontext_get_set_type(void)387 static void test_fcontext_get_set_type(void)
388 {
389 	semanage_fcontext_t *fcontext;
390 	int type_exp = SEMANAGE_FCONTEXT_SOCK;
391 	int type;
392 
393 	/* setup */
394 	setup_handle(SH_CONNECT);
395 	fcontext = get_fcontext_nth(I_FIRST);
396 
397 	/* test */
398 	semanage_fcontext_set_type(fcontext, type_exp);
399 	type = semanage_fcontext_get_type(fcontext);
400 	CU_ASSERT(type == type_exp);
401 
402 	/* cleanup */
403 	semanage_fcontext_free(fcontext);
404 	cleanup_handle(SH_CONNECT);
405 }
406 
407 /* Function semanage_fcontext_get_type_str */
helper_fcontext_get_type_str(int type,const char * exp_str)408 static void helper_fcontext_get_type_str(int type, const char *exp_str)
409 {
410 	CU_ASSERT_STRING_EQUAL(semanage_fcontext_get_type_str(type), exp_str);
411 }
412 
test_fcontext_get_type_str(void)413 static void test_fcontext_get_type_str(void)
414 {
415 	helper_fcontext_get_type_str(SEMANAGE_FCONTEXT_ALL, "all files");
416 	helper_fcontext_get_type_str(SEMANAGE_FCONTEXT_REG, "regular file");
417 	helper_fcontext_get_type_str(SEMANAGE_FCONTEXT_DIR, "directory");
418 	helper_fcontext_get_type_str(SEMANAGE_FCONTEXT_CHAR,
419 				     "character device");
420 	helper_fcontext_get_type_str(SEMANAGE_FCONTEXT_BLOCK, "block device");
421 	helper_fcontext_get_type_str(SEMANAGE_FCONTEXT_SOCK, "socket");
422 	helper_fcontext_get_type_str(SEMANAGE_FCONTEXT_LINK, "symbolic link");
423 	helper_fcontext_get_type_str(SEMANAGE_FCONTEXT_PIPE, "named pipe");
424 
425 	helper_fcontext_get_type_str(SEMANAGE_FCONTEXT_ALL - 1, "????");
426 	helper_fcontext_get_type_str(SEMANAGE_FCONTEXT_PIPE + 1, "????");
427 }
428 
429 /* Function semanage_fcontext_get_con, semanage_fcontext_set_con */
helper_fcontext_get_set_con(level_t level,int fcontext_idx,const char * con_str)430 static void helper_fcontext_get_set_con(level_t level, int fcontext_idx,
431 				 const char *con_str)
432 {
433 	semanage_fcontext_t *fcontext;
434 	semanage_context_t *con = NULL;
435 	semanage_context_t *new_con = NULL;
436 
437 	/* setup */
438 	setup_handle(level);
439 	fcontext = get_fcontext_nth(fcontext_idx);
440 
441 	if (con_str != NULL) {
442 		CU_ASSERT(semanage_context_from_string(sh, con_str, &con) >= 0);
443 		CU_ASSERT_PTR_NOT_NULL(con);
444 	} else {
445 		con = NULL;
446 	}
447 
448 	/* test */
449 	CU_ASSERT(semanage_fcontext_set_con(sh, fcontext, con) >= 0);
450 	new_con = semanage_fcontext_get_con(fcontext);
451 
452 	if (con_str != NULL) {
453 		CU_ASSERT_CONTEXT_EQUAL(con, new_con);
454 	} else {
455 		CU_ASSERT_PTR_NULL(new_con);
456 	}
457 
458 	/* cleanup */
459 	semanage_context_free(con);
460 	semanage_fcontext_free(fcontext);
461 	cleanup_handle(level);
462 }
463 
test_fcontext_get_set_con(void)464 static void test_fcontext_get_set_con(void)
465 {
466 	helper_fcontext_get_set_con(SH_CONNECT, I_FIRST, NULL);
467 	helper_fcontext_get_set_con(SH_CONNECT, I_FIRST,
468 				    "user_u:role_r:type_t:s0");
469 	helper_fcontext_get_set_con(SH_CONNECT, I_SECOND,
470 				    "user_u:role_r:type_t:s0");
471 	helper_fcontext_get_set_con(SH_TRANS, I_FIRST, NULL);
472 	helper_fcontext_get_set_con(SH_TRANS, I_FIRST,
473 				    "user_u:role_r:type_t:s0");
474 	helper_fcontext_get_set_con(SH_TRANS, I_SECOND,
475 				    "user_u:role_r:type_t:s0");
476 }
477 
478 /* Function semanage_fcontext_create */
helper_fcontext_create(level_t level)479 static void helper_fcontext_create(level_t level)
480 {
481 	semanage_fcontext_t *fcontext;
482 
483 	/* setup */
484 	setup_handle(level);
485 
486 	/* test */
487 	CU_ASSERT(semanage_fcontext_create(sh, &fcontext) >= 0);
488 	CU_ASSERT_PTR_NULL(semanage_fcontext_get_expr(fcontext));
489 	CU_ASSERT(semanage_fcontext_get_type(fcontext)
490 		  == SEMANAGE_FCONTEXT_ALL);
491 	CU_ASSERT_PTR_NULL(semanage_fcontext_get_con(fcontext));
492 
493 	/* cleanup */
494 	semanage_fcontext_free(fcontext);
495 	cleanup_handle(level);
496 }
497 
test_fcontext_create(void)498 static void test_fcontext_create(void)
499 {
500 	helper_fcontext_create(SH_NULL);
501 	helper_fcontext_create(SH_HANDLE);
502 	helper_fcontext_create(SH_CONNECT);
503 	helper_fcontext_create(SH_TRANS);
504 }
505 
506 /* Function semanage_fcontext_clone */
helper_fcontext_clone(level_t level,int fcontext_idx)507 static void helper_fcontext_clone(level_t level, int fcontext_idx)
508 {
509 	semanage_fcontext_t *fcontext;
510 	semanage_fcontext_t *fcontext_clone;
511 	const char *expr;
512 	const char *expr_clone;
513 	int type;
514 	int type_clone;
515 	semanage_context_t *con;
516 	semanage_context_t *con_clone;
517 
518 	/* setup */
519 	setup_handle(level);
520 	fcontext = get_fcontext_nth(fcontext_idx);
521 
522 	/* test */
523 	CU_ASSERT(semanage_fcontext_clone(sh, fcontext, &fcontext_clone) >= 0);
524 
525 	expr = semanage_fcontext_get_expr(fcontext);
526 	expr_clone = semanage_fcontext_get_expr(fcontext_clone);
527 	CU_ASSERT_STRING_EQUAL(expr, expr_clone);
528 
529 	type = semanage_fcontext_get_type(fcontext);
530 	type_clone = semanage_fcontext_get_type(fcontext_clone);
531 	CU_ASSERT_EQUAL(type, type_clone);
532 
533 	con = semanage_fcontext_get_con(fcontext);
534 	con_clone = semanage_fcontext_get_con(fcontext_clone);
535 	CU_ASSERT_CONTEXT_EQUAL(con, con_clone);
536 
537 	/* cleanup */
538 	semanage_fcontext_free(fcontext);
539 	semanage_fcontext_free(fcontext_clone);
540 	cleanup_handle(level);
541 }
542 
test_fcontext_clone(void)543 static void test_fcontext_clone(void)
544 {
545 	helper_fcontext_clone(SH_CONNECT, I_FIRST);
546 	helper_fcontext_clone(SH_CONNECT, I_SECOND);
547 	helper_fcontext_clone(SH_TRANS, I_FIRST);
548 	helper_fcontext_clone(SH_TRANS, I_SECOND);
549 }
550 
551 /* Function semanage_fcontext_query */
helper_fcontext_query(level_t level,const char * fcontext_expr,int fcontext_type,int exp_res)552 static void helper_fcontext_query(level_t level, const char *fcontext_expr,
553 			   int fcontext_type, int exp_res)
554 {
555 	semanage_fcontext_key_t *key;
556 	semanage_fcontext_t *resp = (void *) 42;
557 	int res;
558 
559 	/* setup */
560 	setup_handle(level);
561 	key = get_fcontext_key_from_str(fcontext_expr, fcontext_type);
562 
563 	/* test */
564 	res = semanage_fcontext_query(sh, key, &resp);
565 
566 	if (exp_res >= 0) {
567 		CU_ASSERT(res >= 0);
568 		const char *expr = semanage_fcontext_get_expr(resp);
569 		CU_ASSERT_STRING_EQUAL(expr, fcontext_expr);
570 		semanage_fcontext_free(resp);
571 	} else {
572 		CU_ASSERT(res < 0);
573 		CU_ASSERT(resp == (void *) 42);
574 	}
575 
576 	/* cleanup */
577 	semanage_fcontext_key_free(key);
578 	cleanup_handle(level);
579 }
580 
test_fcontext_query(void)581 static void test_fcontext_query(void)
582 {
583 	helper_fcontext_query(SH_CONNECT, FCONTEXT_NONEXISTENT_EXPR,
584 			      FCONTEXT_NONEXISTENT_TYPE, -1);
585 	helper_fcontext_query(SH_CONNECT, FCONTEXT2_EXPR, FCONTEXT1_TYPE, -1);
586 	helper_fcontext_query(SH_CONNECT, FCONTEXT1_EXPR, FCONTEXT1_TYPE, 1);
587 	helper_fcontext_query(SH_CONNECT, FCONTEXT2_EXPR, FCONTEXT2_TYPE, 1);
588 	helper_fcontext_query(SH_TRANS, FCONTEXT_NONEXISTENT_EXPR,
589 			      FCONTEXT_NONEXISTENT_TYPE, -1);
590 	helper_fcontext_query(SH_TRANS, FCONTEXT2_EXPR, FCONTEXT1_TYPE, -1);
591 	helper_fcontext_query(SH_TRANS, FCONTEXT1_EXPR, FCONTEXT1_TYPE, 1);
592 	helper_fcontext_query(SH_TRANS, FCONTEXT2_EXPR, FCONTEXT2_TYPE, 1);
593 }
594 
595 /* Function semanage_fcontext_exists */
helper_fcontext_exists(level_t level,const char * fcontext_expr,int fcontext_type,int exp_resp)596 static void helper_fcontext_exists(level_t level, const char *fcontext_expr,
597 			    int fcontext_type, int exp_resp)
598 {
599 	semanage_fcontext_key_t *key;
600 	int resp;
601 
602 	/* setup */
603 	setup_handle(level);
604 	key = get_fcontext_key_from_str(fcontext_expr, fcontext_type);
605 
606 	/* test */
607 	CU_ASSERT(semanage_fcontext_exists(sh, key, &resp) >= 0);
608 	CU_ASSERT(resp == exp_resp);
609 
610 	/* cleanup */
611 	semanage_fcontext_key_free(key);
612 	cleanup_handle(level);
613 }
614 
test_fcontext_exists(void)615 static void test_fcontext_exists(void)
616 {
617 	helper_fcontext_exists(SH_CONNECT, FCONTEXT_NONEXISTENT_EXPR,
618 			       FCONTEXT_NONEXISTENT_TYPE, 0);
619 	helper_fcontext_exists(SH_CONNECT, FCONTEXT2_EXPR, FCONTEXT1_TYPE, 0);
620 	helper_fcontext_exists(SH_CONNECT, FCONTEXT1_EXPR, FCONTEXT1_TYPE, 1);
621 	helper_fcontext_exists(SH_CONNECT, FCONTEXT2_EXPR, FCONTEXT2_TYPE, 1);
622 	helper_fcontext_exists(SH_TRANS, FCONTEXT_NONEXISTENT_EXPR,
623 			       FCONTEXT_NONEXISTENT_TYPE, 0);
624 	helper_fcontext_exists(SH_TRANS, FCONTEXT2_EXPR, FCONTEXT1_TYPE, 0);
625 	helper_fcontext_exists(SH_TRANS, FCONTEXT1_EXPR, FCONTEXT1_TYPE, 1);
626 	helper_fcontext_exists(SH_TRANS, FCONTEXT2_EXPR, FCONTEXT2_TYPE, 1);
627 }
628 
629 /* Function semanage_fcontext_count */
test_fcontext_count(void)630 static void test_fcontext_count(void)
631 {
632 	unsigned int resp;
633 
634 	/* handle */
635 	setup_handle(SH_HANDLE);
636 	CU_ASSERT(semanage_fcontext_count(sh, &resp) < 0);
637 	CU_ASSERT(semanage_fcontext_count(sh, NULL) < 0);
638 	cleanup_handle(SH_HANDLE);
639 
640 	/* connect */
641 	resp = 0;
642 	setup_handle(SH_CONNECT);
643 	CU_ASSERT(semanage_fcontext_count(sh, &resp) >= 0);
644 	CU_ASSERT(resp == FCONTEXTS_COUNT);
645 	cleanup_handle(SH_CONNECT);
646 
647 	/* trans */
648 	resp = 0;
649 	setup_handle(SH_TRANS);
650 	CU_ASSERT(semanage_fcontext_count(sh, &resp) >= 0);
651 	CU_ASSERT(resp == FCONTEXTS_COUNT);
652 	cleanup_handle(SH_TRANS);
653 }
654 
655 /* Function semanage_fcontext_iterate */
656 unsigned int counter_fcontext_iterate = 0;
657 
handler_fcontext_iterate(const semanage_fcontext_t * record,void * varg)658 static int handler_fcontext_iterate(const semanage_fcontext_t *record, void *varg)
659 {
660 	CU_ASSERT_PTR_NOT_NULL(record);
661 	counter_fcontext_iterate++;
662 	return 0;
663 }
664 
helper_fcontext_iterate_invalid(void)665 static void helper_fcontext_iterate_invalid(void)
666 {
667 	/* setup */
668 	setup_handle(SH_HANDLE);
669 
670 	/* test */
671 	CU_ASSERT(semanage_fcontext_iterate(sh, &handler_fcontext_iterate,
672 				            NULL) < 0);
673 	CU_ASSERT(semanage_fcontext_iterate(sh, NULL, NULL) < 0);
674 
675 	/* cleanup */
676 	cleanup_handle(SH_HANDLE);
677 }
678 
helper_fcontext_iterate(level_t level)679 static void helper_fcontext_iterate(level_t level)
680 {
681 	/* setup */
682 	setup_handle(level);
683 	counter_fcontext_iterate = 0;
684 
685 	/* test */
686 	CU_ASSERT(semanage_fcontext_iterate(sh, &handler_fcontext_iterate,
687 					    NULL) >= 0);
688 	CU_ASSERT(counter_fcontext_iterate == FCONTEXTS_COUNT);
689 
690 	/* cleanup */
691 	cleanup_handle(level);
692 }
693 
test_fcontext_iterate(void)694 static void test_fcontext_iterate(void)
695 {
696 	helper_fcontext_iterate_invalid();
697 	helper_fcontext_iterate(SH_CONNECT);
698 	helper_fcontext_iterate(SH_TRANS);
699 }
700 
701 /* Function semanage_fcontext_list */
helper_fcontext_list_invalid(void)702 static void helper_fcontext_list_invalid(void)
703 {
704 	semanage_fcontext_t **records;
705 	unsigned int count;
706 
707 	/* setup */
708 	setup_handle(SH_HANDLE);
709 
710 	/* test */
711 	CU_ASSERT(semanage_fcontext_list(sh, &records, &count) < 0);
712 	CU_ASSERT(semanage_fcontext_list(sh, NULL, &count) < 0);
713 	CU_ASSERT(semanage_fcontext_list(sh, &records, NULL) < 0);
714 
715 	/* cleanup */
716 	cleanup_handle(SH_HANDLE);
717 }
718 
helper_fcontext_list(level_t level)719 static void helper_fcontext_list(level_t level)
720 {
721 	semanage_fcontext_t **records;
722 	unsigned int count;
723 
724 	/* setup */
725 	setup_handle(level);
726 
727 	/* test */
728 	CU_ASSERT(semanage_fcontext_list(sh, &records, &count) >= 0);
729 	CU_ASSERT(count == FCONTEXTS_COUNT);
730 
731 	for (unsigned int i = 0; i < count; i++)
732 		CU_ASSERT_PTR_NOT_NULL(records[i]);
733 
734 	for (unsigned int i = 0; i < count; i++)
735 		semanage_fcontext_free(records[i]);
736 
737 	free(records);
738 
739 	/* cleanup */
740 	cleanup_handle(level);
741 }
742 
test_fcontext_list(void)743 static void test_fcontext_list(void)
744 {
745 	helper_fcontext_list_invalid();
746 	helper_fcontext_list(SH_CONNECT);
747 	helper_fcontext_list(SH_TRANS);
748 }
749 
750 /* Function semanage_fcontext_modify_local, semanage_fcontext_del_local */
helper_fcontext_modify_del_local(level_t level,int fcontext_idx,const char * con_str,int exp_res)751 static void helper_fcontext_modify_del_local(level_t level, int fcontext_idx,
752 				      const char *con_str, int exp_res)
753 {
754 	semanage_fcontext_t *fcontext;
755 	semanage_fcontext_t *fcontext_local = NULL;
756 	semanage_fcontext_key_t *key = NULL;
757 	semanage_context_t *con = NULL;
758 	int res;
759 
760 	/* setup */
761 	setup_handle(level);
762 	fcontext = get_fcontext_nth(fcontext_idx);
763 	CU_ASSERT(semanage_fcontext_key_extract(sh, fcontext, &key) >= 0);
764 	CU_ASSERT_PTR_NOT_NULL(key);
765 
766 	if (con_str != NULL) {
767 		CU_ASSERT(semanage_context_from_string(sh, con_str, &con) >= 0);
768 		CU_ASSERT_PTR_NOT_NULL(con);
769 	} else {
770 		con = NULL;
771 	}
772 
773 	CU_ASSERT(semanage_fcontext_set_con(sh, fcontext, con) >= 0);
774 
775 	/* test */
776 	res = semanage_fcontext_modify_local(sh, key, fcontext);
777 
778 	if (exp_res >= 0) {
779 		CU_ASSERT(res >= 0);
780 
781 		if (level == SH_TRANS) {
782 			helper_commit();
783 			helper_begin_transaction();
784 		}
785 
786 		CU_ASSERT(semanage_fcontext_query_local(sh, key,
787 					                &fcontext_local) >= 0);
788 		CU_ASSERT(semanage_fcontext_compare2(fcontext_local,
789 						     fcontext) == 0);
790 		semanage_fcontext_free(fcontext_local);
791 
792 		CU_ASSERT(semanage_fcontext_del_local(sh, key) >= 0);
793 		CU_ASSERT(semanage_fcontext_query_local(sh, key,
794 					                &fcontext_local) < 0);
795 	} else {
796 		CU_ASSERT(res < 0);
797 	}
798 
799 	/* cleanup */
800 	semanage_context_free(con);
801 	semanage_fcontext_key_free(key);
802 	semanage_fcontext_free(fcontext);
803 	cleanup_handle(level);
804 }
805 
test_fcontext_modify_del_local(void)806 static void test_fcontext_modify_del_local(void)
807 {
808 	helper_fcontext_modify_del_local(SH_CONNECT, I_FIRST,
809 					 "system_u:object_r:tmp_t:s0", -1);
810 	helper_fcontext_modify_del_local(SH_CONNECT, I_SECOND,
811 					 "system_u:object_r:tmp_t:s0", -1);
812 	helper_fcontext_modify_del_local(SH_TRANS, I_FIRST,
813 					 "system_u:object_r:tmp_t:s0", 1);
814 	helper_fcontext_modify_del_local(SH_TRANS, I_SECOND,
815 					 "system_u:object_r:tmp_t:s0", 1);
816 }
817 
818 /* Function semanage_fcontext_query_local */
test_fcontext_query_local(void)819 static void test_fcontext_query_local(void)
820 {
821 	semanage_fcontext_key_t *key = NULL;
822 	semanage_fcontext_t *resp = NULL;
823 
824 	/* connect */
825 	setup_handle(SH_CONNECT);
826 
827 	key = get_fcontext_key_nth(I_FIRST);
828 	CU_ASSERT(semanage_fcontext_query_local(sh, key, &resp) < 0);
829 	CU_ASSERT_PTR_NULL(resp);
830 
831 	cleanup_handle(SH_CONNECT);
832 
833 	/* transaction */
834 	setup_handle(SH_TRANS);
835 
836 	semanage_fcontext_key_free(key);
837 	key = get_fcontext_key_nth(I_FIRST);
838 	CU_ASSERT(semanage_fcontext_query_local(sh, key, &resp) < 0);
839 	CU_ASSERT_PTR_NULL(resp);
840 
841 	add_local_fcontext(I_FIRST);
842 	CU_ASSERT(semanage_fcontext_query_local(sh, key, &resp) >= 0);
843 	CU_ASSERT_PTR_NOT_NULL(resp);
844 	semanage_fcontext_free(resp);
845 	resp = NULL;
846 
847 	semanage_fcontext_key_free(key);
848 	key = get_fcontext_key_nth(I_SECOND);
849 	add_local_fcontext(I_SECOND);
850 	CU_ASSERT(semanage_fcontext_query_local(sh, key, &resp) >= 0);
851 	CU_ASSERT_PTR_NOT_NULL(resp);
852 	semanage_fcontext_free(resp);
853 	resp = NULL;
854 
855 	/* cleanup */
856 	semanage_fcontext_key_free(key);
857 	delete_local_fcontext(I_FIRST);
858 	delete_local_fcontext(I_SECOND);
859 	cleanup_handle(SH_TRANS);
860 }
861 
862 /* Function semanage_fcontext_exists_local */
test_fcontext_exists_local(void)863 static void test_fcontext_exists_local(void)
864 {
865 	int resp = -1;
866 	semanage_fcontext_key_t *key;
867 
868 	/* setup */
869 	setup_handle(SH_TRANS);
870 	key = get_fcontext_key_nth(I_FIRST);
871 
872 	/* test */
873 	CU_ASSERT(semanage_fcontext_exists_local(sh, key, &resp) >= 0);
874 	CU_ASSERT(resp == 0);
875 
876 	add_local_fcontext(I_FIRST);
877 	resp = -1;
878 
879 	CU_ASSERT(semanage_fcontext_exists_local(sh, key, &resp) >= 0);
880 	CU_ASSERT(resp == 1);
881 
882 	delete_local_fcontext(I_FIRST);
883 	resp = -1;
884 
885 	CU_ASSERT(semanage_fcontext_exists_local(sh, key, &resp) >= 0);
886 	CU_ASSERT(resp == 0);
887 
888 	resp = -1;
889 
890 	CU_ASSERT(semanage_fcontext_exists_local(sh, NULL, &resp) >= 0);
891 	CU_ASSERT(resp == 0);
892 
893 	/* cleanup */
894 	semanage_fcontext_key_free(key);
895 	cleanup_handle(SH_TRANS);
896 }
897 
898 /* Function semanage_fcontext_count_local */
test_fcontext_count_local(void)899 static void test_fcontext_count_local(void)
900 {
901 	unsigned int resp;
902 
903 	/* handle */
904 	setup_handle(SH_HANDLE);
905 	CU_ASSERT(semanage_fcontext_count_local(sh, &resp) < 0);
906 	cleanup_handle(SH_HANDLE);
907 
908 	/* connect */
909 	setup_handle(SH_CONNECT);
910 	CU_ASSERT(semanage_fcontext_count_local(sh, &resp) >= 0);
911 	CU_ASSERT(resp == 0);
912 	cleanup_handle(SH_CONNECT);
913 
914 	/* transaction */
915 	setup_handle(SH_TRANS);
916 	CU_ASSERT(semanage_fcontext_count_local(sh, &resp) >= 0);
917 	CU_ASSERT(resp == 0);
918 
919 	add_local_fcontext(I_FIRST);
920 	CU_ASSERT(semanage_fcontext_count_local(sh, &resp) >= 0);
921 	CU_ASSERT(resp == 1);
922 
923 	add_local_fcontext(I_SECOND);
924 	CU_ASSERT(semanage_fcontext_count_local(sh, &resp) >= 0);
925 	CU_ASSERT(resp == 2);
926 
927 	delete_local_fcontext(I_SECOND);
928 	CU_ASSERT(semanage_fcontext_count_local(sh, &resp) >= 0);
929 	CU_ASSERT(resp == 1);
930 
931 	/* cleanup */
932 	delete_local_fcontext(I_FIRST);
933 	cleanup_handle(SH_TRANS);
934 }
935 
936 /* Function semanage_fcontext_iterate_local */
937 unsigned int counter_fcontext_iterate_local = 0;
938 
handler_fcontext_iterate_local(const semanage_fcontext_t * record,void * varg)939 static int handler_fcontext_iterate_local(const semanage_fcontext_t *record,
940 				   void *varg)
941 {
942 	CU_ASSERT_PTR_NOT_NULL(record);
943 	counter_fcontext_iterate_local++;
944 	return 0;
945 }
946 
test_fcontext_iterate_local(void)947 static void test_fcontext_iterate_local(void)
948 {
949 	/* handle */
950 	setup_handle(SH_HANDLE);
951 
952 	CU_ASSERT(semanage_fcontext_iterate_local(sh,
953 				    &handler_fcontext_iterate_local, NULL) < 0);
954 	CU_ASSERT(semanage_fcontext_iterate_local(sh, NULL, NULL) < 0);
955 
956 	cleanup_handle(SH_HANDLE);
957 
958 	/* connect */
959 	setup_handle(SH_CONNECT);
960 
961 	counter_fcontext_iterate_local = 0;
962 	CU_ASSERT(semanage_fcontext_iterate_local(sh,
963 				   &handler_fcontext_iterate_local, NULL) >= 0);
964 	CU_ASSERT(counter_fcontext_iterate_local == 0);
965 	CU_ASSERT(semanage_fcontext_iterate_local(sh, NULL, NULL) >= 0);
966 
967 	cleanup_handle(SH_CONNECT);
968 
969 	/* transaction */
970 	setup_handle(SH_TRANS);
971 
972 	counter_fcontext_iterate_local = 0;
973 	CU_ASSERT(semanage_fcontext_iterate_local(sh,
974 				   &handler_fcontext_iterate_local, NULL) >= 0);
975 	CU_ASSERT(counter_fcontext_iterate_local == 0);
976 
977 	add_local_fcontext(I_FIRST);
978 	counter_fcontext_iterate_local = 0;
979 	CU_ASSERT(semanage_fcontext_iterate_local(sh,
980 				   &handler_fcontext_iterate_local, NULL) >= 0);
981 	CU_ASSERT(counter_fcontext_iterate_local == 1);
982 
983 	add_local_fcontext(I_SECOND);
984 	counter_fcontext_iterate_local = 0;
985 	CU_ASSERT(semanage_fcontext_iterate_local(sh,
986 				   &handler_fcontext_iterate_local, NULL) >= 0);
987 	CU_ASSERT(counter_fcontext_iterate_local == 2);
988 
989 	/* cleanup */
990 	delete_local_fcontext(I_FIRST);
991 	delete_local_fcontext(I_SECOND);
992 	cleanup_handle(SH_TRANS);
993 }
994 
995 /* Function semanage_fcontext_list_local */
test_fcontext_list_local(void)996 static void test_fcontext_list_local(void)
997 {
998 	semanage_fcontext_t **records;
999 	unsigned int count;
1000 
1001 	/* handle */
1002 	setup_handle(SH_HANDLE);
1003 
1004 	CU_ASSERT(semanage_fcontext_list_local(sh, &records, &count) < 0);
1005 	CU_ASSERT(semanage_fcontext_list_local(sh, NULL, &count) < 0);
1006 	CU_ASSERT(semanage_fcontext_list_local(sh, &records, NULL) < 0);
1007 
1008 	cleanup_handle(SH_HANDLE);
1009 
1010 	/* connect */
1011 	setup_handle(SH_CONNECT);
1012 
1013 	CU_ASSERT(semanage_fcontext_list_local(sh, &records, &count) >= 0);
1014 	CU_ASSERT(count == 0);
1015 
1016 	cleanup_handle(SH_CONNECT);
1017 
1018 	/* transaction */
1019 	setup_handle(SH_TRANS);
1020 
1021 	CU_ASSERT(semanage_fcontext_list_local(sh, &records, &count) >= 0);
1022 	CU_ASSERT(count == 0);
1023 
1024 	add_local_fcontext(I_FIRST);
1025 	CU_ASSERT(semanage_fcontext_list_local(sh, &records, &count) >= 0);
1026 	CU_ASSERT(count == 1);
1027 	CU_ASSERT_PTR_NOT_NULL(records[0]);
1028 	semanage_fcontext_free(records[0]);
1029 	free(records);
1030 
1031 	add_local_fcontext(I_SECOND);
1032 	CU_ASSERT(semanage_fcontext_list_local(sh, &records, &count) >= 0);
1033 	CU_ASSERT(count == 2);
1034 	CU_ASSERT_PTR_NOT_NULL(records[0]);
1035 	CU_ASSERT_PTR_NOT_NULL(records[1]);
1036 	semanage_fcontext_free(records[0]);
1037 	semanage_fcontext_free(records[1]);
1038 	free(records);
1039 
1040 	/* cleanup */
1041 	delete_local_fcontext(I_FIRST);
1042 	delete_local_fcontext(I_SECOND);
1043 	cleanup_handle(SH_TRANS);
1044 }
1045