• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include <stdlib.h>
2 
3 #include "debug.h"
4 #include "context.h"
5 #include "handle.h"
6 
7 #include <sepol/policydb/policydb.h>
8 #include <sepol/interfaces.h>
9 #include "iface_internal.h"
10 
11 /* Create a low level structure from record */
iface_from_record(sepol_handle_t * handle,const policydb_t * policydb,ocontext_t ** iface,const sepol_iface_t * record)12 static int iface_from_record(sepol_handle_t * handle,
13 			     const policydb_t * policydb,
14 			     ocontext_t ** iface, const sepol_iface_t * record)
15 {
16 
17 	ocontext_t *tmp_iface = NULL;
18 	context_struct_t *tmp_con = NULL;
19 
20 	tmp_iface = (ocontext_t *) calloc(1, sizeof(ocontext_t));
21 	if (!tmp_iface)
22 		goto omem;
23 
24 	/* Name */
25 	tmp_iface->u.name = strdup(sepol_iface_get_name(record));
26 	if (!tmp_iface->u.name)
27 		goto omem;
28 
29 	/* Interface Context */
30 	if (context_from_record(handle, policydb,
31 				&tmp_con, sepol_iface_get_ifcon(record)) < 0)
32 		goto err;
33 	context_cpy(&tmp_iface->context[0], tmp_con);
34 	context_destroy(tmp_con);
35 	free(tmp_con);
36 	tmp_con = NULL;
37 
38 	/* Message Context */
39 	if (context_from_record(handle, policydb,
40 				&tmp_con, sepol_iface_get_msgcon(record)) < 0)
41 		goto err;
42 	context_cpy(&tmp_iface->context[1], tmp_con);
43 	context_destroy(tmp_con);
44 	free(tmp_con);
45 	tmp_con = NULL;
46 
47 	*iface = tmp_iface;
48 	return STATUS_SUCCESS;
49 
50       omem:
51 	ERR(handle, "out of memory");
52 
53       err:
54 	if (tmp_iface != NULL) {
55 		free(tmp_iface->u.name);
56 		context_destroy(&tmp_iface->context[0]);
57 		context_destroy(&tmp_iface->context[1]);
58 		free(tmp_iface);
59 	}
60 	context_destroy(tmp_con);
61 	free(tmp_con);
62 	ERR(handle, "error creating interface structure");
63 	return STATUS_ERR;
64 }
65 
iface_to_record(sepol_handle_t * handle,const policydb_t * policydb,ocontext_t * iface,sepol_iface_t ** record)66 static int iface_to_record(sepol_handle_t * handle,
67 			   const policydb_t * policydb,
68 			   ocontext_t * iface, sepol_iface_t ** record)
69 {
70 
71 	char *name = iface->u.name;
72 	context_struct_t *ifcon = &iface->context[0];
73 	context_struct_t *msgcon = &iface->context[1];
74 
75 	sepol_context_t *tmp_con = NULL;
76 	sepol_iface_t *tmp_record = NULL;
77 
78 	if (sepol_iface_create(handle, &tmp_record) < 0)
79 		goto err;
80 
81 	if (sepol_iface_set_name(handle, tmp_record, name) < 0)
82 		goto err;
83 
84 	if (context_to_record(handle, policydb, ifcon, &tmp_con) < 0)
85 		goto err;
86 	if (sepol_iface_set_ifcon(handle, tmp_record, tmp_con) < 0)
87 		goto err;
88 	sepol_context_free(tmp_con);
89 	tmp_con = NULL;
90 
91 	if (context_to_record(handle, policydb, msgcon, &tmp_con) < 0)
92 		goto err;
93 	if (sepol_iface_set_msgcon(handle, tmp_record, tmp_con) < 0)
94 		goto err;
95 	sepol_context_free(tmp_con);
96 	tmp_con = NULL;
97 
98 	*record = tmp_record;
99 	return STATUS_SUCCESS;
100 
101       err:
102 	ERR(handle, "could not convert interface %s to record", name);
103 	sepol_context_free(tmp_con);
104 	sepol_iface_free(tmp_record);
105 	return STATUS_ERR;
106 }
107 
108 /* Check if an interface exists */
sepol_iface_exists(sepol_handle_t * handle,const sepol_policydb_t * p,const sepol_iface_key_t * key,int * response)109 int sepol_iface_exists(sepol_handle_t * handle __attribute__ ((unused)),
110 		       const sepol_policydb_t * p,
111 		       const sepol_iface_key_t * key, int *response)
112 {
113 
114 	const policydb_t *policydb = &p->p;
115 	ocontext_t *c, *head;
116 
117 	const char *name;
118 	sepol_iface_key_unpack(key, &name);
119 
120 	head = policydb->ocontexts[OCON_NETIF];
121 	for (c = head; c; c = c->next) {
122 		if (!strcmp(name, c->u.name)) {
123 			*response = 1;
124 			return STATUS_SUCCESS;
125 		}
126 	}
127 	*response = 0;
128 
129 	handle = NULL;
130 	return STATUS_SUCCESS;
131 }
132 
133 /* Query an interface */
sepol_iface_query(sepol_handle_t * handle,const sepol_policydb_t * p,const sepol_iface_key_t * key,sepol_iface_t ** response)134 int sepol_iface_query(sepol_handle_t * handle,
135 		      const sepol_policydb_t * p,
136 		      const sepol_iface_key_t * key, sepol_iface_t ** response)
137 {
138 
139 	const policydb_t *policydb = &p->p;
140 	ocontext_t *c, *head;
141 
142 	const char *name;
143 	sepol_iface_key_unpack(key, &name);
144 
145 	head = policydb->ocontexts[OCON_NETIF];
146 	for (c = head; c; c = c->next) {
147 		if (!strcmp(name, c->u.name)) {
148 
149 			if (iface_to_record(handle, policydb, c, response) < 0)
150 				goto err;
151 
152 			return STATUS_SUCCESS;
153 		}
154 	}
155 
156 	*response = NULL;
157 	return STATUS_SUCCESS;
158 
159       err:
160 	ERR(handle, "could not query interface %s", name);
161 	return STATUS_ERR;
162 }
163 
164 /* Load an interface into policy */
sepol_iface_modify(sepol_handle_t * handle,sepol_policydb_t * p,const sepol_iface_key_t * key,const sepol_iface_t * data)165 int sepol_iface_modify(sepol_handle_t * handle,
166 		       sepol_policydb_t * p,
167 		       const sepol_iface_key_t * key,
168 		       const sepol_iface_t * data)
169 {
170 
171 	policydb_t *policydb = &p->p;
172 	ocontext_t *head, *prev, *c, *iface = NULL;
173 
174 	const char *name;
175 	sepol_iface_key_unpack(key, &name);
176 
177 	if (iface_from_record(handle, policydb, &iface, data) < 0)
178 		goto err;
179 
180 	prev = NULL;
181 	head = policydb->ocontexts[OCON_NETIF];
182 	for (c = head; c; c = c->next) {
183 		if (!strcmp(name, c->u.name)) {
184 
185 			/* Replace */
186 			iface->next = c->next;
187 			if (prev == NULL)
188 				policydb->ocontexts[OCON_NETIF] = iface;
189 			else
190 				prev->next = iface;
191 			free(c->u.name);
192 			context_destroy(&c->context[0]);
193 			context_destroy(&c->context[1]);
194 			free(c);
195 
196 			return STATUS_SUCCESS;
197 		}
198 		prev = c;
199 	}
200 
201 	/* Attach to context list */
202 	iface->next = policydb->ocontexts[OCON_NETIF];
203 	policydb->ocontexts[OCON_NETIF] = iface;
204 	return STATUS_SUCCESS;
205 
206       err:
207 	ERR(handle, "error while loading interface %s", name);
208 
209 	if (iface != NULL) {
210 		free(iface->u.name);
211 		context_destroy(&iface->context[0]);
212 		context_destroy(&iface->context[1]);
213 		free(iface);
214 	}
215 	return STATUS_ERR;
216 }
217 
218 /* Return the number of interfaces */
sepol_iface_count(sepol_handle_t * handle,const sepol_policydb_t * p,unsigned int * response)219 extern int sepol_iface_count(sepol_handle_t * handle __attribute__ ((unused)),
220 			     const sepol_policydb_t * p, unsigned int *response)
221 {
222 
223 	unsigned int count = 0;
224 	ocontext_t *c, *head;
225 	const policydb_t *policydb = &p->p;
226 
227 	head = policydb->ocontexts[OCON_NETIF];
228 	for (c = head; c != NULL; c = c->next)
229 		count++;
230 
231 	*response = count;
232 
233 	handle = NULL;
234 	return STATUS_SUCCESS;
235 }
236 
sepol_iface_iterate(sepol_handle_t * handle,const sepol_policydb_t * p,int (* fn)(const sepol_iface_t * iface,void * fn_arg),void * arg)237 int sepol_iface_iterate(sepol_handle_t * handle,
238 			const sepol_policydb_t * p,
239 			int (*fn) (const sepol_iface_t * iface,
240 				   void *fn_arg), void *arg)
241 {
242 
243 	const policydb_t *policydb = &p->p;
244 	ocontext_t *c, *head;
245 	sepol_iface_t *iface = NULL;
246 
247 	head = policydb->ocontexts[OCON_NETIF];
248 	for (c = head; c; c = c->next) {
249 		int status;
250 
251 		if (iface_to_record(handle, policydb, c, &iface) < 0)
252 			goto err;
253 
254 		/* Invoke handler */
255 		status = fn(iface, arg);
256 		if (status < 0)
257 			goto err;
258 
259 		sepol_iface_free(iface);
260 		iface = NULL;
261 
262 		/* Handler requested exit */
263 		if (status > 0)
264 			break;
265 	}
266 
267 	return STATUS_SUCCESS;
268 
269       err:
270 	ERR(handle, "could not iterate over interfaces");
271 	sepol_iface_free(iface);
272 	return STATUS_ERR;
273 }
274