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