1*2d543d20SAndroid Build Coastguard Worker /*
2*2d543d20SAndroid Build Coastguard Worker * Generalized labeling frontend for userspace object managers.
3*2d543d20SAndroid Build Coastguard Worker *
4*2d543d20SAndroid Build Coastguard Worker * Author : Eamon Walsh <[email protected]>
5*2d543d20SAndroid Build Coastguard Worker */
6*2d543d20SAndroid Build Coastguard Worker
7*2d543d20SAndroid Build Coastguard Worker #include <sys/types.h>
8*2d543d20SAndroid Build Coastguard Worker #include <ctype.h>
9*2d543d20SAndroid Build Coastguard Worker #include <errno.h>
10*2d543d20SAndroid Build Coastguard Worker #include <stdio.h>
11*2d543d20SAndroid Build Coastguard Worker #include <stdlib.h>
12*2d543d20SAndroid Build Coastguard Worker #include <string.h>
13*2d543d20SAndroid Build Coastguard Worker #include <sys/stat.h>
14*2d543d20SAndroid Build Coastguard Worker #include <selinux/selinux.h>
15*2d543d20SAndroid Build Coastguard Worker #include "callbacks.h"
16*2d543d20SAndroid Build Coastguard Worker #include "label_internal.h"
17*2d543d20SAndroid Build Coastguard Worker
18*2d543d20SAndroid Build Coastguard Worker #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
19*2d543d20SAndroid Build Coastguard Worker
20*2d543d20SAndroid Build Coastguard Worker #ifdef NO_MEDIA_BACKEND
21*2d543d20SAndroid Build Coastguard Worker #define CONFIG_MEDIA_BACKEND(fnptr) NULL
22*2d543d20SAndroid Build Coastguard Worker #else
23*2d543d20SAndroid Build Coastguard Worker #define CONFIG_MEDIA_BACKEND(fnptr) &fnptr
24*2d543d20SAndroid Build Coastguard Worker #endif
25*2d543d20SAndroid Build Coastguard Worker
26*2d543d20SAndroid Build Coastguard Worker #ifdef NO_X_BACKEND
27*2d543d20SAndroid Build Coastguard Worker #define CONFIG_X_BACKEND(fnptr) NULL
28*2d543d20SAndroid Build Coastguard Worker #else
29*2d543d20SAndroid Build Coastguard Worker #define CONFIG_X_BACKEND(fnptr) &fnptr
30*2d543d20SAndroid Build Coastguard Worker #endif
31*2d543d20SAndroid Build Coastguard Worker
32*2d543d20SAndroid Build Coastguard Worker #ifdef NO_DB_BACKEND
33*2d543d20SAndroid Build Coastguard Worker #define CONFIG_DB_BACKEND(fnptr) NULL
34*2d543d20SAndroid Build Coastguard Worker #else
35*2d543d20SAndroid Build Coastguard Worker #define CONFIG_DB_BACKEND(fnptr) &fnptr
36*2d543d20SAndroid Build Coastguard Worker #endif
37*2d543d20SAndroid Build Coastguard Worker
38*2d543d20SAndroid Build Coastguard Worker #ifdef NO_ANDROID_BACKEND
39*2d543d20SAndroid Build Coastguard Worker #define CONFIG_ANDROID_BACKEND(fnptr) NULL
40*2d543d20SAndroid Build Coastguard Worker #else
41*2d543d20SAndroid Build Coastguard Worker #define CONFIG_ANDROID_BACKEND(fnptr) (&(fnptr))
42*2d543d20SAndroid Build Coastguard Worker #endif
43*2d543d20SAndroid Build Coastguard Worker
44*2d543d20SAndroid Build Coastguard Worker typedef int (*selabel_initfunc)(struct selabel_handle *rec,
45*2d543d20SAndroid Build Coastguard Worker const struct selinux_opt *opts,
46*2d543d20SAndroid Build Coastguard Worker unsigned nopts);
47*2d543d20SAndroid Build Coastguard Worker
48*2d543d20SAndroid Build Coastguard Worker static const selabel_initfunc initfuncs[] = {
49*2d543d20SAndroid Build Coastguard Worker &selabel_file_init,
50*2d543d20SAndroid Build Coastguard Worker CONFIG_MEDIA_BACKEND(selabel_media_init),
51*2d543d20SAndroid Build Coastguard Worker CONFIG_X_BACKEND(selabel_x_init),
52*2d543d20SAndroid Build Coastguard Worker CONFIG_DB_BACKEND(selabel_db_init),
53*2d543d20SAndroid Build Coastguard Worker CONFIG_ANDROID_BACKEND(selabel_property_init),
54*2d543d20SAndroid Build Coastguard Worker CONFIG_ANDROID_BACKEND(selabel_exact_match_init),//service init
55*2d543d20SAndroid Build Coastguard Worker CONFIG_ANDROID_BACKEND(selabel_exact_match_init),//keyStore key init
56*2d543d20SAndroid Build Coastguard Worker };
57*2d543d20SAndroid Build Coastguard Worker
selabel_is_digest_set(const struct selinux_opt * opts,unsigned n)58*2d543d20SAndroid Build Coastguard Worker static inline struct selabel_digest *selabel_is_digest_set
59*2d543d20SAndroid Build Coastguard Worker (const struct selinux_opt *opts,
60*2d543d20SAndroid Build Coastguard Worker unsigned n)
61*2d543d20SAndroid Build Coastguard Worker {
62*2d543d20SAndroid Build Coastguard Worker struct selabel_digest *digest = NULL;
63*2d543d20SAndroid Build Coastguard Worker
64*2d543d20SAndroid Build Coastguard Worker while (n) {
65*2d543d20SAndroid Build Coastguard Worker n--;
66*2d543d20SAndroid Build Coastguard Worker if (opts[n].type == SELABEL_OPT_DIGEST &&
67*2d543d20SAndroid Build Coastguard Worker !!opts[n].value) {
68*2d543d20SAndroid Build Coastguard Worker digest = calloc(1, sizeof(*digest));
69*2d543d20SAndroid Build Coastguard Worker if (!digest)
70*2d543d20SAndroid Build Coastguard Worker goto err;
71*2d543d20SAndroid Build Coastguard Worker
72*2d543d20SAndroid Build Coastguard Worker digest->digest = calloc(1, DIGEST_SPECFILE_SIZE + 1);
73*2d543d20SAndroid Build Coastguard Worker if (!digest->digest)
74*2d543d20SAndroid Build Coastguard Worker goto err;
75*2d543d20SAndroid Build Coastguard Worker
76*2d543d20SAndroid Build Coastguard Worker digest->specfile_list = calloc(DIGEST_FILES_MAX,
77*2d543d20SAndroid Build Coastguard Worker sizeof(char *));
78*2d543d20SAndroid Build Coastguard Worker if (!digest->specfile_list)
79*2d543d20SAndroid Build Coastguard Worker goto err;
80*2d543d20SAndroid Build Coastguard Worker
81*2d543d20SAndroid Build Coastguard Worker return digest;
82*2d543d20SAndroid Build Coastguard Worker }
83*2d543d20SAndroid Build Coastguard Worker }
84*2d543d20SAndroid Build Coastguard Worker return NULL;
85*2d543d20SAndroid Build Coastguard Worker
86*2d543d20SAndroid Build Coastguard Worker err:
87*2d543d20SAndroid Build Coastguard Worker if (digest) {
88*2d543d20SAndroid Build Coastguard Worker free(digest->digest);
89*2d543d20SAndroid Build Coastguard Worker free(digest->specfile_list);
90*2d543d20SAndroid Build Coastguard Worker free(digest);
91*2d543d20SAndroid Build Coastguard Worker }
92*2d543d20SAndroid Build Coastguard Worker return NULL;
93*2d543d20SAndroid Build Coastguard Worker }
94*2d543d20SAndroid Build Coastguard Worker
selabel_digest_fini(struct selabel_digest * ptr)95*2d543d20SAndroid Build Coastguard Worker static void selabel_digest_fini(struct selabel_digest *ptr)
96*2d543d20SAndroid Build Coastguard Worker {
97*2d543d20SAndroid Build Coastguard Worker int i;
98*2d543d20SAndroid Build Coastguard Worker
99*2d543d20SAndroid Build Coastguard Worker free(ptr->digest);
100*2d543d20SAndroid Build Coastguard Worker free(ptr->hashbuf);
101*2d543d20SAndroid Build Coastguard Worker
102*2d543d20SAndroid Build Coastguard Worker if (ptr->specfile_list) {
103*2d543d20SAndroid Build Coastguard Worker for (i = 0; ptr->specfile_list[i]; i++)
104*2d543d20SAndroid Build Coastguard Worker free(ptr->specfile_list[i]);
105*2d543d20SAndroid Build Coastguard Worker free(ptr->specfile_list);
106*2d543d20SAndroid Build Coastguard Worker }
107*2d543d20SAndroid Build Coastguard Worker free(ptr);
108*2d543d20SAndroid Build Coastguard Worker }
109*2d543d20SAndroid Build Coastguard Worker
110*2d543d20SAndroid Build Coastguard Worker /*
111*2d543d20SAndroid Build Coastguard Worker * Validation functions
112*2d543d20SAndroid Build Coastguard Worker */
113*2d543d20SAndroid Build Coastguard Worker
selabel_is_validate_set(const struct selinux_opt * opts,unsigned n)114*2d543d20SAndroid Build Coastguard Worker static inline int selabel_is_validate_set(const struct selinux_opt *opts,
115*2d543d20SAndroid Build Coastguard Worker unsigned n)
116*2d543d20SAndroid Build Coastguard Worker {
117*2d543d20SAndroid Build Coastguard Worker while (n) {
118*2d543d20SAndroid Build Coastguard Worker n--;
119*2d543d20SAndroid Build Coastguard Worker if (opts[n].type == SELABEL_OPT_VALIDATE)
120*2d543d20SAndroid Build Coastguard Worker return !!opts[n].value;
121*2d543d20SAndroid Build Coastguard Worker }
122*2d543d20SAndroid Build Coastguard Worker
123*2d543d20SAndroid Build Coastguard Worker return 0;
124*2d543d20SAndroid Build Coastguard Worker }
125*2d543d20SAndroid Build Coastguard Worker
selabel_validate(struct selabel_lookup_rec * contexts)126*2d543d20SAndroid Build Coastguard Worker int selabel_validate(struct selabel_lookup_rec *contexts)
127*2d543d20SAndroid Build Coastguard Worker {
128*2d543d20SAndroid Build Coastguard Worker int rc = 0;
129*2d543d20SAndroid Build Coastguard Worker
130*2d543d20SAndroid Build Coastguard Worker if (contexts->validated)
131*2d543d20SAndroid Build Coastguard Worker goto out;
132*2d543d20SAndroid Build Coastguard Worker
133*2d543d20SAndroid Build Coastguard Worker rc = selinux_validate(&contexts->ctx_raw);
134*2d543d20SAndroid Build Coastguard Worker if (rc < 0)
135*2d543d20SAndroid Build Coastguard Worker goto out;
136*2d543d20SAndroid Build Coastguard Worker
137*2d543d20SAndroid Build Coastguard Worker contexts->validated = true;
138*2d543d20SAndroid Build Coastguard Worker out:
139*2d543d20SAndroid Build Coastguard Worker return rc;
140*2d543d20SAndroid Build Coastguard Worker }
141*2d543d20SAndroid Build Coastguard Worker
142*2d543d20SAndroid Build Coastguard Worker /* Public API helpers */
selabel_fini(const struct selabel_handle * rec,struct selabel_lookup_rec * lr,bool translating)143*2d543d20SAndroid Build Coastguard Worker static int selabel_fini(const struct selabel_handle *rec,
144*2d543d20SAndroid Build Coastguard Worker struct selabel_lookup_rec *lr,
145*2d543d20SAndroid Build Coastguard Worker bool translating)
146*2d543d20SAndroid Build Coastguard Worker {
147*2d543d20SAndroid Build Coastguard Worker char *path = NULL;
148*2d543d20SAndroid Build Coastguard Worker
149*2d543d20SAndroid Build Coastguard Worker if (rec->spec_files)
150*2d543d20SAndroid Build Coastguard Worker path = rec->spec_files[0];
151*2d543d20SAndroid Build Coastguard Worker if (compat_validate(rec, lr, path, lr->lineno))
152*2d543d20SAndroid Build Coastguard Worker return -1;
153*2d543d20SAndroid Build Coastguard Worker
154*2d543d20SAndroid Build Coastguard Worker if (translating && !lr->ctx_trans &&
155*2d543d20SAndroid Build Coastguard Worker selinux_raw_to_trans_context(lr->ctx_raw, &lr->ctx_trans))
156*2d543d20SAndroid Build Coastguard Worker return -1;
157*2d543d20SAndroid Build Coastguard Worker
158*2d543d20SAndroid Build Coastguard Worker return 0;
159*2d543d20SAndroid Build Coastguard Worker }
160*2d543d20SAndroid Build Coastguard Worker
161*2d543d20SAndroid Build Coastguard Worker static struct selabel_lookup_rec *
selabel_lookup_common(struct selabel_handle * rec,bool translating,const char * key,int type)162*2d543d20SAndroid Build Coastguard Worker selabel_lookup_common(struct selabel_handle *rec, bool translating,
163*2d543d20SAndroid Build Coastguard Worker const char *key, int type)
164*2d543d20SAndroid Build Coastguard Worker {
165*2d543d20SAndroid Build Coastguard Worker struct selabel_lookup_rec *lr;
166*2d543d20SAndroid Build Coastguard Worker
167*2d543d20SAndroid Build Coastguard Worker if (key == NULL) {
168*2d543d20SAndroid Build Coastguard Worker errno = EINVAL;
169*2d543d20SAndroid Build Coastguard Worker return NULL;
170*2d543d20SAndroid Build Coastguard Worker }
171*2d543d20SAndroid Build Coastguard Worker
172*2d543d20SAndroid Build Coastguard Worker lr = rec->func_lookup(rec, key, type);
173*2d543d20SAndroid Build Coastguard Worker if (!lr)
174*2d543d20SAndroid Build Coastguard Worker return NULL;
175*2d543d20SAndroid Build Coastguard Worker
176*2d543d20SAndroid Build Coastguard Worker if (selabel_fini(rec, lr, translating))
177*2d543d20SAndroid Build Coastguard Worker return NULL;
178*2d543d20SAndroid Build Coastguard Worker
179*2d543d20SAndroid Build Coastguard Worker return lr;
180*2d543d20SAndroid Build Coastguard Worker }
181*2d543d20SAndroid Build Coastguard Worker
182*2d543d20SAndroid Build Coastguard Worker static struct selabel_lookup_rec *
selabel_lookup_bm_common(struct selabel_handle * rec,bool translating,const char * key,int type,const char ** aliases)183*2d543d20SAndroid Build Coastguard Worker selabel_lookup_bm_common(struct selabel_handle *rec, bool translating,
184*2d543d20SAndroid Build Coastguard Worker const char *key, int type, const char **aliases)
185*2d543d20SAndroid Build Coastguard Worker {
186*2d543d20SAndroid Build Coastguard Worker struct selabel_lookup_rec *lr;
187*2d543d20SAndroid Build Coastguard Worker
188*2d543d20SAndroid Build Coastguard Worker if (key == NULL) {
189*2d543d20SAndroid Build Coastguard Worker errno = EINVAL;
190*2d543d20SAndroid Build Coastguard Worker return NULL;
191*2d543d20SAndroid Build Coastguard Worker }
192*2d543d20SAndroid Build Coastguard Worker
193*2d543d20SAndroid Build Coastguard Worker lr = rec->func_lookup_best_match(rec, key, aliases, type);
194*2d543d20SAndroid Build Coastguard Worker if (!lr)
195*2d543d20SAndroid Build Coastguard Worker return NULL;
196*2d543d20SAndroid Build Coastguard Worker
197*2d543d20SAndroid Build Coastguard Worker if (selabel_fini(rec, lr, translating))
198*2d543d20SAndroid Build Coastguard Worker return NULL;
199*2d543d20SAndroid Build Coastguard Worker
200*2d543d20SAndroid Build Coastguard Worker return lr;
201*2d543d20SAndroid Build Coastguard Worker }
202*2d543d20SAndroid Build Coastguard Worker
203*2d543d20SAndroid Build Coastguard Worker /*
204*2d543d20SAndroid Build Coastguard Worker * Public API
205*2d543d20SAndroid Build Coastguard Worker */
206*2d543d20SAndroid Build Coastguard Worker
selabel_open(unsigned int backend,const struct selinux_opt * opts,unsigned nopts)207*2d543d20SAndroid Build Coastguard Worker struct selabel_handle *selabel_open(unsigned int backend,
208*2d543d20SAndroid Build Coastguard Worker const struct selinux_opt *opts,
209*2d543d20SAndroid Build Coastguard Worker unsigned nopts)
210*2d543d20SAndroid Build Coastguard Worker {
211*2d543d20SAndroid Build Coastguard Worker struct selabel_handle *rec = NULL;
212*2d543d20SAndroid Build Coastguard Worker
213*2d543d20SAndroid Build Coastguard Worker if (backend >= ARRAY_SIZE(initfuncs)) {
214*2d543d20SAndroid Build Coastguard Worker errno = EINVAL;
215*2d543d20SAndroid Build Coastguard Worker goto out;
216*2d543d20SAndroid Build Coastguard Worker }
217*2d543d20SAndroid Build Coastguard Worker
218*2d543d20SAndroid Build Coastguard Worker if (!initfuncs[backend]) {
219*2d543d20SAndroid Build Coastguard Worker errno = ENOTSUP;
220*2d543d20SAndroid Build Coastguard Worker goto out;
221*2d543d20SAndroid Build Coastguard Worker }
222*2d543d20SAndroid Build Coastguard Worker
223*2d543d20SAndroid Build Coastguard Worker rec = (struct selabel_handle *)calloc(1, sizeof(*rec));
224*2d543d20SAndroid Build Coastguard Worker if (!rec)
225*2d543d20SAndroid Build Coastguard Worker goto out;
226*2d543d20SAndroid Build Coastguard Worker
227*2d543d20SAndroid Build Coastguard Worker rec->backend = backend;
228*2d543d20SAndroid Build Coastguard Worker rec->validating = selabel_is_validate_set(opts, nopts);
229*2d543d20SAndroid Build Coastguard Worker
230*2d543d20SAndroid Build Coastguard Worker rec->digest = selabel_is_digest_set(opts, nopts);
231*2d543d20SAndroid Build Coastguard Worker
232*2d543d20SAndroid Build Coastguard Worker if ((*initfuncs[backend])(rec, opts, nopts)) {
233*2d543d20SAndroid Build Coastguard Worker selabel_close(rec);
234*2d543d20SAndroid Build Coastguard Worker rec = NULL;
235*2d543d20SAndroid Build Coastguard Worker }
236*2d543d20SAndroid Build Coastguard Worker out:
237*2d543d20SAndroid Build Coastguard Worker return rec;
238*2d543d20SAndroid Build Coastguard Worker }
239*2d543d20SAndroid Build Coastguard Worker
selabel_lookup(struct selabel_handle * rec,char ** con,const char * key,int type)240*2d543d20SAndroid Build Coastguard Worker int selabel_lookup(struct selabel_handle *rec, char **con,
241*2d543d20SAndroid Build Coastguard Worker const char *key, int type)
242*2d543d20SAndroid Build Coastguard Worker {
243*2d543d20SAndroid Build Coastguard Worker struct selabel_lookup_rec *lr;
244*2d543d20SAndroid Build Coastguard Worker
245*2d543d20SAndroid Build Coastguard Worker lr = selabel_lookup_common(rec, true, key, type);
246*2d543d20SAndroid Build Coastguard Worker if (!lr)
247*2d543d20SAndroid Build Coastguard Worker return -1;
248*2d543d20SAndroid Build Coastguard Worker
249*2d543d20SAndroid Build Coastguard Worker *con = strdup(lr->ctx_trans);
250*2d543d20SAndroid Build Coastguard Worker return *con ? 0 : -1;
251*2d543d20SAndroid Build Coastguard Worker }
252*2d543d20SAndroid Build Coastguard Worker
selabel_lookup_raw(struct selabel_handle * rec,char ** con,const char * key,int type)253*2d543d20SAndroid Build Coastguard Worker int selabel_lookup_raw(struct selabel_handle *rec, char **con,
254*2d543d20SAndroid Build Coastguard Worker const char *key, int type)
255*2d543d20SAndroid Build Coastguard Worker {
256*2d543d20SAndroid Build Coastguard Worker struct selabel_lookup_rec *lr;
257*2d543d20SAndroid Build Coastguard Worker
258*2d543d20SAndroid Build Coastguard Worker lr = selabel_lookup_common(rec, false, key, type);
259*2d543d20SAndroid Build Coastguard Worker if (!lr)
260*2d543d20SAndroid Build Coastguard Worker return -1;
261*2d543d20SAndroid Build Coastguard Worker
262*2d543d20SAndroid Build Coastguard Worker *con = strdup(lr->ctx_raw);
263*2d543d20SAndroid Build Coastguard Worker return *con ? 0 : -1;
264*2d543d20SAndroid Build Coastguard Worker }
265*2d543d20SAndroid Build Coastguard Worker
selabel_partial_match(struct selabel_handle * rec,const char * key)266*2d543d20SAndroid Build Coastguard Worker bool selabel_partial_match(struct selabel_handle *rec, const char *key)
267*2d543d20SAndroid Build Coastguard Worker {
268*2d543d20SAndroid Build Coastguard Worker if (!rec->func_partial_match) {
269*2d543d20SAndroid Build Coastguard Worker /*
270*2d543d20SAndroid Build Coastguard Worker * If the label backend does not support partial matching,
271*2d543d20SAndroid Build Coastguard Worker * then assume a match is possible.
272*2d543d20SAndroid Build Coastguard Worker */
273*2d543d20SAndroid Build Coastguard Worker return true;
274*2d543d20SAndroid Build Coastguard Worker }
275*2d543d20SAndroid Build Coastguard Worker
276*2d543d20SAndroid Build Coastguard Worker return rec->func_partial_match(rec, key);
277*2d543d20SAndroid Build Coastguard Worker }
278*2d543d20SAndroid Build Coastguard Worker
selabel_get_digests_all_partial_matches(struct selabel_handle * rec,const char * key,uint8_t ** calculated_digest,uint8_t ** xattr_digest,size_t * digest_len)279*2d543d20SAndroid Build Coastguard Worker bool selabel_get_digests_all_partial_matches(struct selabel_handle *rec,
280*2d543d20SAndroid Build Coastguard Worker const char *key,
281*2d543d20SAndroid Build Coastguard Worker uint8_t **calculated_digest,
282*2d543d20SAndroid Build Coastguard Worker uint8_t **xattr_digest,
283*2d543d20SAndroid Build Coastguard Worker size_t *digest_len)
284*2d543d20SAndroid Build Coastguard Worker {
285*2d543d20SAndroid Build Coastguard Worker if (!rec->func_get_digests_all_partial_matches)
286*2d543d20SAndroid Build Coastguard Worker return false;
287*2d543d20SAndroid Build Coastguard Worker
288*2d543d20SAndroid Build Coastguard Worker return rec->func_get_digests_all_partial_matches(rec, key,
289*2d543d20SAndroid Build Coastguard Worker calculated_digest,
290*2d543d20SAndroid Build Coastguard Worker xattr_digest,
291*2d543d20SAndroid Build Coastguard Worker digest_len);
292*2d543d20SAndroid Build Coastguard Worker }
293*2d543d20SAndroid Build Coastguard Worker
selabel_hash_all_partial_matches(struct selabel_handle * rec,const char * key,uint8_t * digest)294*2d543d20SAndroid Build Coastguard Worker bool selabel_hash_all_partial_matches(struct selabel_handle *rec,
295*2d543d20SAndroid Build Coastguard Worker const char *key, uint8_t *digest) {
296*2d543d20SAndroid Build Coastguard Worker if (!rec->func_hash_all_partial_matches) {
297*2d543d20SAndroid Build Coastguard Worker return false;
298*2d543d20SAndroid Build Coastguard Worker }
299*2d543d20SAndroid Build Coastguard Worker
300*2d543d20SAndroid Build Coastguard Worker return rec->func_hash_all_partial_matches(rec, key, digest);
301*2d543d20SAndroid Build Coastguard Worker }
302*2d543d20SAndroid Build Coastguard Worker
selabel_lookup_best_match(struct selabel_handle * rec,char ** con,const char * key,const char ** aliases,int type)303*2d543d20SAndroid Build Coastguard Worker int selabel_lookup_best_match(struct selabel_handle *rec, char **con,
304*2d543d20SAndroid Build Coastguard Worker const char *key, const char **aliases, int type)
305*2d543d20SAndroid Build Coastguard Worker {
306*2d543d20SAndroid Build Coastguard Worker struct selabel_lookup_rec *lr;
307*2d543d20SAndroid Build Coastguard Worker
308*2d543d20SAndroid Build Coastguard Worker if (!rec->func_lookup_best_match) {
309*2d543d20SAndroid Build Coastguard Worker errno = ENOTSUP;
310*2d543d20SAndroid Build Coastguard Worker return -1;
311*2d543d20SAndroid Build Coastguard Worker }
312*2d543d20SAndroid Build Coastguard Worker
313*2d543d20SAndroid Build Coastguard Worker lr = selabel_lookup_bm_common(rec, true, key, type, aliases);
314*2d543d20SAndroid Build Coastguard Worker if (!lr)
315*2d543d20SAndroid Build Coastguard Worker return -1;
316*2d543d20SAndroid Build Coastguard Worker
317*2d543d20SAndroid Build Coastguard Worker *con = strdup(lr->ctx_trans);
318*2d543d20SAndroid Build Coastguard Worker return *con ? 0 : -1;
319*2d543d20SAndroid Build Coastguard Worker }
320*2d543d20SAndroid Build Coastguard Worker
selabel_lookup_best_match_raw(struct selabel_handle * rec,char ** con,const char * key,const char ** aliases,int type)321*2d543d20SAndroid Build Coastguard Worker int selabel_lookup_best_match_raw(struct selabel_handle *rec, char **con,
322*2d543d20SAndroid Build Coastguard Worker const char *key, const char **aliases, int type)
323*2d543d20SAndroid Build Coastguard Worker {
324*2d543d20SAndroid Build Coastguard Worker struct selabel_lookup_rec *lr;
325*2d543d20SAndroid Build Coastguard Worker
326*2d543d20SAndroid Build Coastguard Worker if (!rec->func_lookup_best_match) {
327*2d543d20SAndroid Build Coastguard Worker errno = ENOTSUP;
328*2d543d20SAndroid Build Coastguard Worker return -1;
329*2d543d20SAndroid Build Coastguard Worker }
330*2d543d20SAndroid Build Coastguard Worker
331*2d543d20SAndroid Build Coastguard Worker lr = selabel_lookup_bm_common(rec, false, key, type, aliases);
332*2d543d20SAndroid Build Coastguard Worker if (!lr)
333*2d543d20SAndroid Build Coastguard Worker return -1;
334*2d543d20SAndroid Build Coastguard Worker
335*2d543d20SAndroid Build Coastguard Worker *con = strdup(lr->ctx_raw);
336*2d543d20SAndroid Build Coastguard Worker return *con ? 0 : -1;
337*2d543d20SAndroid Build Coastguard Worker }
338*2d543d20SAndroid Build Coastguard Worker
selabel_cmp(const struct selabel_handle * h1,const struct selabel_handle * h2)339*2d543d20SAndroid Build Coastguard Worker enum selabel_cmp_result selabel_cmp(const struct selabel_handle *h1,
340*2d543d20SAndroid Build Coastguard Worker const struct selabel_handle *h2)
341*2d543d20SAndroid Build Coastguard Worker {
342*2d543d20SAndroid Build Coastguard Worker if (!h1->func_cmp || h1->func_cmp != h2->func_cmp)
343*2d543d20SAndroid Build Coastguard Worker return SELABEL_INCOMPARABLE;
344*2d543d20SAndroid Build Coastguard Worker
345*2d543d20SAndroid Build Coastguard Worker return h1->func_cmp(h1, h2);
346*2d543d20SAndroid Build Coastguard Worker }
347*2d543d20SAndroid Build Coastguard Worker
selabel_digest(struct selabel_handle * rec,unsigned char ** digest,size_t * digest_len,char *** specfiles,size_t * num_specfiles)348*2d543d20SAndroid Build Coastguard Worker int selabel_digest(struct selabel_handle *rec,
349*2d543d20SAndroid Build Coastguard Worker unsigned char **digest, size_t *digest_len,
350*2d543d20SAndroid Build Coastguard Worker char ***specfiles, size_t *num_specfiles)
351*2d543d20SAndroid Build Coastguard Worker {
352*2d543d20SAndroid Build Coastguard Worker if (!rec->digest) {
353*2d543d20SAndroid Build Coastguard Worker errno = EINVAL;
354*2d543d20SAndroid Build Coastguard Worker return -1;
355*2d543d20SAndroid Build Coastguard Worker }
356*2d543d20SAndroid Build Coastguard Worker
357*2d543d20SAndroid Build Coastguard Worker *digest = rec->digest->digest;
358*2d543d20SAndroid Build Coastguard Worker *digest_len = DIGEST_SPECFILE_SIZE;
359*2d543d20SAndroid Build Coastguard Worker *specfiles = rec->digest->specfile_list;
360*2d543d20SAndroid Build Coastguard Worker *num_specfiles = rec->digest->specfile_cnt;
361*2d543d20SAndroid Build Coastguard Worker return 0;
362*2d543d20SAndroid Build Coastguard Worker }
363*2d543d20SAndroid Build Coastguard Worker
selabel_close(struct selabel_handle * rec)364*2d543d20SAndroid Build Coastguard Worker void selabel_close(struct selabel_handle *rec)
365*2d543d20SAndroid Build Coastguard Worker {
366*2d543d20SAndroid Build Coastguard Worker size_t i;
367*2d543d20SAndroid Build Coastguard Worker
368*2d543d20SAndroid Build Coastguard Worker if (rec->spec_files) {
369*2d543d20SAndroid Build Coastguard Worker for (i = 0; i < rec->spec_files_len; i++)
370*2d543d20SAndroid Build Coastguard Worker free(rec->spec_files[i]);
371*2d543d20SAndroid Build Coastguard Worker free(rec->spec_files);
372*2d543d20SAndroid Build Coastguard Worker }
373*2d543d20SAndroid Build Coastguard Worker if (rec->digest)
374*2d543d20SAndroid Build Coastguard Worker selabel_digest_fini(rec->digest);
375*2d543d20SAndroid Build Coastguard Worker if (rec->func_close)
376*2d543d20SAndroid Build Coastguard Worker rec->func_close(rec);
377*2d543d20SAndroid Build Coastguard Worker free(rec);
378*2d543d20SAndroid Build Coastguard Worker }
379*2d543d20SAndroid Build Coastguard Worker
selabel_stats(struct selabel_handle * rec)380*2d543d20SAndroid Build Coastguard Worker void selabel_stats(struct selabel_handle *rec)
381*2d543d20SAndroid Build Coastguard Worker {
382*2d543d20SAndroid Build Coastguard Worker rec->func_stats(rec);
383*2d543d20SAndroid Build Coastguard Worker }
384