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