16cd6a6acSopenharmony_ci/* 26cd6a6acSopenharmony_ci * Copyright 2011 Tresys Technology, LLC. All rights reserved. 36cd6a6acSopenharmony_ci * 46cd6a6acSopenharmony_ci * Redistribution and use in source and binary forms, with or without 56cd6a6acSopenharmony_ci * modification, are permitted provided that the following conditions are met: 66cd6a6acSopenharmony_ci * 76cd6a6acSopenharmony_ci * 1. Redistributions of source code must retain the above copyright notice, 86cd6a6acSopenharmony_ci * this list of conditions and the following disclaimer. 96cd6a6acSopenharmony_ci * 106cd6a6acSopenharmony_ci * 2. Redistributions in binary form must reproduce the above copyright notice, 116cd6a6acSopenharmony_ci * this list of conditions and the following disclaimer in the documentation 126cd6a6acSopenharmony_ci * and/or other materials provided with the distribution. 136cd6a6acSopenharmony_ci * 146cd6a6acSopenharmony_ci * THIS SOFTWARE IS PROVIDED BY TRESYS TECHNOLOGY, LLC ``AS IS'' AND ANY EXPRESS 156cd6a6acSopenharmony_ci * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 166cd6a6acSopenharmony_ci * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 176cd6a6acSopenharmony_ci * EVENT SHALL TRESYS TECHNOLOGY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 186cd6a6acSopenharmony_ci * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 196cd6a6acSopenharmony_ci * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 206cd6a6acSopenharmony_ci * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 216cd6a6acSopenharmony_ci * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 226cd6a6acSopenharmony_ci * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 236cd6a6acSopenharmony_ci * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 246cd6a6acSopenharmony_ci * 256cd6a6acSopenharmony_ci * The views and conclusions contained in the software and documentation are those 266cd6a6acSopenharmony_ci * of the authors and should not be interpreted as representing official policies, 276cd6a6acSopenharmony_ci * either expressed or implied, of Tresys Technology, LLC. 286cd6a6acSopenharmony_ci */ 296cd6a6acSopenharmony_ci 306cd6a6acSopenharmony_ci#include <stdlib.h> 316cd6a6acSopenharmony_ci#include <stdio.h> 326cd6a6acSopenharmony_ci#include <stdint.h> 336cd6a6acSopenharmony_ci#include <string.h> 346cd6a6acSopenharmony_ci#include <getopt.h> 356cd6a6acSopenharmony_ci#include <sys/stat.h> 366cd6a6acSopenharmony_ci 376cd6a6acSopenharmony_ci#ifdef ANDROID 386cd6a6acSopenharmony_ci#include <cil/cil.h> 396cd6a6acSopenharmony_ci#else 406cd6a6acSopenharmony_ci#include <cil/cil.h> 416cd6a6acSopenharmony_ci#endif 426cd6a6acSopenharmony_ci#include <sepol/policydb.h> 436cd6a6acSopenharmony_ci 446cd6a6acSopenharmony_cistatic __attribute__((__noreturn__)) void usage(const char *prog) 456cd6a6acSopenharmony_ci{ 466cd6a6acSopenharmony_ci printf("Usage: %s [OPTION]... FILE...\n", prog); 476cd6a6acSopenharmony_ci printf("\n"); 486cd6a6acSopenharmony_ci printf("Options:\n"); 496cd6a6acSopenharmony_ci printf(" -o, --output=<file> write binary policy to <file>\n"); 506cd6a6acSopenharmony_ci printf(" (default: policy.<version>)\n"); 516cd6a6acSopenharmony_ci printf(" -f, --filecontext=<file> write file contexts to <file>\n"); 526cd6a6acSopenharmony_ci printf(" (default: file_contexts)\n"); 536cd6a6acSopenharmony_ci printf(" -t, --target=<type> specify target architecture. may be selinux or\n"); 546cd6a6acSopenharmony_ci printf(" xen. (default: selinux)\n"); 556cd6a6acSopenharmony_ci printf(" -M, --mls true|false build an mls policy. Must be true or false.\n"); 566cd6a6acSopenharmony_ci printf(" This will override the (mls boolean) statement\n"); 576cd6a6acSopenharmony_ci printf(" if present in the policy\n"); 586cd6a6acSopenharmony_ci printf(" -c, --policyvers=<version> build a binary policy with a given <version>\n"); 596cd6a6acSopenharmony_ci printf(" (default: %i)\n", POLICYDB_VERSION_MAX); 606cd6a6acSopenharmony_ci printf(" -U, --handle-unknown=<action> how to handle unknown classes or permissions.\n"); 616cd6a6acSopenharmony_ci printf(" may be deny, allow, or reject. (default: deny)\n"); 626cd6a6acSopenharmony_ci printf(" This will override the (handleunknown action)\n"); 636cd6a6acSopenharmony_ci printf(" statement if present in the policy\n"); 646cd6a6acSopenharmony_ci printf(" -D, --disable-dontaudit do not add dontaudit rules to the binary policy\n"); 656cd6a6acSopenharmony_ci printf(" -P, --preserve-tunables treat tunables as booleans\n"); 666cd6a6acSopenharmony_ci printf(" -Q, --qualified-names Allow names containing dots (qualified names).\n"); 676cd6a6acSopenharmony_ci printf(" Blocks, blockinherits, blockabstracts, and\n"); 686cd6a6acSopenharmony_ci printf(" in-statements will not be allowed.\n"); 696cd6a6acSopenharmony_ci printf(" -m, --multiple-decls allow some statements to be re-declared\n"); 706cd6a6acSopenharmony_ci printf(" -N, --disable-neverallow do not check neverallow rules\n"); 716cd6a6acSopenharmony_ci printf(" -G, --expand-generated Expand and remove auto-generated attributes\n"); 726cd6a6acSopenharmony_ci printf(" -X, --expand-size <SIZE> Expand type attributes with fewer than <SIZE>\n"); 736cd6a6acSopenharmony_ci printf(" members.\n"); 746cd6a6acSopenharmony_ci printf(" -O, --optimize optimize final policy\n"); 756cd6a6acSopenharmony_ci printf(" -v, --verbose increment verbosity level\n"); 766cd6a6acSopenharmony_ci printf(" -h, --help display usage information\n"); 776cd6a6acSopenharmony_ci exit(1); 786cd6a6acSopenharmony_ci} 796cd6a6acSopenharmony_ci 806cd6a6acSopenharmony_ciint main(int argc, char *argv[]) 816cd6a6acSopenharmony_ci{ 826cd6a6acSopenharmony_ci int rc = SEPOL_ERR; 836cd6a6acSopenharmony_ci sepol_policydb_t *pdb = NULL; 846cd6a6acSopenharmony_ci struct sepol_policy_file *pf = NULL; 856cd6a6acSopenharmony_ci FILE *binary = NULL; 866cd6a6acSopenharmony_ci FILE *file_contexts; 876cd6a6acSopenharmony_ci FILE *file = NULL; 886cd6a6acSopenharmony_ci char *buffer = NULL; 896cd6a6acSopenharmony_ci struct stat filedata; 906cd6a6acSopenharmony_ci uint32_t file_size; 916cd6a6acSopenharmony_ci char *output = NULL; 926cd6a6acSopenharmony_ci char *filecontexts = NULL; 936cd6a6acSopenharmony_ci struct cil_db *db = NULL; 946cd6a6acSopenharmony_ci int target = SEPOL_TARGET_SELINUX; 956cd6a6acSopenharmony_ci int mls = -1; 966cd6a6acSopenharmony_ci int disable_dontaudit = 0; 976cd6a6acSopenharmony_ci int multiple_decls = 0; 986cd6a6acSopenharmony_ci int disable_neverallow = 0; 996cd6a6acSopenharmony_ci int preserve_tunables = 0; 1006cd6a6acSopenharmony_ci int qualified_names = 0; 1016cd6a6acSopenharmony_ci int handle_unknown = -1; 1026cd6a6acSopenharmony_ci int policyvers = POLICYDB_VERSION_MAX; 1036cd6a6acSopenharmony_ci int attrs_expand_generated = 0; 1046cd6a6acSopenharmony_ci int attrs_expand_size = -1; 1056cd6a6acSopenharmony_ci int optimize = 0; 1066cd6a6acSopenharmony_ci int opt_char; 1076cd6a6acSopenharmony_ci int opt_index = 0; 1086cd6a6acSopenharmony_ci char *fc_buf = NULL; 1096cd6a6acSopenharmony_ci size_t fc_size; 1106cd6a6acSopenharmony_ci enum cil_log_level log_level = CIL_ERR; 1116cd6a6acSopenharmony_ci static struct option long_opts[] = { 1126cd6a6acSopenharmony_ci {"help", no_argument, 0, 'h'}, 1136cd6a6acSopenharmony_ci {"verbose", no_argument, 0, 'v'}, 1146cd6a6acSopenharmony_ci {"target", required_argument, 0, 't'}, 1156cd6a6acSopenharmony_ci {"mls", required_argument, 0, 'M'}, 1166cd6a6acSopenharmony_ci {"policyversion", required_argument, 0, 'c'}, 1176cd6a6acSopenharmony_ci {"handle-unknown", required_argument, 0, 'U'}, 1186cd6a6acSopenharmony_ci {"disable-dontaudit", no_argument, 0, 'D'}, 1196cd6a6acSopenharmony_ci {"multiple-decls", no_argument, 0, 'm'}, 1206cd6a6acSopenharmony_ci {"disable-neverallow", no_argument, 0, 'N'}, 1216cd6a6acSopenharmony_ci {"preserve-tunables", no_argument, 0, 'P'}, 1226cd6a6acSopenharmony_ci {"qualified-names", no_argument, 0, 'Q'}, 1236cd6a6acSopenharmony_ci {"output", required_argument, 0, 'o'}, 1246cd6a6acSopenharmony_ci {"filecontexts", required_argument, 0, 'f'}, 1256cd6a6acSopenharmony_ci {"expand-generated", no_argument, 0, 'G'}, 1266cd6a6acSopenharmony_ci {"expand-size", required_argument, 0, 'X'}, 1276cd6a6acSopenharmony_ci {"optimize", no_argument, 0, 'O'}, 1286cd6a6acSopenharmony_ci {0, 0, 0, 0} 1296cd6a6acSopenharmony_ci }; 1306cd6a6acSopenharmony_ci int i; 1316cd6a6acSopenharmony_ci 1326cd6a6acSopenharmony_ci while (1) { 1336cd6a6acSopenharmony_ci opt_char = getopt_long(argc, argv, "o:f:U:hvt:M:PQDmNOc:GX:n", long_opts, &opt_index); 1346cd6a6acSopenharmony_ci if (opt_char == -1) { 1356cd6a6acSopenharmony_ci break; 1366cd6a6acSopenharmony_ci } 1376cd6a6acSopenharmony_ci switch (opt_char) { 1386cd6a6acSopenharmony_ci case 'v': 1396cd6a6acSopenharmony_ci log_level++; 1406cd6a6acSopenharmony_ci break; 1416cd6a6acSopenharmony_ci case 't': 1426cd6a6acSopenharmony_ci if (!strcmp(optarg, "selinux")) { 1436cd6a6acSopenharmony_ci target = SEPOL_TARGET_SELINUX; 1446cd6a6acSopenharmony_ci } else if (!strcmp(optarg, "xen")) { 1456cd6a6acSopenharmony_ci target = SEPOL_TARGET_XEN; 1466cd6a6acSopenharmony_ci } else { 1476cd6a6acSopenharmony_ci fprintf(stderr, "Unknown target: %s\n", optarg); 1486cd6a6acSopenharmony_ci usage(argv[0]); 1496cd6a6acSopenharmony_ci } 1506cd6a6acSopenharmony_ci break; 1516cd6a6acSopenharmony_ci case 'M': 1526cd6a6acSopenharmony_ci if (!strcasecmp(optarg, "true") || !strcasecmp(optarg, "1")) { 1536cd6a6acSopenharmony_ci mls = 1; 1546cd6a6acSopenharmony_ci } else if (!strcasecmp(optarg, "false") || !strcasecmp(optarg, "0")) { 1556cd6a6acSopenharmony_ci mls = 0; 1566cd6a6acSopenharmony_ci } else { 1576cd6a6acSopenharmony_ci usage(argv[0]); 1586cd6a6acSopenharmony_ci } 1596cd6a6acSopenharmony_ci break; 1606cd6a6acSopenharmony_ci case 'c': { 1616cd6a6acSopenharmony_ci char *endptr = NULL; 1626cd6a6acSopenharmony_ci errno = 0; 1636cd6a6acSopenharmony_ci policyvers = strtol(optarg, &endptr, 10); 1646cd6a6acSopenharmony_ci if (errno != 0 || endptr == optarg || *endptr != '\0') { 1656cd6a6acSopenharmony_ci fprintf(stderr, "Bad policy version: %s\n", optarg); 1666cd6a6acSopenharmony_ci usage(argv[0]); 1676cd6a6acSopenharmony_ci } 1686cd6a6acSopenharmony_ci if (policyvers > POLICYDB_VERSION_MAX || policyvers < POLICYDB_VERSION_MIN) { 1696cd6a6acSopenharmony_ci fprintf(stderr, "Policy version must be between %d and %d\n", 1706cd6a6acSopenharmony_ci POLICYDB_VERSION_MIN, POLICYDB_VERSION_MAX); 1716cd6a6acSopenharmony_ci usage(argv[0]); 1726cd6a6acSopenharmony_ci } 1736cd6a6acSopenharmony_ci break; 1746cd6a6acSopenharmony_ci } 1756cd6a6acSopenharmony_ci case 'U': 1766cd6a6acSopenharmony_ci if (!strcasecmp(optarg, "deny")) { 1776cd6a6acSopenharmony_ci handle_unknown = SEPOL_DENY_UNKNOWN; 1786cd6a6acSopenharmony_ci } else if (!strcasecmp(optarg, "allow")) { 1796cd6a6acSopenharmony_ci handle_unknown = SEPOL_ALLOW_UNKNOWN; 1806cd6a6acSopenharmony_ci } else if (!strcasecmp(optarg, "reject")) { 1816cd6a6acSopenharmony_ci handle_unknown = SEPOL_REJECT_UNKNOWN; 1826cd6a6acSopenharmony_ci } else { 1836cd6a6acSopenharmony_ci usage(argv[0]); 1846cd6a6acSopenharmony_ci } 1856cd6a6acSopenharmony_ci break; 1866cd6a6acSopenharmony_ci case 'D': 1876cd6a6acSopenharmony_ci disable_dontaudit = 1; 1886cd6a6acSopenharmony_ci break; 1896cd6a6acSopenharmony_ci case 'm': 1906cd6a6acSopenharmony_ci multiple_decls = 1; 1916cd6a6acSopenharmony_ci break; 1926cd6a6acSopenharmony_ci case 'N': 1936cd6a6acSopenharmony_ci disable_neverallow = 1; 1946cd6a6acSopenharmony_ci break; 1956cd6a6acSopenharmony_ci case 'P': 1966cd6a6acSopenharmony_ci preserve_tunables = 1; 1976cd6a6acSopenharmony_ci break; 1986cd6a6acSopenharmony_ci case 'Q': 1996cd6a6acSopenharmony_ci qualified_names = 1; 2006cd6a6acSopenharmony_ci break; 2016cd6a6acSopenharmony_ci case 'o': 2026cd6a6acSopenharmony_ci free(output); 2036cd6a6acSopenharmony_ci output = strdup(optarg); 2046cd6a6acSopenharmony_ci break; 2056cd6a6acSopenharmony_ci case 'f': 2066cd6a6acSopenharmony_ci free(filecontexts); 2076cd6a6acSopenharmony_ci filecontexts = strdup(optarg); 2086cd6a6acSopenharmony_ci break; 2096cd6a6acSopenharmony_ci case 'G': 2106cd6a6acSopenharmony_ci attrs_expand_generated = 1; 2116cd6a6acSopenharmony_ci break; 2126cd6a6acSopenharmony_ci case 'X': { 2136cd6a6acSopenharmony_ci char *endptr = NULL; 2146cd6a6acSopenharmony_ci errno = 0; 2156cd6a6acSopenharmony_ci attrs_expand_size = strtol(optarg, &endptr, 10); 2166cd6a6acSopenharmony_ci if (errno != 0 || endptr == optarg || *endptr != '\0') { 2176cd6a6acSopenharmony_ci fprintf(stderr, "Bad attribute expand size: %s\n", optarg); 2186cd6a6acSopenharmony_ci usage(argv[0]); 2196cd6a6acSopenharmony_ci } 2206cd6a6acSopenharmony_ci 2216cd6a6acSopenharmony_ci if (attrs_expand_size < 0) { 2226cd6a6acSopenharmony_ci fprintf(stderr, "Attribute expand size must be > 0\n"); 2236cd6a6acSopenharmony_ci usage(argv[0]); 2246cd6a6acSopenharmony_ci } 2256cd6a6acSopenharmony_ci break; 2266cd6a6acSopenharmony_ci } 2276cd6a6acSopenharmony_ci case 'O': 2286cd6a6acSopenharmony_ci optimize = 1; 2296cd6a6acSopenharmony_ci break; 2306cd6a6acSopenharmony_ci case 'h': 2316cd6a6acSopenharmony_ci usage(argv[0]); 2326cd6a6acSopenharmony_ci case '?': 2336cd6a6acSopenharmony_ci break; 2346cd6a6acSopenharmony_ci default: 2356cd6a6acSopenharmony_ci fprintf(stderr, "Unsupported option: %s\n", optarg); 2366cd6a6acSopenharmony_ci usage(argv[0]); 2376cd6a6acSopenharmony_ci } 2386cd6a6acSopenharmony_ci } 2396cd6a6acSopenharmony_ci if (optind >= argc) { 2406cd6a6acSopenharmony_ci fprintf(stderr, "No cil files specified\n"); 2416cd6a6acSopenharmony_ci usage(argv[0]); 2426cd6a6acSopenharmony_ci } 2436cd6a6acSopenharmony_ci 2446cd6a6acSopenharmony_ci cil_set_log_level(log_level); 2456cd6a6acSopenharmony_ci 2466cd6a6acSopenharmony_ci cil_db_init(&db); 2476cd6a6acSopenharmony_ci cil_set_disable_dontaudit(db, disable_dontaudit); 2486cd6a6acSopenharmony_ci cil_set_multiple_decls(db, multiple_decls); 2496cd6a6acSopenharmony_ci cil_set_disable_neverallow(db, disable_neverallow); 2506cd6a6acSopenharmony_ci cil_set_preserve_tunables(db, preserve_tunables); 2516cd6a6acSopenharmony_ci cil_set_qualified_names(db, qualified_names); 2526cd6a6acSopenharmony_ci if (handle_unknown != -1) { 2536cd6a6acSopenharmony_ci rc = cil_set_handle_unknown(db, handle_unknown); 2546cd6a6acSopenharmony_ci if (rc != SEPOL_OK) { 2556cd6a6acSopenharmony_ci goto exit; 2566cd6a6acSopenharmony_ci } 2576cd6a6acSopenharmony_ci } 2586cd6a6acSopenharmony_ci 2596cd6a6acSopenharmony_ci cil_set_mls(db, mls); 2606cd6a6acSopenharmony_ci cil_set_target_platform(db, target); 2616cd6a6acSopenharmony_ci cil_set_policy_version(db, policyvers); 2626cd6a6acSopenharmony_ci cil_set_attrs_expand_generated(db, attrs_expand_generated); 2636cd6a6acSopenharmony_ci if (attrs_expand_size >= 0) { 2646cd6a6acSopenharmony_ci cil_set_attrs_expand_size(db, (unsigned)attrs_expand_size); 2656cd6a6acSopenharmony_ci } 2666cd6a6acSopenharmony_ci 2676cd6a6acSopenharmony_ci for (i = optind; i < argc; i++) { 2686cd6a6acSopenharmony_ci file = fopen(argv[i], "r"); 2696cd6a6acSopenharmony_ci if (!file) { 2706cd6a6acSopenharmony_ci fprintf(stderr, "Could not open file: %s\n", argv[i]); 2716cd6a6acSopenharmony_ci rc = SEPOL_ERR; 2726cd6a6acSopenharmony_ci goto exit; 2736cd6a6acSopenharmony_ci } 2746cd6a6acSopenharmony_ci rc = stat(argv[i], &filedata); 2756cd6a6acSopenharmony_ci if (rc == -1) { 2766cd6a6acSopenharmony_ci fprintf(stderr, "Could not stat file: %s\n", argv[i]); 2776cd6a6acSopenharmony_ci rc = SEPOL_ERR; 2786cd6a6acSopenharmony_ci goto exit; 2796cd6a6acSopenharmony_ci } 2806cd6a6acSopenharmony_ci file_size = filedata.st_size; 2816cd6a6acSopenharmony_ci 2826cd6a6acSopenharmony_ci if (!file_size) { 2836cd6a6acSopenharmony_ci fclose(file); 2846cd6a6acSopenharmony_ci file = NULL; 2856cd6a6acSopenharmony_ci continue; 2866cd6a6acSopenharmony_ci } 2876cd6a6acSopenharmony_ci 2886cd6a6acSopenharmony_ci buffer = malloc(file_size); 2896cd6a6acSopenharmony_ci rc = fread(buffer, file_size, 1, file); 2906cd6a6acSopenharmony_ci if (rc != 1) { 2916cd6a6acSopenharmony_ci fprintf(stderr, "Failure reading file: %s\n", argv[i]); 2926cd6a6acSopenharmony_ci rc = SEPOL_ERR; 2936cd6a6acSopenharmony_ci goto exit; 2946cd6a6acSopenharmony_ci } 2956cd6a6acSopenharmony_ci fclose(file); 2966cd6a6acSopenharmony_ci file = NULL; 2976cd6a6acSopenharmony_ci 2986cd6a6acSopenharmony_ci rc = cil_add_file(db, argv[i], buffer, file_size); 2996cd6a6acSopenharmony_ci if (rc != SEPOL_OK) { 3006cd6a6acSopenharmony_ci fprintf(stderr, "Failure adding %s\n", argv[i]); 3016cd6a6acSopenharmony_ci goto exit; 3026cd6a6acSopenharmony_ci } 3036cd6a6acSopenharmony_ci 3046cd6a6acSopenharmony_ci free(buffer); 3056cd6a6acSopenharmony_ci buffer = NULL; 3066cd6a6acSopenharmony_ci } 3076cd6a6acSopenharmony_ci 3086cd6a6acSopenharmony_ci rc = cil_compile(db); 3096cd6a6acSopenharmony_ci if (rc != SEPOL_OK) { 3106cd6a6acSopenharmony_ci fprintf(stderr, "Failed to compile cildb: %d\n", rc); 3116cd6a6acSopenharmony_ci goto exit; 3126cd6a6acSopenharmony_ci } 3136cd6a6acSopenharmony_ci 3146cd6a6acSopenharmony_ci rc = cil_build_policydb(db, &pdb); 3156cd6a6acSopenharmony_ci if (rc != SEPOL_OK) { 3166cd6a6acSopenharmony_ci fprintf(stderr, "Failed to build policydb\n"); 3176cd6a6acSopenharmony_ci goto exit; 3186cd6a6acSopenharmony_ci } 3196cd6a6acSopenharmony_ci 3206cd6a6acSopenharmony_ci if (optimize) { 3216cd6a6acSopenharmony_ci rc = sepol_policydb_optimize(pdb); 3226cd6a6acSopenharmony_ci if (rc != SEPOL_OK) { 3236cd6a6acSopenharmony_ci fprintf(stderr, "Failed to optimize policydb\n"); 3246cd6a6acSopenharmony_ci goto exit; 3256cd6a6acSopenharmony_ci } 3266cd6a6acSopenharmony_ci } 3276cd6a6acSopenharmony_ci 3286cd6a6acSopenharmony_ci if (output == NULL) { 3296cd6a6acSopenharmony_ci int size = snprintf(NULL, 0, "policy.%d", policyvers); 3306cd6a6acSopenharmony_ci output = malloc((size + 1) * sizeof(char)); 3316cd6a6acSopenharmony_ci if (output == NULL) { 3326cd6a6acSopenharmony_ci fprintf(stderr, "Failed to create output filename\n"); 3336cd6a6acSopenharmony_ci rc = SEPOL_ERR; 3346cd6a6acSopenharmony_ci goto exit; 3356cd6a6acSopenharmony_ci } 3366cd6a6acSopenharmony_ci if (snprintf(output, size + 1, "policy.%d", policyvers) != size) { 3376cd6a6acSopenharmony_ci fprintf(stderr, "Failed to create output filename\n"); 3386cd6a6acSopenharmony_ci rc = SEPOL_ERR; 3396cd6a6acSopenharmony_ci goto exit; 3406cd6a6acSopenharmony_ci } 3416cd6a6acSopenharmony_ci } 3426cd6a6acSopenharmony_ci 3436cd6a6acSopenharmony_ci binary = fopen(output, "w"); 3446cd6a6acSopenharmony_ci if (binary == NULL) { 3456cd6a6acSopenharmony_ci fprintf(stderr, "Failure opening binary file for writing\n"); 3466cd6a6acSopenharmony_ci rc = SEPOL_ERR; 3476cd6a6acSopenharmony_ci goto exit; 3486cd6a6acSopenharmony_ci } 3496cd6a6acSopenharmony_ci 3506cd6a6acSopenharmony_ci rc = sepol_policy_file_create(&pf); 3516cd6a6acSopenharmony_ci if (rc != 0) { 3526cd6a6acSopenharmony_ci fprintf(stderr, "Failed to create policy file: %d\n", rc); 3536cd6a6acSopenharmony_ci goto exit; 3546cd6a6acSopenharmony_ci } 3556cd6a6acSopenharmony_ci 3566cd6a6acSopenharmony_ci sepol_policy_file_set_fp(pf, binary); 3576cd6a6acSopenharmony_ci 3586cd6a6acSopenharmony_ci rc = sepol_policydb_write(pdb, pf); 3596cd6a6acSopenharmony_ci if (rc != 0) { 3606cd6a6acSopenharmony_ci fprintf(stderr, "Failed to write binary policy: %d\n", rc); 3616cd6a6acSopenharmony_ci goto exit; 3626cd6a6acSopenharmony_ci } 3636cd6a6acSopenharmony_ci 3646cd6a6acSopenharmony_ci fclose(binary); 3656cd6a6acSopenharmony_ci binary = NULL; 3666cd6a6acSopenharmony_ci 3676cd6a6acSopenharmony_ci rc = cil_filecons_to_string(db, &fc_buf, &fc_size); 3686cd6a6acSopenharmony_ci if (rc != SEPOL_OK) { 3696cd6a6acSopenharmony_ci fprintf(stderr, "Failed to get file context data\n"); 3706cd6a6acSopenharmony_ci goto exit; 3716cd6a6acSopenharmony_ci } 3726cd6a6acSopenharmony_ci 3736cd6a6acSopenharmony_ci if (filecontexts == NULL) { 3746cd6a6acSopenharmony_ci file_contexts = fopen("file_contexts", "w+"); 3756cd6a6acSopenharmony_ci } else { 3766cd6a6acSopenharmony_ci file_contexts = fopen(filecontexts, "w+"); 3776cd6a6acSopenharmony_ci } 3786cd6a6acSopenharmony_ci 3796cd6a6acSopenharmony_ci if (file_contexts == NULL) { 3806cd6a6acSopenharmony_ci fprintf(stderr, "Failed to open file_contexts file\n"); 3816cd6a6acSopenharmony_ci rc = SEPOL_ERR; 3826cd6a6acSopenharmony_ci goto exit; 3836cd6a6acSopenharmony_ci } 3846cd6a6acSopenharmony_ci 3856cd6a6acSopenharmony_ci if (fwrite(fc_buf, sizeof(char), fc_size, file_contexts) != fc_size) { 3866cd6a6acSopenharmony_ci fprintf(stderr, "Failed to write file_contexts file\n"); 3876cd6a6acSopenharmony_ci rc = SEPOL_ERR; 3886cd6a6acSopenharmony_ci goto exit; 3896cd6a6acSopenharmony_ci } 3906cd6a6acSopenharmony_ci 3916cd6a6acSopenharmony_ci fclose(file_contexts); 3926cd6a6acSopenharmony_ci file_contexts = NULL; 3936cd6a6acSopenharmony_ci 3946cd6a6acSopenharmony_ci rc = SEPOL_OK; 3956cd6a6acSopenharmony_ci 3966cd6a6acSopenharmony_ciexit: 3976cd6a6acSopenharmony_ci if (binary != NULL) { 3986cd6a6acSopenharmony_ci fclose(binary); 3996cd6a6acSopenharmony_ci } 4006cd6a6acSopenharmony_ci if (file != NULL) { 4016cd6a6acSopenharmony_ci fclose(file); 4026cd6a6acSopenharmony_ci } 4036cd6a6acSopenharmony_ci free(buffer); 4046cd6a6acSopenharmony_ci free(output); 4056cd6a6acSopenharmony_ci free(filecontexts); 4066cd6a6acSopenharmony_ci cil_db_destroy(&db); 4076cd6a6acSopenharmony_ci sepol_policydb_free(pdb); 4086cd6a6acSopenharmony_ci sepol_policy_file_free(pf); 4096cd6a6acSopenharmony_ci free(fc_buf); 4106cd6a6acSopenharmony_ci return rc; 4116cd6a6acSopenharmony_ci} 412