xref: /aosp_15_r20/external/selinux/libsepol/src/ports.c (revision 2d543d20722ada2425b5bdab9d0d1d29470e7bba)
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