1*2d543d20SAndroid Build Coastguard Worker #include <netinet/in.h>
2*2d543d20SAndroid Build Coastguard Worker #include <stdlib.h>
3*2d543d20SAndroid Build Coastguard Worker
4*2d543d20SAndroid Build Coastguard Worker #include "debug.h"
5*2d543d20SAndroid Build Coastguard Worker #include "context.h"
6*2d543d20SAndroid Build Coastguard Worker #include "handle.h"
7*2d543d20SAndroid Build Coastguard Worker
8*2d543d20SAndroid Build Coastguard Worker #include <sepol/policydb/policydb.h>
9*2d543d20SAndroid Build Coastguard Worker #include "ibendport_internal.h"
10*2d543d20SAndroid Build Coastguard Worker
11*2d543d20SAndroid Build Coastguard Worker /* Create a low level ibendport structure from
12*2d543d20SAndroid Build Coastguard Worker * a high level representation
13*2d543d20SAndroid Build Coastguard Worker */
ibendport_from_record(sepol_handle_t * handle,const policydb_t * policydb,ocontext_t ** ibendport,const sepol_ibendport_t * data)14*2d543d20SAndroid Build Coastguard Worker static int ibendport_from_record(sepol_handle_t *handle,
15*2d543d20SAndroid Build Coastguard Worker const policydb_t *policydb,
16*2d543d20SAndroid Build Coastguard Worker ocontext_t **ibendport,
17*2d543d20SAndroid Build Coastguard Worker const sepol_ibendport_t *data)
18*2d543d20SAndroid Build Coastguard Worker {
19*2d543d20SAndroid Build Coastguard Worker ocontext_t *tmp_ibendport = NULL;
20*2d543d20SAndroid Build Coastguard Worker context_struct_t *tmp_con = NULL;
21*2d543d20SAndroid Build Coastguard Worker char *ibdev_name = NULL;
22*2d543d20SAndroid Build Coastguard Worker int port = sepol_ibendport_get_port(data);
23*2d543d20SAndroid Build Coastguard Worker
24*2d543d20SAndroid Build Coastguard Worker tmp_ibendport = (ocontext_t *)calloc(1, sizeof(ocontext_t));
25*2d543d20SAndroid Build Coastguard Worker if (!tmp_ibendport)
26*2d543d20SAndroid Build Coastguard Worker goto omem;
27*2d543d20SAndroid Build Coastguard Worker
28*2d543d20SAndroid Build Coastguard Worker if (sepol_ibendport_alloc_ibdev_name(handle,
29*2d543d20SAndroid Build Coastguard Worker &tmp_ibendport->u.ibendport.dev_name) < 0)
30*2d543d20SAndroid Build Coastguard Worker goto omem;
31*2d543d20SAndroid Build Coastguard Worker
32*2d543d20SAndroid Build Coastguard Worker if (sepol_ibendport_get_ibdev_name(handle,
33*2d543d20SAndroid Build Coastguard Worker data,
34*2d543d20SAndroid Build Coastguard Worker &ibdev_name) < 0)
35*2d543d20SAndroid Build Coastguard Worker goto err;
36*2d543d20SAndroid Build Coastguard Worker
37*2d543d20SAndroid Build Coastguard Worker strncpy(tmp_ibendport->u.ibendport.dev_name, ibdev_name, IB_DEVICE_NAME_MAX - 1);
38*2d543d20SAndroid Build Coastguard Worker
39*2d543d20SAndroid Build Coastguard Worker free(ibdev_name);
40*2d543d20SAndroid Build Coastguard Worker ibdev_name = NULL;
41*2d543d20SAndroid Build Coastguard Worker
42*2d543d20SAndroid Build Coastguard Worker tmp_ibendport->u.ibendport.port = port;
43*2d543d20SAndroid Build Coastguard Worker
44*2d543d20SAndroid Build Coastguard Worker /* Context */
45*2d543d20SAndroid Build Coastguard Worker if (context_from_record(handle, policydb, &tmp_con,
46*2d543d20SAndroid Build Coastguard Worker sepol_ibendport_get_con(data)) < 0)
47*2d543d20SAndroid Build Coastguard Worker goto err;
48*2d543d20SAndroid Build Coastguard Worker context_cpy(&tmp_ibendport->context[0], tmp_con);
49*2d543d20SAndroid Build Coastguard Worker context_destroy(tmp_con);
50*2d543d20SAndroid Build Coastguard Worker free(tmp_con);
51*2d543d20SAndroid Build Coastguard Worker tmp_con = NULL;
52*2d543d20SAndroid Build Coastguard Worker
53*2d543d20SAndroid Build Coastguard Worker *ibendport = tmp_ibendport;
54*2d543d20SAndroid Build Coastguard Worker return STATUS_SUCCESS;
55*2d543d20SAndroid Build Coastguard Worker
56*2d543d20SAndroid Build Coastguard Worker omem:
57*2d543d20SAndroid Build Coastguard Worker ERR(handle, "out of memory");
58*2d543d20SAndroid Build Coastguard Worker
59*2d543d20SAndroid Build Coastguard Worker err:
60*2d543d20SAndroid Build Coastguard Worker if (tmp_ibendport) {
61*2d543d20SAndroid Build Coastguard Worker context_destroy(&tmp_ibendport->context[0]);
62*2d543d20SAndroid Build Coastguard Worker free(tmp_ibendport);
63*2d543d20SAndroid Build Coastguard Worker }
64*2d543d20SAndroid Build Coastguard Worker context_destroy(tmp_con);
65*2d543d20SAndroid Build Coastguard Worker free(tmp_con);
66*2d543d20SAndroid Build Coastguard Worker free(ibdev_name);
67*2d543d20SAndroid Build Coastguard Worker ERR(handle, "could not create ibendport structure");
68*2d543d20SAndroid Build Coastguard Worker return STATUS_ERR;
69*2d543d20SAndroid Build Coastguard Worker }
70*2d543d20SAndroid Build Coastguard Worker
ibendport_to_record(sepol_handle_t * handle,const policydb_t * policydb,ocontext_t * ibendport,sepol_ibendport_t ** record)71*2d543d20SAndroid Build Coastguard Worker static int ibendport_to_record(sepol_handle_t *handle,
72*2d543d20SAndroid Build Coastguard Worker const policydb_t *policydb,
73*2d543d20SAndroid Build Coastguard Worker ocontext_t *ibendport,
74*2d543d20SAndroid Build Coastguard Worker sepol_ibendport_t **record)
75*2d543d20SAndroid Build Coastguard Worker {
76*2d543d20SAndroid Build Coastguard Worker int port = ibendport->u.ibendport.port;
77*2d543d20SAndroid Build Coastguard Worker context_struct_t *con = &ibendport->context[0];
78*2d543d20SAndroid Build Coastguard Worker
79*2d543d20SAndroid Build Coastguard Worker sepol_context_t *tmp_con = NULL;
80*2d543d20SAndroid Build Coastguard Worker sepol_ibendport_t *tmp_record = NULL;
81*2d543d20SAndroid Build Coastguard Worker
82*2d543d20SAndroid Build Coastguard Worker if (sepol_ibendport_create(handle, &tmp_record) < 0)
83*2d543d20SAndroid Build Coastguard Worker goto err;
84*2d543d20SAndroid Build Coastguard Worker
85*2d543d20SAndroid Build Coastguard Worker if (sepol_ibendport_set_ibdev_name(handle, tmp_record,
86*2d543d20SAndroid Build Coastguard Worker ibendport->u.ibendport.dev_name) < 0)
87*2d543d20SAndroid Build Coastguard Worker goto err;
88*2d543d20SAndroid Build Coastguard Worker
89*2d543d20SAndroid Build Coastguard Worker sepol_ibendport_set_port(tmp_record, port);
90*2d543d20SAndroid Build Coastguard Worker
91*2d543d20SAndroid Build Coastguard Worker if (context_to_record(handle, policydb, con, &tmp_con) < 0)
92*2d543d20SAndroid Build Coastguard Worker goto err;
93*2d543d20SAndroid Build Coastguard Worker
94*2d543d20SAndroid Build Coastguard Worker if (sepol_ibendport_set_con(handle, tmp_record, tmp_con) < 0)
95*2d543d20SAndroid Build Coastguard Worker goto err;
96*2d543d20SAndroid Build Coastguard Worker
97*2d543d20SAndroid Build Coastguard Worker sepol_context_free(tmp_con);
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 ibendport to record");
103*2d543d20SAndroid Build Coastguard Worker sepol_context_free(tmp_con);
104*2d543d20SAndroid Build Coastguard Worker sepol_ibendport_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 /* Return the number of ibendports */
sepol_ibendport_count(sepol_handle_t * handle,const sepol_policydb_t * p,unsigned int * response)109*2d543d20SAndroid Build Coastguard Worker extern int sepol_ibendport_count(sepol_handle_t *handle __attribute__ ((unused)),
110*2d543d20SAndroid Build Coastguard Worker const sepol_policydb_t *p, unsigned int *response)
111*2d543d20SAndroid Build Coastguard Worker {
112*2d543d20SAndroid Build Coastguard Worker unsigned int count = 0;
113*2d543d20SAndroid Build Coastguard Worker ocontext_t *c, *head;
114*2d543d20SAndroid Build Coastguard Worker const policydb_t *policydb = &p->p;
115*2d543d20SAndroid Build Coastguard Worker
116*2d543d20SAndroid Build Coastguard Worker head = policydb->ocontexts[OCON_IBENDPORT];
117*2d543d20SAndroid Build Coastguard Worker for (c = head; c; c = c->next)
118*2d543d20SAndroid Build Coastguard Worker count++;
119*2d543d20SAndroid Build Coastguard Worker
120*2d543d20SAndroid Build Coastguard Worker *response = count;
121*2d543d20SAndroid Build Coastguard Worker
122*2d543d20SAndroid Build Coastguard Worker return STATUS_SUCCESS;
123*2d543d20SAndroid Build Coastguard Worker }
124*2d543d20SAndroid Build Coastguard Worker
125*2d543d20SAndroid Build Coastguard Worker /* Check if a ibendport exists */
sepol_ibendport_exists(sepol_handle_t * handle,const sepol_policydb_t * p,const sepol_ibendport_key_t * key,int * response)126*2d543d20SAndroid Build Coastguard Worker int sepol_ibendport_exists(sepol_handle_t *handle __attribute__ ((unused)),
127*2d543d20SAndroid Build Coastguard Worker const sepol_policydb_t *p,
128*2d543d20SAndroid Build Coastguard Worker const sepol_ibendport_key_t *key, int *response)
129*2d543d20SAndroid Build Coastguard Worker {
130*2d543d20SAndroid Build Coastguard Worker const policydb_t *policydb = &p->p;
131*2d543d20SAndroid Build Coastguard Worker ocontext_t *c, *head;
132*2d543d20SAndroid Build Coastguard Worker int port;
133*2d543d20SAndroid Build Coastguard Worker const char *ibdev_name;
134*2d543d20SAndroid Build Coastguard Worker
135*2d543d20SAndroid Build Coastguard Worker sepol_ibendport_key_unpack(key, &ibdev_name, &port);
136*2d543d20SAndroid Build Coastguard Worker
137*2d543d20SAndroid Build Coastguard Worker head = policydb->ocontexts[OCON_IBENDPORT];
138*2d543d20SAndroid Build Coastguard Worker for (c = head; c; c = c->next) {
139*2d543d20SAndroid Build Coastguard Worker const char *ibdev_name2 = c->u.ibendport.dev_name;
140*2d543d20SAndroid Build Coastguard Worker int port2 = c->u.ibendport.port;
141*2d543d20SAndroid Build Coastguard Worker
142*2d543d20SAndroid Build Coastguard Worker if (port2 == port &&
143*2d543d20SAndroid Build Coastguard Worker (!strcmp(ibdev_name, ibdev_name2))) {
144*2d543d20SAndroid Build Coastguard Worker *response = 1;
145*2d543d20SAndroid Build Coastguard Worker return STATUS_SUCCESS;
146*2d543d20SAndroid Build Coastguard Worker }
147*2d543d20SAndroid Build Coastguard Worker }
148*2d543d20SAndroid Build Coastguard Worker
149*2d543d20SAndroid Build Coastguard Worker *response = 0;
150*2d543d20SAndroid Build Coastguard Worker return STATUS_SUCCESS;
151*2d543d20SAndroid Build Coastguard Worker }
152*2d543d20SAndroid Build Coastguard Worker
sepol_ibendport_query(sepol_handle_t * handle,const sepol_policydb_t * p,const sepol_ibendport_key_t * key,sepol_ibendport_t ** response)153*2d543d20SAndroid Build Coastguard Worker int sepol_ibendport_query(sepol_handle_t *handle,
154*2d543d20SAndroid Build Coastguard Worker const sepol_policydb_t *p,
155*2d543d20SAndroid Build Coastguard Worker const sepol_ibendport_key_t *key,
156*2d543d20SAndroid Build Coastguard Worker sepol_ibendport_t **response)
157*2d543d20SAndroid Build Coastguard Worker {
158*2d543d20SAndroid Build Coastguard Worker const policydb_t *policydb = &p->p;
159*2d543d20SAndroid Build Coastguard Worker ocontext_t *c, *head;
160*2d543d20SAndroid Build Coastguard Worker int port;
161*2d543d20SAndroid Build Coastguard Worker const char *ibdev_name;
162*2d543d20SAndroid Build Coastguard Worker
163*2d543d20SAndroid Build Coastguard Worker sepol_ibendport_key_unpack(key, &ibdev_name, &port);
164*2d543d20SAndroid Build Coastguard Worker
165*2d543d20SAndroid Build Coastguard Worker head = policydb->ocontexts[OCON_IBENDPORT];
166*2d543d20SAndroid Build Coastguard Worker for (c = head; c; c = c->next) {
167*2d543d20SAndroid Build Coastguard Worker const char *ibdev_name2 = c->u.ibendport.dev_name;
168*2d543d20SAndroid Build Coastguard Worker int port2 = c->u.ibendport.port;
169*2d543d20SAndroid Build Coastguard Worker
170*2d543d20SAndroid Build Coastguard Worker if (port2 == port &&
171*2d543d20SAndroid Build Coastguard Worker (!strcmp(ibdev_name, ibdev_name2))) {
172*2d543d20SAndroid Build Coastguard Worker if (ibendport_to_record(handle, policydb, c, response) < 0)
173*2d543d20SAndroid Build Coastguard Worker goto err;
174*2d543d20SAndroid Build Coastguard Worker return STATUS_SUCCESS;
175*2d543d20SAndroid Build Coastguard Worker }
176*2d543d20SAndroid Build Coastguard Worker }
177*2d543d20SAndroid Build Coastguard Worker
178*2d543d20SAndroid Build Coastguard Worker *response = NULL;
179*2d543d20SAndroid Build Coastguard Worker return STATUS_SUCCESS;
180*2d543d20SAndroid Build Coastguard Worker
181*2d543d20SAndroid Build Coastguard Worker err:
182*2d543d20SAndroid Build Coastguard Worker ERR(handle, "could not query ibendport, IB device: %s port %u",
183*2d543d20SAndroid Build Coastguard Worker ibdev_name, port);
184*2d543d20SAndroid Build Coastguard Worker return STATUS_ERR;
185*2d543d20SAndroid Build Coastguard Worker }
186*2d543d20SAndroid Build Coastguard Worker
187*2d543d20SAndroid Build Coastguard Worker /* Load a ibendport into policy */
sepol_ibendport_modify(sepol_handle_t * handle,sepol_policydb_t * p,const sepol_ibendport_key_t * key,const sepol_ibendport_t * data)188*2d543d20SAndroid Build Coastguard Worker int sepol_ibendport_modify(sepol_handle_t *handle,
189*2d543d20SAndroid Build Coastguard Worker sepol_policydb_t *p,
190*2d543d20SAndroid Build Coastguard Worker const sepol_ibendport_key_t *key,
191*2d543d20SAndroid Build Coastguard Worker const sepol_ibendport_t *data)
192*2d543d20SAndroid Build Coastguard Worker {
193*2d543d20SAndroid Build Coastguard Worker policydb_t *policydb = &p->p;
194*2d543d20SAndroid Build Coastguard Worker ocontext_t *ibendport = NULL;
195*2d543d20SAndroid Build Coastguard Worker int port;
196*2d543d20SAndroid Build Coastguard Worker const char *ibdev_name;
197*2d543d20SAndroid Build Coastguard Worker
198*2d543d20SAndroid Build Coastguard Worker sepol_ibendport_key_unpack(key, &ibdev_name, &port);
199*2d543d20SAndroid Build Coastguard Worker
200*2d543d20SAndroid Build Coastguard Worker if (ibendport_from_record(handle, policydb, &ibendport, data) < 0)
201*2d543d20SAndroid Build Coastguard Worker goto err;
202*2d543d20SAndroid Build Coastguard Worker
203*2d543d20SAndroid Build Coastguard Worker /* Attach to context list */
204*2d543d20SAndroid Build Coastguard Worker ibendport->next = policydb->ocontexts[OCON_IBENDPORT];
205*2d543d20SAndroid Build Coastguard Worker policydb->ocontexts[OCON_IBENDPORT] = ibendport;
206*2d543d20SAndroid Build Coastguard Worker
207*2d543d20SAndroid Build Coastguard Worker return STATUS_SUCCESS;
208*2d543d20SAndroid Build Coastguard Worker
209*2d543d20SAndroid Build Coastguard Worker err:
210*2d543d20SAndroid Build Coastguard Worker ERR(handle, "could not load ibendport %s/%d",
211*2d543d20SAndroid Build Coastguard Worker ibdev_name, port);
212*2d543d20SAndroid Build Coastguard Worker if (ibendport) {
213*2d543d20SAndroid Build Coastguard Worker context_destroy(&ibendport->context[0]);
214*2d543d20SAndroid Build Coastguard Worker free(ibendport);
215*2d543d20SAndroid Build Coastguard Worker }
216*2d543d20SAndroid Build Coastguard Worker return STATUS_ERR;
217*2d543d20SAndroid Build Coastguard Worker }
218*2d543d20SAndroid Build Coastguard Worker
sepol_ibendport_iterate(sepol_handle_t * handle,const sepol_policydb_t * p,int (* fn)(const sepol_ibendport_t * ibendport,void * fn_arg),void * arg)219*2d543d20SAndroid Build Coastguard Worker int sepol_ibendport_iterate(sepol_handle_t *handle,
220*2d543d20SAndroid Build Coastguard Worker const sepol_policydb_t *p,
221*2d543d20SAndroid Build Coastguard Worker int (*fn)(const sepol_ibendport_t *ibendport,
222*2d543d20SAndroid Build Coastguard Worker void *fn_arg), void *arg)
223*2d543d20SAndroid Build Coastguard Worker {
224*2d543d20SAndroid Build Coastguard Worker const policydb_t *policydb = &p->p;
225*2d543d20SAndroid Build Coastguard Worker ocontext_t *c, *head;
226*2d543d20SAndroid Build Coastguard Worker sepol_ibendport_t *ibendport = NULL;
227*2d543d20SAndroid Build Coastguard Worker
228*2d543d20SAndroid Build Coastguard Worker head = policydb->ocontexts[OCON_IBENDPORT];
229*2d543d20SAndroid Build Coastguard Worker for (c = head; c; c = c->next) {
230*2d543d20SAndroid Build Coastguard Worker int status;
231*2d543d20SAndroid Build Coastguard Worker
232*2d543d20SAndroid Build Coastguard Worker if (ibendport_to_record(handle, policydb, c, &ibendport) < 0)
233*2d543d20SAndroid Build Coastguard Worker goto err;
234*2d543d20SAndroid Build Coastguard Worker
235*2d543d20SAndroid Build Coastguard Worker /* Invoke handler */
236*2d543d20SAndroid Build Coastguard Worker status = fn(ibendport, arg);
237*2d543d20SAndroid Build Coastguard Worker if (status < 0)
238*2d543d20SAndroid Build Coastguard Worker goto err;
239*2d543d20SAndroid Build Coastguard Worker
240*2d543d20SAndroid Build Coastguard Worker sepol_ibendport_free(ibendport);
241*2d543d20SAndroid Build Coastguard Worker ibendport = NULL;
242*2d543d20SAndroid Build Coastguard Worker
243*2d543d20SAndroid Build Coastguard Worker /* Handler requested exit */
244*2d543d20SAndroid Build Coastguard Worker if (status > 0)
245*2d543d20SAndroid Build Coastguard Worker break;
246*2d543d20SAndroid Build Coastguard Worker }
247*2d543d20SAndroid Build Coastguard Worker
248*2d543d20SAndroid Build Coastguard Worker return STATUS_SUCCESS;
249*2d543d20SAndroid Build Coastguard Worker
250*2d543d20SAndroid Build Coastguard Worker err:
251*2d543d20SAndroid Build Coastguard Worker ERR(handle, "could not iterate over ibendports");
252*2d543d20SAndroid Build Coastguard Worker sepol_ibendport_free(ibendport);
253*2d543d20SAndroid Build Coastguard Worker return STATUS_ERR;
254*2d543d20SAndroid Build Coastguard Worker }
255