xref: /aosp_15_r20/external/selinux/libselinux/src/is_customizable_type.c (revision 2d543d20722ada2425b5bdab9d0d1d29470e7bba)
1 #include <unistd.h>
2 #include <errno.h>
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <string.h>
6 #include <ctype.h>
7 #include <pwd.h>
8 #include <limits.h>
9 #include "selinux_internal.h"
10 #include "context_internal.h"
11 
12 static char **customizable_list = NULL;
13 static pthread_once_t customizable_once = PTHREAD_ONCE_INIT;
14 
customizable_init(void)15 static void customizable_init(void)
16 {
17 	FILE *fp;
18 	char *buf;
19 	unsigned int ctr = 0, i;
20 	char **list = NULL;
21 
22 	fp = fopen(selinux_customizable_types_path(), "re");
23 	if (!fp)
24 		return;
25 
26 	buf = malloc(selinux_page_size);
27 	if (!buf) {
28 		fclose(fp);
29 		return;
30 	}
31 	while (fgets_unlocked(buf, selinux_page_size, fp) && ctr < UINT_MAX) {
32 		ctr++;
33 	}
34 
35 	if (fseek(fp, 0L, SEEK_SET) == -1) {
36 		free(buf);
37 		fclose(fp);
38 		return;
39 	}
40 
41 	if (ctr) {
42 		list = calloc(ctr + 1, sizeof(char *));
43 		if (list) {
44 			i = 0;
45 			while (fgets_unlocked(buf, selinux_page_size, fp)
46 			       && i < ctr) {
47 				buf[strlen(buf) - 1] = 0;
48 				list[i] = strdup(buf);
49 				if (!list[i]) {
50 					unsigned int j;
51 					for (j = 0; j < i; j++)
52 						free(list[j]);
53 					free(list);
54 					list = NULL;
55 					break;
56 				}
57 				i++;
58 			}
59 		}
60 	}
61 	fclose(fp);
62 	free(buf);
63 	if (!list)
64 		return;
65 	customizable_list = list;
66 }
67 
is_context_customizable(const char * scontext)68 int is_context_customizable(const char * scontext)
69 {
70 	int i;
71 	const char *type;
72 	context_t c;
73 
74 	__selinux_once(customizable_once, customizable_init);
75 	if (!customizable_list)
76 		return -1;
77 
78 	c = context_new(scontext);
79 	if (!c)
80 		return -1;
81 
82 	type = context_type_get(c);
83 	if (!type) {
84 		context_free(c);
85 		return -1;
86 	}
87 
88 	for (i = 0; customizable_list[i]; i++) {
89 		if (strcmp(customizable_list[i], type) == 0) {
90 			context_free(c);
91 			return 1;
92 		}
93 	}
94 	context_free(c);
95 	return 0;
96 }
97