1*2d543d20SAndroid Build Coastguard Worker #include <netinet/in.h>
2*2d543d20SAndroid Build Coastguard Worker #ifndef IPPROTO_DCCP
3*2d543d20SAndroid Build Coastguard Worker #define IPPROTO_DCCP 33
4*2d543d20SAndroid Build Coastguard Worker #endif
5*2d543d20SAndroid Build Coastguard Worker #ifndef IPPROTO_SCTP
6*2d543d20SAndroid Build Coastguard Worker #define IPPROTO_SCTP 132
7*2d543d20SAndroid Build Coastguard Worker #endif
8*2d543d20SAndroid Build Coastguard Worker #include <stdlib.h>
9*2d543d20SAndroid Build Coastguard Worker
10*2d543d20SAndroid Build Coastguard Worker #include "debug.h"
11*2d543d20SAndroid Build Coastguard Worker #include "context.h"
12*2d543d20SAndroid Build Coastguard Worker #include "handle.h"
13*2d543d20SAndroid Build Coastguard Worker
14*2d543d20SAndroid Build Coastguard Worker #include <sepol/policydb/policydb.h>
15*2d543d20SAndroid Build Coastguard Worker #include "port_internal.h"
16*2d543d20SAndroid Build Coastguard Worker
sepol2ipproto(sepol_handle_t * handle,int proto)17*2d543d20SAndroid Build Coastguard Worker static inline int sepol2ipproto(sepol_handle_t * handle, int proto)
18*2d543d20SAndroid Build Coastguard Worker {
19*2d543d20SAndroid Build Coastguard Worker
20*2d543d20SAndroid Build Coastguard Worker switch (proto) {
21*2d543d20SAndroid Build Coastguard Worker case SEPOL_PROTO_TCP:
22*2d543d20SAndroid Build Coastguard Worker return IPPROTO_TCP;
23*2d543d20SAndroid Build Coastguard Worker case SEPOL_PROTO_UDP:
24*2d543d20SAndroid Build Coastguard Worker return IPPROTO_UDP;
25*2d543d20SAndroid Build Coastguard Worker case SEPOL_PROTO_DCCP:
26*2d543d20SAndroid Build Coastguard Worker return IPPROTO_DCCP;
27*2d543d20SAndroid Build Coastguard Worker case SEPOL_PROTO_SCTP:
28*2d543d20SAndroid Build Coastguard Worker return IPPROTO_SCTP;
29*2d543d20SAndroid Build Coastguard Worker default:
30*2d543d20SAndroid Build Coastguard Worker ERR(handle, "unsupported protocol %u", proto);
31*2d543d20SAndroid Build Coastguard Worker return STATUS_ERR;
32*2d543d20SAndroid Build Coastguard Worker }
33*2d543d20SAndroid Build Coastguard Worker }
34*2d543d20SAndroid Build Coastguard Worker
ipproto2sepol(sepol_handle_t * handle,int proto)35*2d543d20SAndroid Build Coastguard Worker static inline int ipproto2sepol(sepol_handle_t * handle, int proto)
36*2d543d20SAndroid Build Coastguard Worker {
37*2d543d20SAndroid Build Coastguard Worker
38*2d543d20SAndroid Build Coastguard Worker switch (proto) {
39*2d543d20SAndroid Build Coastguard Worker case IPPROTO_TCP:
40*2d543d20SAndroid Build Coastguard Worker return SEPOL_PROTO_TCP;
41*2d543d20SAndroid Build Coastguard Worker case IPPROTO_UDP:
42*2d543d20SAndroid Build Coastguard Worker return SEPOL_PROTO_UDP;
43*2d543d20SAndroid Build Coastguard Worker case IPPROTO_DCCP:
44*2d543d20SAndroid Build Coastguard Worker return SEPOL_PROTO_DCCP;
45*2d543d20SAndroid Build Coastguard Worker case IPPROTO_SCTP:
46*2d543d20SAndroid Build Coastguard Worker return SEPOL_PROTO_SCTP;
47*2d543d20SAndroid Build Coastguard Worker default:
48*2d543d20SAndroid Build Coastguard Worker ERR(handle, "invalid protocol %u " "found in policy", proto);
49*2d543d20SAndroid Build Coastguard Worker return STATUS_ERR;
50*2d543d20SAndroid Build Coastguard Worker }
51*2d543d20SAndroid Build Coastguard Worker }
52*2d543d20SAndroid Build Coastguard Worker
53*2d543d20SAndroid Build Coastguard Worker /* Create a low level port structure from
54*2d543d20SAndroid Build Coastguard Worker * a high level representation */
port_from_record(sepol_handle_t * handle,const policydb_t * policydb,ocontext_t ** port,const sepol_port_t * data)55*2d543d20SAndroid Build Coastguard Worker static int port_from_record(sepol_handle_t * handle,
56*2d543d20SAndroid Build Coastguard Worker const policydb_t * policydb,
57*2d543d20SAndroid Build Coastguard Worker ocontext_t ** port, const sepol_port_t * data)
58*2d543d20SAndroid Build Coastguard Worker {
59*2d543d20SAndroid Build Coastguard Worker
60*2d543d20SAndroid Build Coastguard Worker ocontext_t *tmp_port = NULL;
61*2d543d20SAndroid Build Coastguard Worker context_struct_t *tmp_con = NULL;
62*2d543d20SAndroid Build Coastguard Worker int tmp_proto;
63*2d543d20SAndroid Build Coastguard Worker
64*2d543d20SAndroid Build Coastguard Worker int low = sepol_port_get_low(data);
65*2d543d20SAndroid Build Coastguard Worker int high = sepol_port_get_high(data);
66*2d543d20SAndroid Build Coastguard Worker int proto = sepol_port_get_proto(data);
67*2d543d20SAndroid Build Coastguard Worker
68*2d543d20SAndroid Build Coastguard Worker tmp_port = (ocontext_t *) calloc(1, sizeof(ocontext_t));
69*2d543d20SAndroid Build Coastguard Worker if (!tmp_port)
70*2d543d20SAndroid Build Coastguard Worker goto omem;
71*2d543d20SAndroid Build Coastguard Worker
72*2d543d20SAndroid Build Coastguard Worker /* Process protocol */
73*2d543d20SAndroid Build Coastguard Worker tmp_proto = sepol2ipproto(handle, proto);
74*2d543d20SAndroid Build Coastguard Worker if (tmp_proto < 0)
75*2d543d20SAndroid Build Coastguard Worker goto err;
76*2d543d20SAndroid Build Coastguard Worker tmp_port->u.port.protocol = tmp_proto;
77*2d543d20SAndroid Build Coastguard Worker
78*2d543d20SAndroid Build Coastguard Worker /* Port range */
79*2d543d20SAndroid Build Coastguard Worker tmp_port->u.port.low_port = low;
80*2d543d20SAndroid Build Coastguard Worker tmp_port->u.port.high_port = high;
81*2d543d20SAndroid Build Coastguard Worker if (tmp_port->u.port.low_port > tmp_port->u.port.high_port) {
82*2d543d20SAndroid Build Coastguard Worker ERR(handle, "low port %d exceeds high port %d",
83*2d543d20SAndroid Build Coastguard Worker tmp_port->u.port.low_port, tmp_port->u.port.high_port);
84*2d543d20SAndroid Build Coastguard Worker goto err;
85*2d543d20SAndroid Build Coastguard Worker }
86*2d543d20SAndroid Build Coastguard Worker
87*2d543d20SAndroid Build Coastguard Worker /* Context */
88*2d543d20SAndroid Build Coastguard Worker if (context_from_record(handle, policydb, &tmp_con,
89*2d543d20SAndroid Build Coastguard Worker sepol_port_get_con(data)) < 0)
90*2d543d20SAndroid Build Coastguard Worker goto err;
91*2d543d20SAndroid Build Coastguard Worker context_cpy(&tmp_port->context[0], tmp_con);
92*2d543d20SAndroid Build Coastguard Worker context_destroy(tmp_con);
93*2d543d20SAndroid Build Coastguard Worker free(tmp_con);
94*2d543d20SAndroid Build Coastguard Worker tmp_con = NULL;
95*2d543d20SAndroid Build Coastguard Worker
96*2d543d20SAndroid Build Coastguard Worker *port = tmp_port;
97*2d543d20SAndroid Build Coastguard Worker return STATUS_SUCCESS;
98*2d543d20SAndroid Build Coastguard Worker
99*2d543d20SAndroid Build Coastguard Worker omem:
100*2d543d20SAndroid Build Coastguard Worker ERR(handle, "out of memory");
101*2d543d20SAndroid Build Coastguard Worker
102*2d543d20SAndroid Build Coastguard Worker err:
103*2d543d20SAndroid Build Coastguard Worker if (tmp_port != NULL) {
104*2d543d20SAndroid Build Coastguard Worker context_destroy(&tmp_port->context[0]);
105*2d543d20SAndroid Build Coastguard Worker free(tmp_port);
106*2d543d20SAndroid Build Coastguard Worker }
107*2d543d20SAndroid Build Coastguard Worker context_destroy(tmp_con);
108*2d543d20SAndroid Build Coastguard Worker free(tmp_con);
109*2d543d20SAndroid Build Coastguard Worker ERR(handle, "could not create port structure for range %u:%u (%s)",
110*2d543d20SAndroid Build Coastguard Worker low, high, sepol_port_get_proto_str(proto));
111*2d543d20SAndroid Build Coastguard Worker return STATUS_ERR;
112*2d543d20SAndroid Build Coastguard Worker }
113*2d543d20SAndroid Build Coastguard Worker
port_to_record(sepol_handle_t * handle,const policydb_t * policydb,ocontext_t * port,sepol_port_t ** record)114*2d543d20SAndroid Build Coastguard Worker static int port_to_record(sepol_handle_t * handle,
115*2d543d20SAndroid Build Coastguard Worker const policydb_t * policydb,
116*2d543d20SAndroid Build Coastguard Worker ocontext_t * port, sepol_port_t ** record)
117*2d543d20SAndroid Build Coastguard Worker {
118*2d543d20SAndroid Build Coastguard Worker
119*2d543d20SAndroid Build Coastguard Worker int proto = port->u.port.protocol;
120*2d543d20SAndroid Build Coastguard Worker int low = port->u.port.low_port;
121*2d543d20SAndroid Build Coastguard Worker int high = port->u.port.high_port;
122*2d543d20SAndroid Build Coastguard Worker context_struct_t *con = &port->context[0];
123*2d543d20SAndroid Build Coastguard Worker int rec_proto = -1;
124*2d543d20SAndroid Build Coastguard Worker
125*2d543d20SAndroid Build Coastguard Worker sepol_context_t *tmp_con = NULL;
126*2d543d20SAndroid Build Coastguard Worker sepol_port_t *tmp_record = NULL;
127*2d543d20SAndroid Build Coastguard Worker
128*2d543d20SAndroid Build Coastguard Worker if (sepol_port_create(handle, &tmp_record) < 0)
129*2d543d20SAndroid Build Coastguard Worker goto err;
130*2d543d20SAndroid Build Coastguard Worker
131*2d543d20SAndroid Build Coastguard Worker rec_proto = ipproto2sepol(handle, proto);
132*2d543d20SAndroid Build Coastguard Worker if (rec_proto < 0)
133*2d543d20SAndroid Build Coastguard Worker goto err;
134*2d543d20SAndroid Build Coastguard Worker
135*2d543d20SAndroid Build Coastguard Worker sepol_port_set_proto(tmp_record, rec_proto);
136*2d543d20SAndroid Build Coastguard Worker sepol_port_set_range(tmp_record, low, high);
137*2d543d20SAndroid Build Coastguard Worker
138*2d543d20SAndroid Build Coastguard Worker if (context_to_record(handle, policydb, con, &tmp_con) < 0)
139*2d543d20SAndroid Build Coastguard Worker goto err;
140*2d543d20SAndroid Build Coastguard Worker
141*2d543d20SAndroid Build Coastguard Worker if (sepol_port_set_con(handle, tmp_record, tmp_con) < 0)
142*2d543d20SAndroid Build Coastguard Worker goto err;
143*2d543d20SAndroid Build Coastguard Worker
144*2d543d20SAndroid Build Coastguard Worker sepol_context_free(tmp_con);
145*2d543d20SAndroid Build Coastguard Worker *record = tmp_record;
146*2d543d20SAndroid Build Coastguard Worker return STATUS_SUCCESS;
147*2d543d20SAndroid Build Coastguard Worker
148*2d543d20SAndroid Build Coastguard Worker err:
149*2d543d20SAndroid Build Coastguard Worker ERR(handle, "could not convert port range %u - %u (%s) "
150*2d543d20SAndroid Build Coastguard Worker "to record", low, high, sepol_port_get_proto_str(rec_proto));
151*2d543d20SAndroid Build Coastguard Worker sepol_context_free(tmp_con);
152*2d543d20SAndroid Build Coastguard Worker sepol_port_free(tmp_record);
153*2d543d20SAndroid Build Coastguard Worker return STATUS_ERR;
154*2d543d20SAndroid Build Coastguard Worker }
155*2d543d20SAndroid Build Coastguard Worker
156*2d543d20SAndroid Build Coastguard Worker /* Return the number of ports */
sepol_port_count(sepol_handle_t * handle,const sepol_policydb_t * p,unsigned int * response)157*2d543d20SAndroid Build Coastguard Worker extern int sepol_port_count(sepol_handle_t * handle __attribute__ ((unused)),
158*2d543d20SAndroid Build Coastguard Worker const sepol_policydb_t * p, unsigned int *response)
159*2d543d20SAndroid Build Coastguard Worker {
160*2d543d20SAndroid Build Coastguard Worker
161*2d543d20SAndroid Build Coastguard Worker unsigned int count = 0;
162*2d543d20SAndroid Build Coastguard Worker ocontext_t *c, *head;
163*2d543d20SAndroid Build Coastguard Worker const policydb_t *policydb = &p->p;
164*2d543d20SAndroid Build Coastguard Worker
165*2d543d20SAndroid Build Coastguard Worker head = policydb->ocontexts[OCON_PORT];
166*2d543d20SAndroid Build Coastguard Worker for (c = head; c != NULL; c = c->next)
167*2d543d20SAndroid Build Coastguard Worker count++;
168*2d543d20SAndroid Build Coastguard Worker
169*2d543d20SAndroid Build Coastguard Worker *response = count;
170*2d543d20SAndroid Build Coastguard Worker
171*2d543d20SAndroid Build Coastguard Worker return STATUS_SUCCESS;
172*2d543d20SAndroid Build Coastguard Worker }
173*2d543d20SAndroid Build Coastguard Worker
174*2d543d20SAndroid Build Coastguard Worker /* Check if a port exists */
sepol_port_exists(sepol_handle_t * handle,const sepol_policydb_t * p,const sepol_port_key_t * key,int * response)175*2d543d20SAndroid Build Coastguard Worker int sepol_port_exists(sepol_handle_t * handle,
176*2d543d20SAndroid Build Coastguard Worker const sepol_policydb_t * p,
177*2d543d20SAndroid Build Coastguard Worker const sepol_port_key_t * key, int *response)
178*2d543d20SAndroid Build Coastguard Worker {
179*2d543d20SAndroid Build Coastguard Worker
180*2d543d20SAndroid Build Coastguard Worker const policydb_t *policydb = &p->p;
181*2d543d20SAndroid Build Coastguard Worker ocontext_t *c, *head;
182*2d543d20SAndroid Build Coastguard Worker
183*2d543d20SAndroid Build Coastguard Worker int low, high, proto;
184*2d543d20SAndroid Build Coastguard Worker const char *proto_str;
185*2d543d20SAndroid Build Coastguard Worker sepol_port_key_unpack(key, &low, &high, &proto);
186*2d543d20SAndroid Build Coastguard Worker proto_str = sepol_port_get_proto_str(proto);
187*2d543d20SAndroid Build Coastguard Worker proto = sepol2ipproto(handle, proto);
188*2d543d20SAndroid Build Coastguard Worker if (proto < 0)
189*2d543d20SAndroid Build Coastguard Worker goto err;
190*2d543d20SAndroid Build Coastguard Worker
191*2d543d20SAndroid Build Coastguard Worker head = policydb->ocontexts[OCON_PORT];
192*2d543d20SAndroid Build Coastguard Worker for (c = head; c; c = c->next) {
193*2d543d20SAndroid Build Coastguard Worker int proto2 = c->u.port.protocol;
194*2d543d20SAndroid Build Coastguard Worker int low2 = c->u.port.low_port;
195*2d543d20SAndroid Build Coastguard Worker int high2 = c->u.port.high_port;
196*2d543d20SAndroid Build Coastguard Worker
197*2d543d20SAndroid Build Coastguard Worker if (proto == proto2 && low2 == low && high2 == high) {
198*2d543d20SAndroid Build Coastguard Worker *response = 1;
199*2d543d20SAndroid Build Coastguard Worker return STATUS_SUCCESS;
200*2d543d20SAndroid Build Coastguard Worker }
201*2d543d20SAndroid Build Coastguard Worker }
202*2d543d20SAndroid Build Coastguard Worker
203*2d543d20SAndroid Build Coastguard Worker *response = 0;
204*2d543d20SAndroid Build Coastguard Worker return STATUS_SUCCESS;
205*2d543d20SAndroid Build Coastguard Worker
206*2d543d20SAndroid Build Coastguard Worker err:
207*2d543d20SAndroid Build Coastguard Worker ERR(handle, "could not check if port range %u - %u (%s) exists",
208*2d543d20SAndroid Build Coastguard Worker low, high, proto_str);
209*2d543d20SAndroid Build Coastguard Worker return STATUS_ERR;
210*2d543d20SAndroid Build Coastguard Worker }
211*2d543d20SAndroid Build Coastguard Worker
212*2d543d20SAndroid Build Coastguard Worker /* Query a port */
sepol_port_query(sepol_handle_t * handle,const sepol_policydb_t * p,const sepol_port_key_t * key,sepol_port_t ** response)213*2d543d20SAndroid Build Coastguard Worker int sepol_port_query(sepol_handle_t * handle,
214*2d543d20SAndroid Build Coastguard Worker const sepol_policydb_t * p,
215*2d543d20SAndroid Build Coastguard Worker const sepol_port_key_t * key, sepol_port_t ** response)
216*2d543d20SAndroid Build Coastguard Worker {
217*2d543d20SAndroid Build Coastguard Worker
218*2d543d20SAndroid Build Coastguard Worker const policydb_t *policydb = &p->p;
219*2d543d20SAndroid Build Coastguard Worker ocontext_t *c, *head;
220*2d543d20SAndroid Build Coastguard Worker
221*2d543d20SAndroid Build Coastguard Worker int low, high, proto;
222*2d543d20SAndroid Build Coastguard Worker const char *proto_str;
223*2d543d20SAndroid Build Coastguard Worker sepol_port_key_unpack(key, &low, &high, &proto);
224*2d543d20SAndroid Build Coastguard Worker proto_str = sepol_port_get_proto_str(proto);
225*2d543d20SAndroid Build Coastguard Worker proto = sepol2ipproto(handle, proto);
226*2d543d20SAndroid Build Coastguard Worker if (proto < 0)
227*2d543d20SAndroid Build Coastguard Worker goto err;
228*2d543d20SAndroid Build Coastguard Worker
229*2d543d20SAndroid Build Coastguard Worker head = policydb->ocontexts[OCON_PORT];
230*2d543d20SAndroid Build Coastguard Worker for (c = head; c; c = c->next) {
231*2d543d20SAndroid Build Coastguard Worker int proto2 = c->u.port.protocol;
232*2d543d20SAndroid Build Coastguard Worker int low2 = c->u.port.low_port;
233*2d543d20SAndroid Build Coastguard Worker int high2 = c->u.port.high_port;
234*2d543d20SAndroid Build Coastguard Worker
235*2d543d20SAndroid Build Coastguard Worker if (proto == proto2 && low2 == low && high2 == high) {
236*2d543d20SAndroid Build Coastguard Worker if (port_to_record(handle, policydb, c, response) < 0)
237*2d543d20SAndroid Build Coastguard Worker goto err;
238*2d543d20SAndroid Build Coastguard Worker return STATUS_SUCCESS;
239*2d543d20SAndroid Build Coastguard Worker }
240*2d543d20SAndroid Build Coastguard Worker }
241*2d543d20SAndroid Build Coastguard Worker
242*2d543d20SAndroid Build Coastguard Worker *response = NULL;
243*2d543d20SAndroid Build Coastguard Worker return STATUS_SUCCESS;
244*2d543d20SAndroid Build Coastguard Worker
245*2d543d20SAndroid Build Coastguard Worker err:
246*2d543d20SAndroid Build Coastguard Worker ERR(handle, "could not query port range %u - %u (%s)",
247*2d543d20SAndroid Build Coastguard Worker low, high, proto_str);
248*2d543d20SAndroid Build Coastguard Worker return STATUS_ERR;
249*2d543d20SAndroid Build Coastguard Worker
250*2d543d20SAndroid Build Coastguard Worker }
251*2d543d20SAndroid Build Coastguard Worker
252*2d543d20SAndroid Build Coastguard Worker /* Load a port into policy */
sepol_port_modify(sepol_handle_t * handle,sepol_policydb_t * p,const sepol_port_key_t * key,const sepol_port_t * data)253*2d543d20SAndroid Build Coastguard Worker int sepol_port_modify(sepol_handle_t * handle,
254*2d543d20SAndroid Build Coastguard Worker sepol_policydb_t * p,
255*2d543d20SAndroid Build Coastguard Worker const sepol_port_key_t * key, const sepol_port_t * data)
256*2d543d20SAndroid Build Coastguard Worker {
257*2d543d20SAndroid Build Coastguard Worker
258*2d543d20SAndroid Build Coastguard Worker policydb_t *policydb = &p->p;
259*2d543d20SAndroid Build Coastguard Worker ocontext_t *port = NULL;
260*2d543d20SAndroid Build Coastguard Worker
261*2d543d20SAndroid Build Coastguard Worker int low, high, proto;
262*2d543d20SAndroid Build Coastguard Worker const char *proto_str;
263*2d543d20SAndroid Build Coastguard Worker
264*2d543d20SAndroid Build Coastguard Worker sepol_port_key_unpack(key, &low, &high, &proto);
265*2d543d20SAndroid Build Coastguard Worker proto_str = sepol_port_get_proto_str(proto);
266*2d543d20SAndroid Build Coastguard Worker proto = sepol2ipproto(handle, proto);
267*2d543d20SAndroid Build Coastguard Worker if (proto < 0)
268*2d543d20SAndroid Build Coastguard Worker goto err;
269*2d543d20SAndroid Build Coastguard Worker
270*2d543d20SAndroid Build Coastguard Worker if (port_from_record(handle, policydb, &port, data) < 0)
271*2d543d20SAndroid Build Coastguard Worker goto err;
272*2d543d20SAndroid Build Coastguard Worker
273*2d543d20SAndroid Build Coastguard Worker /* Attach to context list */
274*2d543d20SAndroid Build Coastguard Worker port->next = policydb->ocontexts[OCON_PORT];
275*2d543d20SAndroid Build Coastguard Worker policydb->ocontexts[OCON_PORT] = port;
276*2d543d20SAndroid Build Coastguard Worker
277*2d543d20SAndroid Build Coastguard Worker return STATUS_SUCCESS;
278*2d543d20SAndroid Build Coastguard Worker
279*2d543d20SAndroid Build Coastguard Worker err:
280*2d543d20SAndroid Build Coastguard Worker ERR(handle, "could not load port range %u - %u (%s)",
281*2d543d20SAndroid Build Coastguard Worker low, high, proto_str);
282*2d543d20SAndroid Build Coastguard Worker if (port != NULL) {
283*2d543d20SAndroid Build Coastguard Worker context_destroy(&port->context[0]);
284*2d543d20SAndroid Build Coastguard Worker free(port);
285*2d543d20SAndroid Build Coastguard Worker }
286*2d543d20SAndroid Build Coastguard Worker return STATUS_ERR;
287*2d543d20SAndroid Build Coastguard Worker }
288*2d543d20SAndroid Build Coastguard Worker
sepol_port_iterate(sepol_handle_t * handle,const sepol_policydb_t * p,int (* fn)(const sepol_port_t * port,void * fn_arg),void * arg)289*2d543d20SAndroid Build Coastguard Worker int sepol_port_iterate(sepol_handle_t * handle,
290*2d543d20SAndroid Build Coastguard Worker const sepol_policydb_t * p,
291*2d543d20SAndroid Build Coastguard Worker int (*fn) (const sepol_port_t * port,
292*2d543d20SAndroid Build Coastguard Worker void *fn_arg), void *arg)
293*2d543d20SAndroid Build Coastguard Worker {
294*2d543d20SAndroid Build Coastguard Worker
295*2d543d20SAndroid Build Coastguard Worker const policydb_t *policydb = &p->p;
296*2d543d20SAndroid Build Coastguard Worker ocontext_t *c, *head;
297*2d543d20SAndroid Build Coastguard Worker sepol_port_t *port = NULL;
298*2d543d20SAndroid Build Coastguard Worker
299*2d543d20SAndroid Build Coastguard Worker head = policydb->ocontexts[OCON_PORT];
300*2d543d20SAndroid Build Coastguard Worker for (c = head; c; c = c->next) {
301*2d543d20SAndroid Build Coastguard Worker int status;
302*2d543d20SAndroid Build Coastguard Worker
303*2d543d20SAndroid Build Coastguard Worker if (port_to_record(handle, policydb, c, &port) < 0)
304*2d543d20SAndroid Build Coastguard Worker goto err;
305*2d543d20SAndroid Build Coastguard Worker
306*2d543d20SAndroid Build Coastguard Worker /* Invoke handler */
307*2d543d20SAndroid Build Coastguard Worker status = fn(port, arg);
308*2d543d20SAndroid Build Coastguard Worker if (status < 0)
309*2d543d20SAndroid Build Coastguard Worker goto err;
310*2d543d20SAndroid Build Coastguard Worker
311*2d543d20SAndroid Build Coastguard Worker sepol_port_free(port);
312*2d543d20SAndroid Build Coastguard Worker port = NULL;
313*2d543d20SAndroid Build Coastguard Worker
314*2d543d20SAndroid Build Coastguard Worker /* Handler requested exit */
315*2d543d20SAndroid Build Coastguard Worker if (status > 0)
316*2d543d20SAndroid Build Coastguard Worker break;
317*2d543d20SAndroid Build Coastguard Worker }
318*2d543d20SAndroid Build Coastguard Worker
319*2d543d20SAndroid Build Coastguard Worker return STATUS_SUCCESS;
320*2d543d20SAndroid Build Coastguard Worker
321*2d543d20SAndroid Build Coastguard Worker err:
322*2d543d20SAndroid Build Coastguard Worker ERR(handle, "could not iterate over ports");
323*2d543d20SAndroid Build Coastguard Worker sepol_port_free(port);
324*2d543d20SAndroid Build Coastguard Worker return STATUS_ERR;
325*2d543d20SAndroid Build Coastguard Worker }
326