Example #1
0
/* Writes a module (or a base) to the file given by a fully-qualified
 * 'filename'.	Returns 0 on success, -1 if file could not be written.
 */
static int semanage_write_module(semanage_handle_t *sh,
				 const char *filename, sepol_module_package_t *package)
{
	struct sepol_policy_file *pf;
	FILE *outfile;
	int retval;
	if (sepol_policy_file_create(&pf)) {
		ERR(sh, "Out of memory!");
		return -1;
	}
	if ((outfile = fopen(filename, "wb")) == NULL) {
		sepol_policy_file_free(pf);
		ERR(sh, "Could not open %s for writing.", filename);
		return -1;
	}
	sepol_policy_file_set_fp(pf, outfile);
	sepol_policy_file_set_handle(pf, sh->sepolh);
	retval = sepol_module_package_write(package, pf);
	fclose(outfile);
	sepol_policy_file_free(pf);
	if (retval == -1) {
		ERR(sh, "Error while writing module to %s.", filename);
		return -1;
	}
	return 0;
}
Example #2
0
/* Takes a module stored in 'module_data' and parses its headers.
 * Sets reference variables 'module_name' to module's name and
 * 'version' to module's version. The caller is responsible for
 * free()ing 'module_name' and 'version'; they will be
 * set to NULL upon entering this function.  Returns 0 on success, -1
 * if out of memory, or -2 if data did not represent a module.
 */
static int parse_module_headers(semanage_handle_t * sh, char *module_data,
				size_t data_len, char **module_name, char **version)
{
	struct sepol_policy_file *pf;
	int file_type;
	*version = NULL;

	if (sepol_policy_file_create(&pf)) {
		ERR(sh, "Out of memory!");
		return -1;
	}
	sepol_policy_file_set_mem(pf, module_data, data_len);
	sepol_policy_file_set_handle(pf, sh->sepolh);
	if (module_data == NULL ||
	    data_len == 0 ||
	    sepol_module_package_info(pf, &file_type, module_name, version) == -1) {
		sepol_policy_file_free(pf);
		ERR(sh, "Could not parse module data.");
		return -2;
	}
	sepol_policy_file_free(pf);
	if (file_type != SEPOL_POLICY_MOD) {
		ERR(sh, "Data did not represent a pp module. Please upgrade to the latest version of libsemanage to support hll modules.");
		return -2;
	}

	return 0;
}
Example #3
0
/* Takes a base module stored in 'module_data' and parse its headers.
 * Returns 0 on success, -1 if out of memory, or -2 if data did not
 * represent a module.
 */
static int parse_base_headers(semanage_handle_t *sh,
			      char *module_data, size_t data_len) {
	struct sepol_policy_file *pf;
	char *module_name = NULL, *version = NULL;
	int file_type;

	if (sepol_policy_file_create(&pf)) {
		ERR(sh, "Out of memory!");
		return -1;
	}
	sepol_policy_file_set_mem(pf, module_data, data_len);
	sepol_policy_file_set_handle(pf, sh->sepolh);
	if (module_data == NULL ||
	    data_len == 0 ||
	    sepol_module_package_info(pf, &file_type,
				      &module_name, &version) == -1) {
		sepol_policy_file_free(pf);
		ERR(sh, "Could not parse base module data.");
		return -2;
	}
	sepol_policy_file_free(pf);
	free(module_name);
	free(version);
	if (file_type != SEPOL_POLICY_BASE) {
		if (file_type == SEPOL_POLICY_MOD)
			ERR(sh, "Received a non-base module, expected a base module.");
		else
			ERR(sh, "Data did not represent a module.");
		return -2;
	}
	return 0;
}
static void cleanup(void) {

    if (global_state.sepolicy.file) {
        fclose(global_state.sepolicy.file);
    }

    if (global_state.sepolicy.sdb) {
        sepol_policydb_free(global_state.sepolicy.sdb);
    }

    if (global_state.sepolicy.pf) {
        sepol_policy_file_free(global_state.sepolicy.pf);
    }

    if (global_state.sepolicy.handle) {
        sepol_handle_destroy(global_state.sepolicy.handle);
    }

    ebitmap_destroy(&global_state.assert.set);

    int i;
    for (i = 0; i < SEHANDLE_CNT; i++) {
        struct selabel_handle *sehnd = global_state.sepolicy.sehnd[i];
        if (sehnd) {
            selabel_close(sehnd);
        }
    }
}
Example #5
0
static sepol_module_package_t *load_module(char *filename)
{
	int ret;
	FILE *fp = NULL;
	struct sepol_policy_file *pf = NULL;
	sepol_module_package_t *p = NULL;

	if (sepol_module_package_create(&p)) {
		fprintf(stderr, "%s:  Out of memory\n", progname);
		goto bad;
	}
	if (sepol_policy_file_create(&pf)) {
		fprintf(stderr, "%s:  Out of memory\n", progname);
		goto bad;
	}
	fp = fopen(filename, "r");
	if (!fp) {
		fprintf(stderr, "%s:  Could not open package %s:  %s", progname, filename, strerror(errno));
		goto bad;
	}
	sepol_policy_file_set_fp(pf, fp);
	
	printf("%s:  loading package from file %s\n", progname, filename);
	
	ret = sepol_module_package_read(p, pf, 0);
	if (ret) {
		fprintf(stderr, "%s:  Error while reading package from %s\n", progname, filename);
		goto bad;
	}
	fclose(fp);
	sepol_policy_file_free(pf);
	return p;
bad:
	sepol_module_package_free(p);
	sepol_policy_file_free(pf);
	if (fp)
		fclose(fp);
	return NULL;
}
Example #6
0
/* Takes a module stored in 'module_data' and parses its headers.
 * Sets reference variables 'filename' to module's fully qualified
 * path name into the sandbox, 'module_name' to module's name, and
 * 'version' to module's version.  The caller is responsible for
 * free()ing 'filename', 'module_name', and 'version'; they will be
 * set to NULL upon entering this function.  Returns 0 on success, -1
 * if out of memory, or -2 if data did not represent a module.
 */
static int parse_module_headers(semanage_handle_t *sh, char *module_data,
				size_t data_len, char **module_name,
				char **version, char **filename) {
	struct sepol_policy_file *pf;
	int file_type;
	const char *module_path;
	*module_name = *version = *filename = NULL;
	
	if (sepol_policy_file_create(&pf)) {
		ERR(sh, "Out of memory!");
		return -1;
	}
	sepol_policy_file_set_mem(pf, module_data, data_len);
	sepol_policy_file_set_handle(pf, sh->sepolh);
	if (module_data == NULL ||
	    data_len == 0 ||
	    sepol_module_package_info(pf, &file_type, module_name,
				      version) == -1) {
		sepol_policy_file_free(pf);
		ERR(sh, "Could not parse module data.");
		return -2;
	}
	sepol_policy_file_free(pf);
	if (file_type != SEPOL_POLICY_MOD) {
		if (file_type == SEPOL_POLICY_BASE)
			ERR(sh, "Received a base module, expected a non-base module.");
		else
			ERR(sh, "Data did not represent a module.");
		return -2;
	}
	if ((module_path = semanage_path(SEMANAGE_TMP, SEMANAGE_MODULES)) == NULL) {
		return -1;
	}
	if (asprintf(filename, "%s/%s.pp", module_path, *module_name) == -1) {
		ERR(sh, "Out of memory!");
		return -1;
	}
	return 0;
}
int main(int argc, char **argv)
{
	struct sepol_module_package *pkg;
	struct sepol_policy_file *mod, *out;
	char *module = NULL, *file_contexts = NULL, *seusers = NULL, *user_extra = NULL;
	char *fcdata = NULL, *outfile = NULL, *seusersdata = NULL, *user_extradata = NULL;
	size_t fclen = 0, seuserslen = 0, user_extralen = 0;
	int i;

        static struct option opts [] = {
                {"module", required_argument, NULL, 'm'},
                {"fc", required_argument, NULL, 'f'},
                {"seuser", required_argument, NULL, 's'},
                {"user_extra", required_argument, NULL, 'u'},
		{"outfile", required_argument, NULL, 'o'},
                {"help", 0, NULL, 'h'},
		{NULL, 0, NULL, 0}
	};

        while ((i = getopt_long(argc, argv, "m:f:s:u:o:h", opts, NULL)) != -1) {
                switch (i) {
		case 'h': usage(argv[0]); exit(0);
		case 'm':  
			if (module) {
				fprintf(stderr, "May not specify more than one module\n");
				exit(1);
			}
			module = strdup(optarg);
			if (!module)
				exit(1);
			break;
		case 'f':
			if (file_contexts) {
				fprintf(stderr, "May not specify more than one file context file\n");
				exit(1);
			}
			file_contexts = strdup(optarg);
			if (!file_contexts)
				exit(1);
			break;
		case 'o':
			if (outfile) {
				fprintf(stderr, "May not specify more than one output file\n");
				exit(1);
			}
			outfile = strdup(optarg);
			if (!outfile) 
				exit(1);
			break;
		case 's':
			if (seusers) {
				fprintf(stderr, "May not specify more than one seuser file\n");
				exit(1);
			}
			seusers = strdup(optarg);
			if (!seusers)
				exit(1);
			break;
		case 'u':
			if (user_extra) {
				fprintf(stderr, "May not specify more than one user_extra file\n");
				exit(1);
			}
			user_extra = strdup(optarg);
			if (!user_extra)
				exit(1);
		}
	}

	progname = argv[0];

	if (!module || !outfile) {
		usage(argv[0]);
		exit(0);
	}
	
        if (file_contexts) {
		if (file_to_data(file_contexts, &fcdata, &fclen))
			exit(1);
        }

        if (seusers) {
		if (file_to_data(seusers, &seusersdata, &seuserslen))
			exit(1);
        }

        if (user_extra) {
		if (file_to_data(user_extra, &user_extradata, &user_extralen))
			exit(1);
        }

	if (file_to_policy_file(module, &mod, "r"))
		exit(1);
	
	if (sepol_module_package_create(&pkg)) {
                fprintf(stderr, "%s:  Out of memory\n", argv[0]);
                exit(1);		
	}

	if (sepol_policydb_read(sepol_module_package_get_policy(pkg), mod)) {
                fprintf(stderr, "%s:  Error while reading policy module from %s\n",
			argv[0], module);
                exit(1);		
	}

	if (fclen)
		sepol_module_package_set_file_contexts(pkg, fcdata, fclen);

	if (seuserslen)
		sepol_module_package_set_seusers(pkg, seusersdata, seuserslen);

	if (user_extra)
		sepol_module_package_set_user_extra(pkg, user_extradata, user_extralen);
	
	if (file_to_policy_file(outfile, &out, "w"))
		exit(1);
		
        if (sepol_module_package_write(pkg, out)) {
                fprintf(stderr, "%s:  Error while writing module package to %s\n", argv[0], argv[1]);
                exit(1);
        }

	if (fclen)
		munmap(fcdata, fclen);
	sepol_policy_file_free(mod);
	sepol_policy_file_free(out);
	sepol_module_package_free(pkg);
	free(file_contexts);
	free(outfile);
	free(module);
	exit(0);
}
Example #8
0
int main(int argc, char **argv)
{
	char *basename, *outname;
	int ch, ret, show_version = 0, verbose = 0;
	struct sepol_policy_file *pf;
	sepol_module_package_t *base;
	sepol_policydb_t *out, *p;
	FILE *fp, *outfile;
	int check_assertions = 1;
	sepol_handle_t *handle;

	while ((ch = getopt(argc, argv, "c:Vva")) != EOF) {
		switch (ch) {
		case 'V':
			show_version = 1;
			break;
		case 'v':
			verbose = 1;
			break;
		case 'c':{
				long int n = strtol(optarg, NULL, 10);
				if (errno) {
					fprintf(stderr,
						"%s:  Invalid policyvers specified: %s\n",
						argv[0], optarg);
					usage(argv[0]);
					exit(1);
				}
				if (n < sepol_policy_kern_vers_min()
				    || n > sepol_policy_kern_vers_max()) {
					fprintf(stderr,
						"%s:  policyvers value %ld not in range %d-%d\n",
						argv[0], n,
						sepol_policy_kern_vers_min(),
						sepol_policy_kern_vers_max());
					usage(argv[0]);
					exit(1);
				}
				policyvers = n;
				break;
			}
		case 'a':{
				check_assertions = 0;
				break;
			}
		default:
			usage(argv[0]);
		}
	}

	if (verbose) {
		if (policyvers)
			printf("Building version %d policy\n", policyvers);
	}

	if (show_version) {
		printf("%s\n", EXPANDPOLICY_VERSION);
		exit(0);
	}

	/* check args */
	if (argc < 3 || !(optind != (argc - 1))) {
		fprintf(stderr,
			"%s:  You must provide the base module package and output filename\n",
			argv[0]);
		usage(argv[0]);
	}

	basename = argv[optind++];
	outname = argv[optind];

	handle = sepol_handle_create();
	if (!handle)
		exit(1);

	if (sepol_policy_file_create(&pf)) {
		fprintf(stderr, "%s:  Out of memory\n", argv[0]);
		exit(1);
	}

	/* read the base module */
	if (sepol_module_package_create(&base)) {
		fprintf(stderr, "%s:  Out of memory\n", argv[0]);
		exit(1);
	}
	fp = fopen(basename, "r");
	if (!fp) {
		fprintf(stderr, "%s:  Can't open '%s':  %s\n",
			argv[0], basename, strerror(errno));
		exit(1);
	}
	sepol_policy_file_set_fp(pf, fp);
	ret = sepol_module_package_read(base, pf, 0);
	if (ret) {
		fprintf(stderr, "%s:  Error in reading package from %s\n",
			argv[0], basename);
		exit(1);
	}
	fclose(fp);

	/* linking the base takes care of enabling optional avrules */
	p = sepol_module_package_get_policy(base);
	if (sepol_link_modules(handle, p, NULL, 0, 0)) {
		fprintf(stderr, "%s:  Error while enabling avrules\n", argv[0]);
		exit(1);
	}

	/* create the output policy */

	if (sepol_policydb_create(&out)) {
		fprintf(stderr, "%s:  Out of memory\n", argv[0]);
		exit(1);
	}

	sepol_set_expand_consume_base(handle, 1);

	if (sepol_expand_module(handle, p, out, verbose, check_assertions)) {
		fprintf(stderr, "%s:  Error while expanding policy\n", argv[0]);
		exit(1);
	}

	if (policyvers) {
		if (sepol_policydb_set_vers(out, policyvers)) {
			fprintf(stderr, "%s:  Invalid version %d\n", argv[0],
				policyvers);
			exit(1);
		}
	}

	sepol_module_package_free(base);

	outfile = fopen(outname, "w");
	if (!outfile) {
		perror(outname);
		exit(1);
	}

	sepol_policy_file_set_fp(pf, outfile);
	ret = sepol_policydb_write(out, pf);
	if (ret) {
		fprintf(stderr,
			"%s:  Error while writing expanded policy to %s\n",
			argv[0], outname);
		exit(1);
	}
	fclose(outfile);
	sepol_handle_destroy(handle);
	sepol_policydb_free(out);
	sepol_policy_file_free(pf);

	return 0;
}
Example #9
0
int main(int argc, char **argv)
{
	int ch, i, show_version = 0, verbose = 0, num_mods;
	char *basename, *outname = NULL;
	sepol_module_package_t *base, **mods;
	FILE *outfile;
	struct sepol_policy_file *pf;

	progname = argv[0];
	
	while ((ch = getopt(argc, argv, "o:V")) != EOF) {
                switch (ch) {
                case 'V':
                        show_version = 1;
                        break;
                case 'v':
                	verbose = 1;
                	break;
		case 'o':
			outname = optarg;
			break;
                default:
                        usage(argv[0]);
                }
        }
        
        if (show_version) {
                printf("%s\n", LINKPOLICY_VERSION);
                exit(0);
        }
        
        /* check args */
        if (argc < 3 || !(optind != (argc - 1))) {
                fprintf(stderr, "%s:  You must provide the base module package and at least one other module package\n", argv[0]);
                usage(argv[0]);
        }
        
        basename = argv[optind++];
        base = load_module(basename);
        if (!base) {
        	fprintf(stderr, "%s:  Could not load base module from file %s\n", argv[0], basename);
        	exit(1);
        }
       
        num_mods = argc - optind;
        mods = (sepol_module_package_t**)malloc(sizeof(sepol_module_package_t*) * num_mods);
        if (!mods) {
        	fprintf(stderr, "%s:  Out of memory\n", argv[0]);
        	exit(1);	
        }
        memset(mods, 0, sizeof(sepol_module_package_t*) * num_mods);
        
        for (i = 0; optind < argc; optind++, i++) {
        	mods[i] = load_module(argv[optind]);
        	if (!mods[i]) {
			fprintf(stderr, "%s:  Could not load module from file %s\n", argv[0], argv[optind]);
        		exit(1);
		}
        }

        if (sepol_link_packages(NULL, base, mods, num_mods, verbose)) {
        	fprintf(stderr, "%s:  Error while linking packages\n", argv[0]);
        	exit(1);	
        }
        
        if (outname) {
        	outfile = fopen(outname, "w");
	        if (!outfile) {
	        	perror(outname);
	        	exit(1);	
	        }
	        
		if (sepol_policy_file_create(&pf)) {
			fprintf(stderr, "%s:  Out of memory\n", argv[0]);
			exit(1);
		}
		sepol_policy_file_set_fp(pf, outfile);
        	if (sepol_module_package_write(base, pf)) {
        		fprintf(stderr, "%s:  Error writing linked package.\n", argv[0]);
        		exit(1);	
        	}
		sepol_policy_file_free(pf);
        }

	sepol_module_package_free(base);
        for (i = 0; i < num_mods; i++)
        	sepol_module_package_free(mods[i]);
	exit(0);
}
Example #10
0
/* Allocate an array of module_info structures for each readable
 * module within the store.  Note that if the calling program has
 * already begun a transaction then this function will get a list of
 * modules within the sandbox.	The caller is responsible for calling
 * semanage_module_info_datum_destroy() on each element of the array
 * as well as free()ing the entire list.
 */
static int semanage_direct_list(semanage_handle_t *sh,
				semanage_module_info_t **modinfo, int *num_modules) {
	struct sepol_policy_file *pf = NULL;
	int i, retval = -1;
	char **module_filenames = NULL;
	int num_mod_files;
	*modinfo = NULL;
	*num_modules = 0;

        /* get the read lock when reading from the active
           (non-transaction) directory */
	if (!sh->is_in_transaction) 
		if (semanage_get_active_lock(sh) < 0) 
			return -1;

	if (semanage_get_modules_names(sh, &module_filenames, &num_mod_files) == -1) {
		goto cleanup;
	}
	if (num_mod_files == 0) {
		retval = semanage_get_commit_number(sh);
		goto cleanup;
	}

	if (sepol_policy_file_create(&pf)) {
		ERR(sh, "Out of memory!");
		goto cleanup;
	}
	sepol_policy_file_set_handle(pf, sh->sepolh);
	
	if ((*modinfo = calloc(num_mod_files, sizeof(**modinfo))) == NULL) {
		ERR(sh, "Out of memory!");
		goto cleanup;
	}
	
	for (i = 0; i < num_mod_files; i++) {
		FILE *fp;
		char *name = NULL, *version = NULL;
		int type;
		if ((fp = fopen(module_filenames[i], "rb")) == NULL) {
			/* could not open this module file, so don't
			 * report it */
			continue;
		}
		sepol_policy_file_set_fp(pf, fp);
		if (sepol_module_package_info(pf, &type, &name, &version)) {
			fclose(fp);
			free(name);
			free(version);
			continue;
		}
		fclose(fp);
		if (type == SEPOL_POLICY_MOD) {
			(*modinfo)[*num_modules].name = name;
			(*modinfo)[*num_modules].version = version;
			(*num_modules)++;
		}
		else {
			/* file was not a module, so don't report it */
			free(name);
			free(version);
		}
	}
	retval = semanage_get_commit_number(sh);
	
 cleanup:
	sepol_policy_file_free(pf);
	for (i = 0; module_filenames != NULL && i < num_mod_files; i++) {
		free(module_filenames[i]);
	}
	free(module_filenames);
        if (!sh->is_in_transaction) {
                semanage_release_active_lock(sh);
        }
	return retval;
}