1*2d543d20SAndroid Build Coastguard Worker #include <netinet/in.h>
2*2d543d20SAndroid Build Coastguard Worker #include <stdlib.h>
3*2d543d20SAndroid Build Coastguard Worker #include <inttypes.h>
4*2d543d20SAndroid Build Coastguard Worker
5*2d543d20SAndroid Build Coastguard Worker #include "debug.h"
6*2d543d20SAndroid Build Coastguard Worker #include "context.h"
7*2d543d20SAndroid Build Coastguard Worker #include "handle.h"
8*2d543d20SAndroid Build Coastguard Worker
9*2d543d20SAndroid Build Coastguard Worker #include <sepol/ibpkey_record.h>
10*2d543d20SAndroid Build Coastguard Worker #include <sepol/policydb/policydb.h>
11*2d543d20SAndroid Build Coastguard Worker #include "ibpkey_internal.h"
12*2d543d20SAndroid Build Coastguard Worker
13*2d543d20SAndroid Build Coastguard Worker /* Create a low level ibpkey structure from
14*2d543d20SAndroid Build Coastguard Worker * a high level representation
15*2d543d20SAndroid Build Coastguard Worker */
ibpkey_from_record(sepol_handle_t * handle,const policydb_t * policydb,ocontext_t ** ibpkey,const sepol_ibpkey_t * data)16*2d543d20SAndroid Build Coastguard Worker static int ibpkey_from_record(sepol_handle_t *handle,
17*2d543d20SAndroid Build Coastguard Worker const policydb_t *policydb,
18*2d543d20SAndroid Build Coastguard Worker ocontext_t **ibpkey, const sepol_ibpkey_t *data)
19*2d543d20SAndroid Build Coastguard Worker {
20*2d543d20SAndroid Build Coastguard Worker ocontext_t *tmp_ibpkey = NULL;
21*2d543d20SAndroid Build Coastguard Worker context_struct_t *tmp_con = NULL;
22*2d543d20SAndroid Build Coastguard Worker char *subnet_prefix_buf = NULL;
23*2d543d20SAndroid Build Coastguard Worker int low = sepol_ibpkey_get_low(data);
24*2d543d20SAndroid Build Coastguard Worker int high = sepol_ibpkey_get_high(data);
25*2d543d20SAndroid Build Coastguard Worker
26*2d543d20SAndroid Build Coastguard Worker tmp_ibpkey = (ocontext_t *)calloc(1, sizeof(*tmp_ibpkey));
27*2d543d20SAndroid Build Coastguard Worker if (!tmp_ibpkey)
28*2d543d20SAndroid Build Coastguard Worker goto omem;
29*2d543d20SAndroid Build Coastguard Worker
30*2d543d20SAndroid Build Coastguard Worker tmp_ibpkey->u.ibpkey.subnet_prefix = sepol_ibpkey_get_subnet_prefix_bytes(data);
31*2d543d20SAndroid Build Coastguard Worker
32*2d543d20SAndroid Build Coastguard Worker /* Pkey range */
33*2d543d20SAndroid Build Coastguard Worker tmp_ibpkey->u.ibpkey.low_pkey = low;
34*2d543d20SAndroid Build Coastguard Worker tmp_ibpkey->u.ibpkey.high_pkey = high;
35*2d543d20SAndroid Build Coastguard Worker if (tmp_ibpkey->u.ibpkey.low_pkey > tmp_ibpkey->u.ibpkey.high_pkey) {
36*2d543d20SAndroid Build Coastguard Worker ERR(handle, "low ibpkey %d exceeds high ibpkey %d",
37*2d543d20SAndroid Build Coastguard Worker tmp_ibpkey->u.ibpkey.low_pkey, tmp_ibpkey->u.ibpkey.high_pkey);
38*2d543d20SAndroid Build Coastguard Worker goto err;
39*2d543d20SAndroid Build Coastguard Worker }
40*2d543d20SAndroid Build Coastguard Worker
41*2d543d20SAndroid Build Coastguard Worker /* Context */
42*2d543d20SAndroid Build Coastguard Worker if (context_from_record(handle, policydb, &tmp_con,
43*2d543d20SAndroid Build Coastguard Worker sepol_ibpkey_get_con(data)) < 0)
44*2d543d20SAndroid Build Coastguard Worker goto err;
45*2d543d20SAndroid Build Coastguard Worker context_cpy(&tmp_ibpkey->context[0], tmp_con);
46*2d543d20SAndroid Build Coastguard Worker context_destroy(tmp_con);
47*2d543d20SAndroid Build Coastguard Worker free(tmp_con);
48*2d543d20SAndroid Build Coastguard Worker tmp_con = NULL;
49*2d543d20SAndroid Build Coastguard Worker
50*2d543d20SAndroid Build Coastguard Worker *ibpkey = tmp_ibpkey;
51*2d543d20SAndroid Build Coastguard Worker return STATUS_SUCCESS;
52*2d543d20SAndroid Build Coastguard Worker
53*2d543d20SAndroid Build Coastguard Worker omem:
54*2d543d20SAndroid Build Coastguard Worker ERR(handle, "out of memory");
55*2d543d20SAndroid Build Coastguard Worker
56*2d543d20SAndroid Build Coastguard Worker err:
57*2d543d20SAndroid Build Coastguard Worker if (tmp_ibpkey) {
58*2d543d20SAndroid Build Coastguard Worker context_destroy(&tmp_ibpkey->context[0]);
59*2d543d20SAndroid Build Coastguard Worker free(tmp_ibpkey);
60*2d543d20SAndroid Build Coastguard Worker }
61*2d543d20SAndroid Build Coastguard Worker context_destroy(tmp_con);
62*2d543d20SAndroid Build Coastguard Worker free(tmp_con);
63*2d543d20SAndroid Build Coastguard Worker free(subnet_prefix_buf);
64*2d543d20SAndroid Build Coastguard Worker ERR(handle, "could not create ibpkey structure");
65*2d543d20SAndroid Build Coastguard Worker return STATUS_ERR;
66*2d543d20SAndroid Build Coastguard Worker }
67*2d543d20SAndroid Build Coastguard Worker
ibpkey_to_record(sepol_handle_t * handle,const policydb_t * policydb,ocontext_t * ibpkey,sepol_ibpkey_t ** record)68*2d543d20SAndroid Build Coastguard Worker static int ibpkey_to_record(sepol_handle_t *handle,
69*2d543d20SAndroid Build Coastguard Worker const policydb_t *policydb,
70*2d543d20SAndroid Build Coastguard Worker ocontext_t *ibpkey, sepol_ibpkey_t **record)
71*2d543d20SAndroid Build Coastguard Worker {
72*2d543d20SAndroid Build Coastguard Worker context_struct_t *con = &ibpkey->context[0];
73*2d543d20SAndroid Build Coastguard Worker sepol_context_t *tmp_con = NULL;
74*2d543d20SAndroid Build Coastguard Worker sepol_ibpkey_t *tmp_record = NULL;
75*2d543d20SAndroid Build Coastguard Worker
76*2d543d20SAndroid Build Coastguard Worker if (sepol_ibpkey_create(handle, &tmp_record) < 0)
77*2d543d20SAndroid Build Coastguard Worker goto err;
78*2d543d20SAndroid Build Coastguard Worker
79*2d543d20SAndroid Build Coastguard Worker sepol_ibpkey_set_subnet_prefix_bytes(tmp_record,
80*2d543d20SAndroid Build Coastguard Worker ibpkey->u.ibpkey.subnet_prefix);
81*2d543d20SAndroid Build Coastguard Worker
82*2d543d20SAndroid Build Coastguard Worker sepol_ibpkey_set_range(tmp_record, ibpkey->u.ibpkey.low_pkey,
83*2d543d20SAndroid Build Coastguard Worker ibpkey->u.ibpkey.high_pkey);
84*2d543d20SAndroid Build Coastguard Worker
85*2d543d20SAndroid Build Coastguard Worker if (context_to_record(handle, policydb, con, &tmp_con) < 0)
86*2d543d20SAndroid Build Coastguard Worker goto err;
87*2d543d20SAndroid Build Coastguard Worker
88*2d543d20SAndroid Build Coastguard Worker if (sepol_ibpkey_set_con(handle, tmp_record, tmp_con) < 0)
89*2d543d20SAndroid Build Coastguard Worker goto err;
90*2d543d20SAndroid Build Coastguard Worker
91*2d543d20SAndroid Build Coastguard Worker sepol_context_free(tmp_con);
92*2d543d20SAndroid Build Coastguard Worker *record = tmp_record;
93*2d543d20SAndroid Build Coastguard Worker return STATUS_SUCCESS;
94*2d543d20SAndroid Build Coastguard Worker
95*2d543d20SAndroid Build Coastguard Worker err:
96*2d543d20SAndroid Build Coastguard Worker ERR(handle, "could not convert ibpkey to record");
97*2d543d20SAndroid Build Coastguard Worker sepol_context_free(tmp_con);
98*2d543d20SAndroid Build Coastguard Worker sepol_ibpkey_free(tmp_record);
99*2d543d20SAndroid Build Coastguard Worker return STATUS_ERR;
100*2d543d20SAndroid Build Coastguard Worker }
101*2d543d20SAndroid Build Coastguard Worker
102*2d543d20SAndroid Build Coastguard Worker /* Return the number of ibpkeys */
sepol_ibpkey_count(sepol_handle_t * handle,const sepol_policydb_t * p,unsigned int * response)103*2d543d20SAndroid Build Coastguard Worker extern int sepol_ibpkey_count(sepol_handle_t *handle __attribute__ ((unused)),
104*2d543d20SAndroid Build Coastguard Worker const sepol_policydb_t *p, unsigned int *response)
105*2d543d20SAndroid Build Coastguard Worker {
106*2d543d20SAndroid Build Coastguard Worker unsigned int count = 0;
107*2d543d20SAndroid Build Coastguard Worker ocontext_t *c, *head;
108*2d543d20SAndroid Build Coastguard Worker const policydb_t *policydb = &p->p;
109*2d543d20SAndroid Build Coastguard Worker
110*2d543d20SAndroid Build Coastguard Worker head = policydb->ocontexts[OCON_IBPKEY];
111*2d543d20SAndroid Build Coastguard Worker for (c = head; c; c = c->next)
112*2d543d20SAndroid Build Coastguard Worker count++;
113*2d543d20SAndroid Build Coastguard Worker
114*2d543d20SAndroid Build Coastguard Worker *response = count;
115*2d543d20SAndroid Build Coastguard Worker
116*2d543d20SAndroid Build Coastguard Worker return STATUS_SUCCESS;
117*2d543d20SAndroid Build Coastguard Worker }
118*2d543d20SAndroid Build Coastguard Worker
119*2d543d20SAndroid Build Coastguard Worker /* Check if a ibpkey exists */
sepol_ibpkey_exists(sepol_handle_t * handle,const sepol_policydb_t * p,const sepol_ibpkey_key_t * key,int * response)120*2d543d20SAndroid Build Coastguard Worker int sepol_ibpkey_exists(sepol_handle_t *handle __attribute__ ((unused)),
121*2d543d20SAndroid Build Coastguard Worker const sepol_policydb_t *p,
122*2d543d20SAndroid Build Coastguard Worker const sepol_ibpkey_key_t *key, int *response)
123*2d543d20SAndroid Build Coastguard Worker {
124*2d543d20SAndroid Build Coastguard Worker const policydb_t *policydb = &p->p;
125*2d543d20SAndroid Build Coastguard Worker ocontext_t *c, *head;
126*2d543d20SAndroid Build Coastguard Worker int low, high;
127*2d543d20SAndroid Build Coastguard Worker uint64_t subnet_prefix;
128*2d543d20SAndroid Build Coastguard Worker
129*2d543d20SAndroid Build Coastguard Worker sepol_ibpkey_key_unpack(key, &subnet_prefix, &low, &high);
130*2d543d20SAndroid Build Coastguard Worker
131*2d543d20SAndroid Build Coastguard Worker head = policydb->ocontexts[OCON_IBPKEY];
132*2d543d20SAndroid Build Coastguard Worker for (c = head; c; c = c->next) {
133*2d543d20SAndroid Build Coastguard Worker uint64_t subnet_prefix2 = c->u.ibpkey.subnet_prefix;
134*2d543d20SAndroid Build Coastguard Worker uint16_t low2 = c->u.ibpkey.low_pkey;
135*2d543d20SAndroid Build Coastguard Worker uint16_t high2 = c->u.ibpkey.high_pkey;
136*2d543d20SAndroid Build Coastguard Worker
137*2d543d20SAndroid Build Coastguard Worker if (low2 == low &&
138*2d543d20SAndroid Build Coastguard Worker high2 == high &&
139*2d543d20SAndroid Build Coastguard Worker subnet_prefix == subnet_prefix2) {
140*2d543d20SAndroid Build Coastguard Worker *response = 1;
141*2d543d20SAndroid Build Coastguard Worker return STATUS_SUCCESS;
142*2d543d20SAndroid Build Coastguard Worker }
143*2d543d20SAndroid Build Coastguard Worker }
144*2d543d20SAndroid Build Coastguard Worker
145*2d543d20SAndroid Build Coastguard Worker *response = 0;
146*2d543d20SAndroid Build Coastguard Worker return STATUS_SUCCESS;
147*2d543d20SAndroid Build Coastguard Worker }
148*2d543d20SAndroid Build Coastguard Worker
149*2d543d20SAndroid Build Coastguard Worker /* Query a ibpkey */
sepol_ibpkey_query(sepol_handle_t * handle,const sepol_policydb_t * p,const sepol_ibpkey_key_t * key,sepol_ibpkey_t ** response)150*2d543d20SAndroid Build Coastguard Worker int sepol_ibpkey_query(sepol_handle_t *handle,
151*2d543d20SAndroid Build Coastguard Worker const sepol_policydb_t *p,
152*2d543d20SAndroid Build Coastguard Worker const sepol_ibpkey_key_t *key, sepol_ibpkey_t **response)
153*2d543d20SAndroid Build Coastguard Worker {
154*2d543d20SAndroid Build Coastguard Worker const policydb_t *policydb = &p->p;
155*2d543d20SAndroid Build Coastguard Worker ocontext_t *c, *head;
156*2d543d20SAndroid Build Coastguard Worker int low, high;
157*2d543d20SAndroid Build Coastguard Worker uint64_t subnet_prefix;
158*2d543d20SAndroid Build Coastguard Worker
159*2d543d20SAndroid Build Coastguard Worker sepol_ibpkey_key_unpack(key, &subnet_prefix, &low, &high);
160*2d543d20SAndroid Build Coastguard Worker
161*2d543d20SAndroid Build Coastguard Worker head = policydb->ocontexts[OCON_IBPKEY];
162*2d543d20SAndroid Build Coastguard Worker for (c = head; c; c = c->next) {
163*2d543d20SAndroid Build Coastguard Worker uint64_t subnet_prefix2 = c->u.ibpkey.subnet_prefix;
164*2d543d20SAndroid Build Coastguard Worker int low2 = c->u.ibpkey.low_pkey;
165*2d543d20SAndroid Build Coastguard Worker int high2 = c->u.ibpkey.high_pkey;
166*2d543d20SAndroid Build Coastguard Worker
167*2d543d20SAndroid Build Coastguard Worker if (low2 == low &&
168*2d543d20SAndroid Build Coastguard Worker high2 == high &&
169*2d543d20SAndroid Build Coastguard Worker subnet_prefix == subnet_prefix2) {
170*2d543d20SAndroid Build Coastguard Worker if (ibpkey_to_record(handle, policydb, c, response) < 0)
171*2d543d20SAndroid Build Coastguard Worker goto err;
172*2d543d20SAndroid Build Coastguard Worker return STATUS_SUCCESS;
173*2d543d20SAndroid Build Coastguard Worker }
174*2d543d20SAndroid Build Coastguard Worker }
175*2d543d20SAndroid Build Coastguard Worker
176*2d543d20SAndroid Build Coastguard Worker *response = NULL;
177*2d543d20SAndroid Build Coastguard Worker return STATUS_SUCCESS;
178*2d543d20SAndroid Build Coastguard Worker
179*2d543d20SAndroid Build Coastguard Worker err:
180*2d543d20SAndroid Build Coastguard Worker ERR(handle, "could not query ibpkey subnet prefix: %#" PRIx64 " range %u - %u exists",
181*2d543d20SAndroid Build Coastguard Worker subnet_prefix, low, high);
182*2d543d20SAndroid Build Coastguard Worker return STATUS_ERR;
183*2d543d20SAndroid Build Coastguard Worker }
184*2d543d20SAndroid Build Coastguard Worker
185*2d543d20SAndroid Build Coastguard Worker /* Load a ibpkey into policy */
sepol_ibpkey_modify(sepol_handle_t * handle,sepol_policydb_t * p,const sepol_ibpkey_key_t * key,const sepol_ibpkey_t * data)186*2d543d20SAndroid Build Coastguard Worker int sepol_ibpkey_modify(sepol_handle_t *handle,
187*2d543d20SAndroid Build Coastguard Worker sepol_policydb_t *p,
188*2d543d20SAndroid Build Coastguard Worker const sepol_ibpkey_key_t *key, const sepol_ibpkey_t *data)
189*2d543d20SAndroid Build Coastguard Worker {
190*2d543d20SAndroid Build Coastguard Worker policydb_t *policydb = &p->p;
191*2d543d20SAndroid Build Coastguard Worker ocontext_t *ibpkey = NULL;
192*2d543d20SAndroid Build Coastguard Worker int low, high;
193*2d543d20SAndroid Build Coastguard Worker uint64_t subnet_prefix;
194*2d543d20SAndroid Build Coastguard Worker
195*2d543d20SAndroid Build Coastguard Worker sepol_ibpkey_key_unpack(key, &subnet_prefix, &low, &high);
196*2d543d20SAndroid Build Coastguard Worker
197*2d543d20SAndroid Build Coastguard Worker if (ibpkey_from_record(handle, policydb, &ibpkey, data) < 0)
198*2d543d20SAndroid Build Coastguard Worker goto err;
199*2d543d20SAndroid Build Coastguard Worker
200*2d543d20SAndroid Build Coastguard Worker /* Attach to context list */
201*2d543d20SAndroid Build Coastguard Worker ibpkey->next = policydb->ocontexts[OCON_IBPKEY];
202*2d543d20SAndroid Build Coastguard Worker policydb->ocontexts[OCON_IBPKEY] = ibpkey;
203*2d543d20SAndroid Build Coastguard Worker
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 load ibpkey subnet prefix: %#" PRIx64 " range %u - %u exists",
208*2d543d20SAndroid Build Coastguard Worker subnet_prefix, low, high);
209*2d543d20SAndroid Build Coastguard Worker if (ibpkey) {
210*2d543d20SAndroid Build Coastguard Worker context_destroy(&ibpkey->context[0]);
211*2d543d20SAndroid Build Coastguard Worker free(ibpkey);
212*2d543d20SAndroid Build Coastguard Worker }
213*2d543d20SAndroid Build Coastguard Worker return STATUS_ERR;
214*2d543d20SAndroid Build Coastguard Worker }
215*2d543d20SAndroid Build Coastguard Worker
sepol_ibpkey_iterate(sepol_handle_t * handle,const sepol_policydb_t * p,int (* fn)(const sepol_ibpkey_t * ibpkey,void * fn_arg),void * arg)216*2d543d20SAndroid Build Coastguard Worker int sepol_ibpkey_iterate(sepol_handle_t *handle,
217*2d543d20SAndroid Build Coastguard Worker const sepol_policydb_t *p,
218*2d543d20SAndroid Build Coastguard Worker int (*fn)(const sepol_ibpkey_t *ibpkey,
219*2d543d20SAndroid Build Coastguard Worker void *fn_arg), void *arg)
220*2d543d20SAndroid Build Coastguard Worker {
221*2d543d20SAndroid Build Coastguard Worker const policydb_t *policydb = &p->p;
222*2d543d20SAndroid Build Coastguard Worker ocontext_t *c, *head;
223*2d543d20SAndroid Build Coastguard Worker sepol_ibpkey_t *ibpkey = NULL;
224*2d543d20SAndroid Build Coastguard Worker
225*2d543d20SAndroid Build Coastguard Worker head = policydb->ocontexts[OCON_IBPKEY];
226*2d543d20SAndroid Build Coastguard Worker for (c = head; c; c = c->next) {
227*2d543d20SAndroid Build Coastguard Worker int status;
228*2d543d20SAndroid Build Coastguard Worker
229*2d543d20SAndroid Build Coastguard Worker if (ibpkey_to_record(handle, policydb, c, &ibpkey) < 0)
230*2d543d20SAndroid Build Coastguard Worker goto err;
231*2d543d20SAndroid Build Coastguard Worker
232*2d543d20SAndroid Build Coastguard Worker /* Invoke handler */
233*2d543d20SAndroid Build Coastguard Worker status = fn(ibpkey, arg);
234*2d543d20SAndroid Build Coastguard Worker if (status < 0)
235*2d543d20SAndroid Build Coastguard Worker goto err;
236*2d543d20SAndroid Build Coastguard Worker
237*2d543d20SAndroid Build Coastguard Worker sepol_ibpkey_free(ibpkey);
238*2d543d20SAndroid Build Coastguard Worker ibpkey = NULL;
239*2d543d20SAndroid Build Coastguard Worker
240*2d543d20SAndroid Build Coastguard Worker /* Handler requested exit */
241*2d543d20SAndroid Build Coastguard Worker if (status > 0)
242*2d543d20SAndroid Build Coastguard Worker break;
243*2d543d20SAndroid Build Coastguard Worker }
244*2d543d20SAndroid Build Coastguard Worker
245*2d543d20SAndroid Build Coastguard Worker return STATUS_SUCCESS;
246*2d543d20SAndroid Build Coastguard Worker
247*2d543d20SAndroid Build Coastguard Worker err:
248*2d543d20SAndroid Build Coastguard Worker ERR(handle, "could not iterate over ibpkeys");
249*2d543d20SAndroid Build Coastguard Worker sepol_ibpkey_free(ibpkey);
250*2d543d20SAndroid Build Coastguard Worker return STATUS_ERR;
251*2d543d20SAndroid Build Coastguard Worker }
252