16cd6a6acSopenharmony_ci/* 26cd6a6acSopenharmony_ci * Generalized labeling frontend for userspace object managers. 36cd6a6acSopenharmony_ci * 46cd6a6acSopenharmony_ci * Author : Eamon Walsh <ewalsh@epoch.ncsc.mil> 56cd6a6acSopenharmony_ci */ 66cd6a6acSopenharmony_ci 76cd6a6acSopenharmony_ci#include <sys/types.h> 86cd6a6acSopenharmony_ci#include <ctype.h> 96cd6a6acSopenharmony_ci#include <errno.h> 106cd6a6acSopenharmony_ci#include <stdio.h> 116cd6a6acSopenharmony_ci#include <stdlib.h> 126cd6a6acSopenharmony_ci#include <string.h> 136cd6a6acSopenharmony_ci#include <sys/stat.h> 146cd6a6acSopenharmony_ci#include <selinux/selinux.h> 156cd6a6acSopenharmony_ci#include "callbacks.h" 166cd6a6acSopenharmony_ci#include "label_internal.h" 176cd6a6acSopenharmony_ci 186cd6a6acSopenharmony_ci#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) 196cd6a6acSopenharmony_ci 206cd6a6acSopenharmony_ci#ifdef NO_MEDIA_BACKEND 216cd6a6acSopenharmony_ci#define CONFIG_MEDIA_BACKEND(fnptr) NULL 226cd6a6acSopenharmony_ci#else 236cd6a6acSopenharmony_ci#define CONFIG_MEDIA_BACKEND(fnptr) &fnptr 246cd6a6acSopenharmony_ci#endif 256cd6a6acSopenharmony_ci 266cd6a6acSopenharmony_ci#ifdef NO_X_BACKEND 276cd6a6acSopenharmony_ci#define CONFIG_X_BACKEND(fnptr) NULL 286cd6a6acSopenharmony_ci#else 296cd6a6acSopenharmony_ci#define CONFIG_X_BACKEND(fnptr) &fnptr 306cd6a6acSopenharmony_ci#endif 316cd6a6acSopenharmony_ci 326cd6a6acSopenharmony_ci#ifdef NO_DB_BACKEND 336cd6a6acSopenharmony_ci#define CONFIG_DB_BACKEND(fnptr) NULL 346cd6a6acSopenharmony_ci#else 356cd6a6acSopenharmony_ci#define CONFIG_DB_BACKEND(fnptr) &fnptr 366cd6a6acSopenharmony_ci#endif 376cd6a6acSopenharmony_ci 386cd6a6acSopenharmony_ci#ifdef NO_ANDROID_BACKEND 396cd6a6acSopenharmony_ci#define CONFIG_ANDROID_BACKEND(fnptr) NULL 406cd6a6acSopenharmony_ci#else 416cd6a6acSopenharmony_ci#define CONFIG_ANDROID_BACKEND(fnptr) (&(fnptr)) 426cd6a6acSopenharmony_ci#endif 436cd6a6acSopenharmony_ci 446cd6a6acSopenharmony_citypedef int (*selabel_initfunc)(struct selabel_handle *rec, 456cd6a6acSopenharmony_ci const struct selinux_opt *opts, 466cd6a6acSopenharmony_ci unsigned nopts); 476cd6a6acSopenharmony_ci 486cd6a6acSopenharmony_cistatic selabel_initfunc initfuncs[] = { 496cd6a6acSopenharmony_ci &selabel_file_init, 506cd6a6acSopenharmony_ci CONFIG_MEDIA_BACKEND(selabel_media_init), 516cd6a6acSopenharmony_ci CONFIG_X_BACKEND(selabel_x_init), 526cd6a6acSopenharmony_ci CONFIG_DB_BACKEND(selabel_db_init), 536cd6a6acSopenharmony_ci CONFIG_ANDROID_BACKEND(selabel_property_init), 546cd6a6acSopenharmony_ci CONFIG_ANDROID_BACKEND(selabel_service_init), 556cd6a6acSopenharmony_ci}; 566cd6a6acSopenharmony_ci 576cd6a6acSopenharmony_cistatic inline struct selabel_digest *selabel_is_digest_set 586cd6a6acSopenharmony_ci (const struct selinux_opt *opts, 596cd6a6acSopenharmony_ci unsigned n, 606cd6a6acSopenharmony_ci struct selabel_digest *entry) 616cd6a6acSopenharmony_ci{ 626cd6a6acSopenharmony_ci struct selabel_digest *digest = NULL; 636cd6a6acSopenharmony_ci 646cd6a6acSopenharmony_ci while (n--) { 656cd6a6acSopenharmony_ci if (opts[n].type == SELABEL_OPT_DIGEST && 666cd6a6acSopenharmony_ci opts[n].value == (char *)1) { 676cd6a6acSopenharmony_ci digest = calloc(1, sizeof(*digest)); 686cd6a6acSopenharmony_ci if (!digest) 696cd6a6acSopenharmony_ci goto err; 706cd6a6acSopenharmony_ci 716cd6a6acSopenharmony_ci digest->digest = calloc(1, DIGEST_SPECFILE_SIZE + 1); 726cd6a6acSopenharmony_ci if (!digest->digest) 736cd6a6acSopenharmony_ci goto err; 746cd6a6acSopenharmony_ci 756cd6a6acSopenharmony_ci digest->specfile_list = calloc(DIGEST_FILES_MAX, 766cd6a6acSopenharmony_ci sizeof(char *)); 776cd6a6acSopenharmony_ci if (!digest->specfile_list) 786cd6a6acSopenharmony_ci goto err; 796cd6a6acSopenharmony_ci 806cd6a6acSopenharmony_ci entry = digest; 816cd6a6acSopenharmony_ci return entry; 826cd6a6acSopenharmony_ci } 836cd6a6acSopenharmony_ci } 846cd6a6acSopenharmony_ci return NULL; 856cd6a6acSopenharmony_ci 866cd6a6acSopenharmony_cierr: 876cd6a6acSopenharmony_ci if (digest) { 886cd6a6acSopenharmony_ci free(digest->digest); 896cd6a6acSopenharmony_ci free(digest->specfile_list); 906cd6a6acSopenharmony_ci free(digest); 916cd6a6acSopenharmony_ci } 926cd6a6acSopenharmony_ci return NULL; 936cd6a6acSopenharmony_ci} 946cd6a6acSopenharmony_ci 956cd6a6acSopenharmony_cistatic void selabel_digest_fini(struct selabel_digest *ptr) 966cd6a6acSopenharmony_ci{ 976cd6a6acSopenharmony_ci int i; 986cd6a6acSopenharmony_ci 996cd6a6acSopenharmony_ci free(ptr->digest); 1006cd6a6acSopenharmony_ci free(ptr->hashbuf); 1016cd6a6acSopenharmony_ci 1026cd6a6acSopenharmony_ci if (ptr->specfile_list) { 1036cd6a6acSopenharmony_ci for (i = 0; ptr->specfile_list[i]; i++) 1046cd6a6acSopenharmony_ci free(ptr->specfile_list[i]); 1056cd6a6acSopenharmony_ci free(ptr->specfile_list); 1066cd6a6acSopenharmony_ci } 1076cd6a6acSopenharmony_ci free(ptr); 1086cd6a6acSopenharmony_ci} 1096cd6a6acSopenharmony_ci 1106cd6a6acSopenharmony_ci/* 1116cd6a6acSopenharmony_ci * Validation functions 1126cd6a6acSopenharmony_ci */ 1136cd6a6acSopenharmony_ci 1146cd6a6acSopenharmony_cistatic inline int selabel_is_validate_set(const struct selinux_opt *opts, 1156cd6a6acSopenharmony_ci unsigned n) 1166cd6a6acSopenharmony_ci{ 1176cd6a6acSopenharmony_ci while (n--) 1186cd6a6acSopenharmony_ci if (opts[n].type == SELABEL_OPT_VALIDATE) 1196cd6a6acSopenharmony_ci return !!opts[n].value; 1206cd6a6acSopenharmony_ci 1216cd6a6acSopenharmony_ci return 0; 1226cd6a6acSopenharmony_ci} 1236cd6a6acSopenharmony_ci 1246cd6a6acSopenharmony_ciint selabel_validate(struct selabel_handle *rec, 1256cd6a6acSopenharmony_ci struct selabel_lookup_rec *contexts) 1266cd6a6acSopenharmony_ci{ 1276cd6a6acSopenharmony_ci int rc = 0; 1286cd6a6acSopenharmony_ci 1296cd6a6acSopenharmony_ci if (!rec->validating || contexts->validated) 1306cd6a6acSopenharmony_ci goto out; 1316cd6a6acSopenharmony_ci 1326cd6a6acSopenharmony_ci rc = selinux_validate(&contexts->ctx_raw); 1336cd6a6acSopenharmony_ci if (rc < 0) 1346cd6a6acSopenharmony_ci goto out; 1356cd6a6acSopenharmony_ci 1366cd6a6acSopenharmony_ci contexts->validated = 1; 1376cd6a6acSopenharmony_ciout: 1386cd6a6acSopenharmony_ci return rc; 1396cd6a6acSopenharmony_ci} 1406cd6a6acSopenharmony_ci 1416cd6a6acSopenharmony_ci/* Public API helpers */ 1426cd6a6acSopenharmony_cistatic int selabel_fini(struct selabel_handle *rec, 1436cd6a6acSopenharmony_ci struct selabel_lookup_rec *lr, 1446cd6a6acSopenharmony_ci int translating) 1456cd6a6acSopenharmony_ci{ 1466cd6a6acSopenharmony_ci#ifdef OHOS_FC_INIT 1476cd6a6acSopenharmony_ci char *path = NULL; 1486cd6a6acSopenharmony_ci if (rec->spec_file != NULL) { 1496cd6a6acSopenharmony_ci path = rec->spec_file[0]; 1506cd6a6acSopenharmony_ci } 1516cd6a6acSopenharmony_ci if (compat_validate(rec, lr, path, lr->lineno)) 1526cd6a6acSopenharmony_ci return -1; 1536cd6a6acSopenharmony_ci#else 1546cd6a6acSopenharmony_ci if (compat_validate(rec, lr, rec->spec_file, lr->lineno)) 1556cd6a6acSopenharmony_ci return -1; 1566cd6a6acSopenharmony_ci#endif 1576cd6a6acSopenharmony_ci 1586cd6a6acSopenharmony_ci if (translating && !lr->ctx_trans && 1596cd6a6acSopenharmony_ci selinux_raw_to_trans_context(lr->ctx_raw, &lr->ctx_trans)) 1606cd6a6acSopenharmony_ci return -1; 1616cd6a6acSopenharmony_ci 1626cd6a6acSopenharmony_ci return 0; 1636cd6a6acSopenharmony_ci} 1646cd6a6acSopenharmony_ci 1656cd6a6acSopenharmony_cistatic struct selabel_lookup_rec * 1666cd6a6acSopenharmony_ciselabel_lookup_common(struct selabel_handle *rec, int translating, 1676cd6a6acSopenharmony_ci const char *key, int type) 1686cd6a6acSopenharmony_ci{ 1696cd6a6acSopenharmony_ci struct selabel_lookup_rec *lr; 1706cd6a6acSopenharmony_ci 1716cd6a6acSopenharmony_ci if (key == NULL) { 1726cd6a6acSopenharmony_ci errno = EINVAL; 1736cd6a6acSopenharmony_ci return NULL; 1746cd6a6acSopenharmony_ci } 1756cd6a6acSopenharmony_ci 1766cd6a6acSopenharmony_ci lr = rec->func_lookup(rec, key, type); 1776cd6a6acSopenharmony_ci if (!lr) 1786cd6a6acSopenharmony_ci return NULL; 1796cd6a6acSopenharmony_ci 1806cd6a6acSopenharmony_ci if (selabel_fini(rec, lr, translating)) 1816cd6a6acSopenharmony_ci return NULL; 1826cd6a6acSopenharmony_ci 1836cd6a6acSopenharmony_ci return lr; 1846cd6a6acSopenharmony_ci} 1856cd6a6acSopenharmony_ci 1866cd6a6acSopenharmony_cistatic struct selabel_lookup_rec * 1876cd6a6acSopenharmony_ciselabel_lookup_bm_common(struct selabel_handle *rec, int translating, 1886cd6a6acSopenharmony_ci const char *key, int type, const char **aliases) 1896cd6a6acSopenharmony_ci{ 1906cd6a6acSopenharmony_ci struct selabel_lookup_rec *lr; 1916cd6a6acSopenharmony_ci 1926cd6a6acSopenharmony_ci if (key == NULL) { 1936cd6a6acSopenharmony_ci errno = EINVAL; 1946cd6a6acSopenharmony_ci return NULL; 1956cd6a6acSopenharmony_ci } 1966cd6a6acSopenharmony_ci 1976cd6a6acSopenharmony_ci lr = rec->func_lookup_best_match(rec, key, aliases, type); 1986cd6a6acSopenharmony_ci if (!lr) 1996cd6a6acSopenharmony_ci return NULL; 2006cd6a6acSopenharmony_ci 2016cd6a6acSopenharmony_ci if (selabel_fini(rec, lr, translating)) 2026cd6a6acSopenharmony_ci return NULL; 2036cd6a6acSopenharmony_ci 2046cd6a6acSopenharmony_ci return lr; 2056cd6a6acSopenharmony_ci} 2066cd6a6acSopenharmony_ci 2076cd6a6acSopenharmony_ci#ifdef OHOS_FC_INIT 2086cd6a6acSopenharmony_cistatic void free_spec_files(struct selabel_handle *rec) 2096cd6a6acSopenharmony_ci{ 2106cd6a6acSopenharmony_ci if (rec->spec_file != NULL) { 2116cd6a6acSopenharmony_ci for (int path_index = 0; path_index < rec->spec_file_nums; path_index++) { 2126cd6a6acSopenharmony_ci if (rec->spec_file[path_index] != NULL) { 2136cd6a6acSopenharmony_ci free(rec->spec_file[path_index]); 2146cd6a6acSopenharmony_ci } 2156cd6a6acSopenharmony_ci } 2166cd6a6acSopenharmony_ci free(rec->spec_file); 2176cd6a6acSopenharmony_ci } 2186cd6a6acSopenharmony_ci} 2196cd6a6acSopenharmony_ci#endif 2206cd6a6acSopenharmony_ci 2216cd6a6acSopenharmony_ci/* 2226cd6a6acSopenharmony_ci * Public API 2236cd6a6acSopenharmony_ci */ 2246cd6a6acSopenharmony_ci 2256cd6a6acSopenharmony_cistruct selabel_handle *selabel_open(unsigned int backend, 2266cd6a6acSopenharmony_ci const struct selinux_opt *opts, 2276cd6a6acSopenharmony_ci unsigned nopts) 2286cd6a6acSopenharmony_ci{ 2296cd6a6acSopenharmony_ci struct selabel_handle *rec = NULL; 2306cd6a6acSopenharmony_ci 2316cd6a6acSopenharmony_ci if (backend >= ARRAY_SIZE(initfuncs)) { 2326cd6a6acSopenharmony_ci errno = EINVAL; 2336cd6a6acSopenharmony_ci goto out; 2346cd6a6acSopenharmony_ci } 2356cd6a6acSopenharmony_ci 2366cd6a6acSopenharmony_ci if (!initfuncs[backend]) { 2376cd6a6acSopenharmony_ci errno = ENOTSUP; 2386cd6a6acSopenharmony_ci goto out; 2396cd6a6acSopenharmony_ci } 2406cd6a6acSopenharmony_ci 2416cd6a6acSopenharmony_ci rec = (struct selabel_handle *)malloc(sizeof(*rec)); 2426cd6a6acSopenharmony_ci if (!rec) 2436cd6a6acSopenharmony_ci goto out; 2446cd6a6acSopenharmony_ci 2456cd6a6acSopenharmony_ci memset(rec, 0, sizeof(*rec)); 2466cd6a6acSopenharmony_ci rec->backend = backend; 2476cd6a6acSopenharmony_ci rec->validating = selabel_is_validate_set(opts, nopts); 2486cd6a6acSopenharmony_ci 2496cd6a6acSopenharmony_ci rec->digest = selabel_is_digest_set(opts, nopts, rec->digest); 2506cd6a6acSopenharmony_ci 2516cd6a6acSopenharmony_ci if ((*initfuncs[backend])(rec, opts, nopts)) { 2526cd6a6acSopenharmony_ci if (rec->digest) 2536cd6a6acSopenharmony_ci selabel_digest_fini(rec->digest); 2546cd6a6acSopenharmony_ci#ifdef OHOS_FC_INIT 2556cd6a6acSopenharmony_ci free_spec_files(rec); 2566cd6a6acSopenharmony_ci#else 2576cd6a6acSopenharmony_ci free(rec->spec_file); 2586cd6a6acSopenharmony_ci#endif 2596cd6a6acSopenharmony_ci free(rec); 2606cd6a6acSopenharmony_ci rec = NULL; 2616cd6a6acSopenharmony_ci } 2626cd6a6acSopenharmony_ci 2636cd6a6acSopenharmony_ciout: 2646cd6a6acSopenharmony_ci return rec; 2656cd6a6acSopenharmony_ci} 2666cd6a6acSopenharmony_ci 2676cd6a6acSopenharmony_ciint selabel_lookup(struct selabel_handle *rec, char **con, 2686cd6a6acSopenharmony_ci const char *key, int type) 2696cd6a6acSopenharmony_ci{ 2706cd6a6acSopenharmony_ci struct selabel_lookup_rec *lr; 2716cd6a6acSopenharmony_ci 2726cd6a6acSopenharmony_ci lr = selabel_lookup_common(rec, 1, key, type); 2736cd6a6acSopenharmony_ci if (!lr) 2746cd6a6acSopenharmony_ci return -1; 2756cd6a6acSopenharmony_ci 2766cd6a6acSopenharmony_ci *con = strdup(lr->ctx_trans); 2776cd6a6acSopenharmony_ci return *con ? 0 : -1; 2786cd6a6acSopenharmony_ci} 2796cd6a6acSopenharmony_ci 2806cd6a6acSopenharmony_ciint selabel_lookup_raw(struct selabel_handle *rec, char **con, 2816cd6a6acSopenharmony_ci const char *key, int type) 2826cd6a6acSopenharmony_ci{ 2836cd6a6acSopenharmony_ci struct selabel_lookup_rec *lr; 2846cd6a6acSopenharmony_ci 2856cd6a6acSopenharmony_ci lr = selabel_lookup_common(rec, 0, key, type); 2866cd6a6acSopenharmony_ci if (!lr) 2876cd6a6acSopenharmony_ci return -1; 2886cd6a6acSopenharmony_ci 2896cd6a6acSopenharmony_ci *con = strdup(lr->ctx_raw); 2906cd6a6acSopenharmony_ci return *con ? 0 : -1; 2916cd6a6acSopenharmony_ci} 2926cd6a6acSopenharmony_ci 2936cd6a6acSopenharmony_cibool selabel_partial_match(struct selabel_handle *rec, const char *key) 2946cd6a6acSopenharmony_ci{ 2956cd6a6acSopenharmony_ci if (!rec->func_partial_match) { 2966cd6a6acSopenharmony_ci /* 2976cd6a6acSopenharmony_ci * If the label backend does not support partial matching, 2986cd6a6acSopenharmony_ci * then assume a match is possible. 2996cd6a6acSopenharmony_ci */ 3006cd6a6acSopenharmony_ci return true; 3016cd6a6acSopenharmony_ci } 3026cd6a6acSopenharmony_ci 3036cd6a6acSopenharmony_ci return rec->func_partial_match(rec, key); 3046cd6a6acSopenharmony_ci} 3056cd6a6acSopenharmony_ci 3066cd6a6acSopenharmony_cibool selabel_get_digests_all_partial_matches(struct selabel_handle *rec, 3076cd6a6acSopenharmony_ci const char *key, 3086cd6a6acSopenharmony_ci uint8_t **calculated_digest, 3096cd6a6acSopenharmony_ci uint8_t **xattr_digest, 3106cd6a6acSopenharmony_ci size_t *digest_len) 3116cd6a6acSopenharmony_ci{ 3126cd6a6acSopenharmony_ci if (!rec->func_get_digests_all_partial_matches) 3136cd6a6acSopenharmony_ci return false; 3146cd6a6acSopenharmony_ci 3156cd6a6acSopenharmony_ci return rec->func_get_digests_all_partial_matches(rec, key, 3166cd6a6acSopenharmony_ci calculated_digest, 3176cd6a6acSopenharmony_ci xattr_digest, 3186cd6a6acSopenharmony_ci digest_len); 3196cd6a6acSopenharmony_ci} 3206cd6a6acSopenharmony_ci 3216cd6a6acSopenharmony_cibool selabel_hash_all_partial_matches(struct selabel_handle *rec, 3226cd6a6acSopenharmony_ci const char *key, uint8_t *digest) { 3236cd6a6acSopenharmony_ci if (!rec->func_hash_all_partial_matches) { 3246cd6a6acSopenharmony_ci return false; 3256cd6a6acSopenharmony_ci } 3266cd6a6acSopenharmony_ci 3276cd6a6acSopenharmony_ci return rec->func_hash_all_partial_matches(rec, key, digest); 3286cd6a6acSopenharmony_ci} 3296cd6a6acSopenharmony_ci 3306cd6a6acSopenharmony_ciint selabel_lookup_best_match(struct selabel_handle *rec, char **con, 3316cd6a6acSopenharmony_ci const char *key, const char **aliases, int type) 3326cd6a6acSopenharmony_ci{ 3336cd6a6acSopenharmony_ci struct selabel_lookup_rec *lr; 3346cd6a6acSopenharmony_ci 3356cd6a6acSopenharmony_ci if (!rec->func_lookup_best_match) { 3366cd6a6acSopenharmony_ci errno = ENOTSUP; 3376cd6a6acSopenharmony_ci return -1; 3386cd6a6acSopenharmony_ci } 3396cd6a6acSopenharmony_ci 3406cd6a6acSopenharmony_ci lr = selabel_lookup_bm_common(rec, 1, key, type, aliases); 3416cd6a6acSopenharmony_ci if (!lr) 3426cd6a6acSopenharmony_ci return -1; 3436cd6a6acSopenharmony_ci 3446cd6a6acSopenharmony_ci *con = strdup(lr->ctx_trans); 3456cd6a6acSopenharmony_ci return *con ? 0 : -1; 3466cd6a6acSopenharmony_ci} 3476cd6a6acSopenharmony_ci 3486cd6a6acSopenharmony_ciint selabel_lookup_best_match_raw(struct selabel_handle *rec, char **con, 3496cd6a6acSopenharmony_ci const char *key, const char **aliases, int type) 3506cd6a6acSopenharmony_ci{ 3516cd6a6acSopenharmony_ci struct selabel_lookup_rec *lr; 3526cd6a6acSopenharmony_ci 3536cd6a6acSopenharmony_ci if (!rec->func_lookup_best_match) { 3546cd6a6acSopenharmony_ci errno = ENOTSUP; 3556cd6a6acSopenharmony_ci return -1; 3566cd6a6acSopenharmony_ci } 3576cd6a6acSopenharmony_ci 3586cd6a6acSopenharmony_ci lr = selabel_lookup_bm_common(rec, 0, key, type, aliases); 3596cd6a6acSopenharmony_ci if (!lr) 3606cd6a6acSopenharmony_ci return -1; 3616cd6a6acSopenharmony_ci 3626cd6a6acSopenharmony_ci *con = strdup(lr->ctx_raw); 3636cd6a6acSopenharmony_ci return *con ? 0 : -1; 3646cd6a6acSopenharmony_ci} 3656cd6a6acSopenharmony_ci 3666cd6a6acSopenharmony_cienum selabel_cmp_result selabel_cmp(struct selabel_handle *h1, 3676cd6a6acSopenharmony_ci struct selabel_handle *h2) 3686cd6a6acSopenharmony_ci{ 3696cd6a6acSopenharmony_ci if (!h1->func_cmp || h1->func_cmp != h2->func_cmp) 3706cd6a6acSopenharmony_ci return SELABEL_INCOMPARABLE; 3716cd6a6acSopenharmony_ci 3726cd6a6acSopenharmony_ci return h1->func_cmp(h1, h2); 3736cd6a6acSopenharmony_ci} 3746cd6a6acSopenharmony_ci 3756cd6a6acSopenharmony_ciint selabel_digest(struct selabel_handle *rec, 3766cd6a6acSopenharmony_ci unsigned char **digest, size_t *digest_len, 3776cd6a6acSopenharmony_ci char ***specfiles, size_t *num_specfiles) 3786cd6a6acSopenharmony_ci{ 3796cd6a6acSopenharmony_ci if (!rec->digest) { 3806cd6a6acSopenharmony_ci errno = EINVAL; 3816cd6a6acSopenharmony_ci return -1; 3826cd6a6acSopenharmony_ci } 3836cd6a6acSopenharmony_ci 3846cd6a6acSopenharmony_ci *digest = rec->digest->digest; 3856cd6a6acSopenharmony_ci *digest_len = DIGEST_SPECFILE_SIZE; 3866cd6a6acSopenharmony_ci *specfiles = rec->digest->specfile_list; 3876cd6a6acSopenharmony_ci *num_specfiles = rec->digest->specfile_cnt; 3886cd6a6acSopenharmony_ci return 0; 3896cd6a6acSopenharmony_ci} 3906cd6a6acSopenharmony_ci 3916cd6a6acSopenharmony_civoid selabel_close(struct selabel_handle *rec) 3926cd6a6acSopenharmony_ci{ 3936cd6a6acSopenharmony_ci if (rec->digest) 3946cd6a6acSopenharmony_ci selabel_digest_fini(rec->digest); 3956cd6a6acSopenharmony_ci rec->func_close(rec); 3966cd6a6acSopenharmony_ci#ifdef OHOS_FC_INIT 3976cd6a6acSopenharmony_ci free_spec_files(rec); 3986cd6a6acSopenharmony_ci#else 3996cd6a6acSopenharmony_ci free(rec->spec_file); 4006cd6a6acSopenharmony_ci#endif 4016cd6a6acSopenharmony_ci free(rec); 4026cd6a6acSopenharmony_ci} 4036cd6a6acSopenharmony_ci 4046cd6a6acSopenharmony_civoid selabel_stats(struct selabel_handle *rec) 4056cd6a6acSopenharmony_ci{ 4066cd6a6acSopenharmony_ci rec->func_stats(rec); 4076cd6a6acSopenharmony_ci} 408