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