Ejemplo n.º 1
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;
}
Ejemplo n.º 2
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;
}
Ejemplo n.º 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;
}
Ejemplo n.º 4
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;
}
Ejemplo n.º 5
0
static void do_fc_check_and_die_on_error(struct selinux_opt opts[], unsigned int backend, filemode mode,
        const char *sepolicy_file, const char *context_file, bool allow_empty)
{
    struct stat sb;
    if (stat(context_file, &sb) < 0) {
        perror("Error: could not get stat on file contexts file");
        exit(1);
    }

    if (sb.st_size == 0) {
        /* Nothing to check on empty file_contexts file if allowed*/
        if (allow_empty) {
            return;
        }
        /* else: We could throw the error here, but libselinux backend will catch it */
    }

    global_state.sepolicy.file = fopen(sepolicy_file, "r");
    if (!global_state.sepolicy.file) {
      perror("Error: could not open policy file");
      exit(1);
    }

    global_state.sepolicy.handle = sepol_handle_create();
    if (!global_state.sepolicy.handle) {
        fprintf(stderr, "Error: could not create policy handle: %s\n", strerror(errno));
        exit(1);
    }

    if (sepol_policy_file_create(&global_state.sepolicy.pf) < 0) {
      perror("Error: could not create policy handle");
      exit(1);
    }

    sepol_policy_file_set_fp(global_state.sepolicy.pf, global_state.sepolicy.file);
    sepol_policy_file_set_handle(global_state.sepolicy.pf, global_state.sepolicy.handle);

    int rc = sepol_policydb_create(&global_state.sepolicy.sdb);
    if (rc < 0) {
      perror("Error: could not create policy db");
      exit(1);
    }

    rc = sepol_policydb_read(global_state.sepolicy.sdb, global_state.sepolicy.pf);
    if (rc < 0) {
      perror("Error: could not read file into policy db");
      exit(1);
    }

    global_state.assert.attrs = filemode_to_assert_attrs(mode);

    bool ret = ebitmap_attribute_assertion_init(&global_state.assert.set, global_state.assert.attrs);
    if (!ret) {
        /* error messages logged by ebitmap_attribute_assertion_init() */
        exit(1);
    }

    selinux_set_callback(SELINUX_CB_VALIDATE,
                         (union selinux_callback)&validate);

    opts[1].value = context_file;

    global_state.sepolicy.sehnd[0] = selabel_open(backend, opts, 2);
    if (!global_state.sepolicy.sehnd[0]) {
      fprintf(stderr, "Error: could not load context file from %s\n", context_file);
      exit(1);
    }
}
Ejemplo n.º 6
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;
}