Exemplo n.º 1
0
/* Tests the semanage_get_lock functions in semanage_store.c
 */
void test_semanage_get_lock(void)
{
	int err;

	/* attempt to get an active lock */
	err = semanage_get_active_lock(sh);
	CU_ASSERT(err == 0);

	/* attempt to get the lock again */
	err = semanage_get_active_lock(sh);
	CU_ASSERT(err == 0);

	/* attempt to release the active lock */
	semanage_release_active_lock(sh);

	/* attempt to get an active lock */
	err = semanage_get_active_lock(sh);
	CU_ASSERT(err == 0);

	/* attempt to release the active lock */
	semanage_release_active_lock(sh);

	/* attempt to get a trans lock */
	err = semanage_get_trans_lock(sh);
	CU_ASSERT(err == 0);

	/* attempt to get the lock again */
	err = semanage_get_trans_lock(sh);
	CU_ASSERT(err == 0);

	/* attempt to release the trans lock */
	semanage_release_trans_lock(sh);

	/* attempt to get a trans lock */
	err = semanage_get_trans_lock(sh);
	CU_ASSERT(err == 0);

	/* attempt to release the trans lock */
	semanage_release_trans_lock(sh);

	/* remove the lock files */
	err = remove(readlockpath);
	CU_ASSERT(err == 0);
	err = remove(translockpath);
	CU_ASSERT(err == 0);
}
Exemplo n.º 2
0
static int semanage_direct_disconnect(semanage_handle_t *sh) {
	/* destroy transaction */
	if (sh->is_in_transaction) {
		/* destroy sandbox */
		if (semanage_remove_directory(semanage_path(SEMANAGE_TMP, SEMANAGE_TOPLEVEL)) < 0) {
			ERR(sh, "Could not cleanly remove sandbox %s.", semanage_path(SEMANAGE_TMP, SEMANAGE_TOPLEVEL));
			return -1;
		}
		semanage_release_trans_lock(sh);
	}

	/* Release object databases: local modifications */
	user_base_file_dbase_release(semanage_user_base_dbase_local(sh));
	user_extra_file_dbase_release(semanage_user_extra_dbase_local(sh));
	user_join_dbase_release(semanage_user_dbase_local(sh));
	port_file_dbase_release(semanage_port_dbase_local(sh));
	iface_file_dbase_release(semanage_iface_dbase_local(sh));
	bool_file_dbase_release(semanage_bool_dbase_local(sh));
	fcontext_file_dbase_release(semanage_fcontext_dbase_local(sh));
	seuser_file_dbase_release(semanage_seuser_dbase_local(sh));
	node_file_dbase_release(semanage_node_dbase_local(sh));

	/* Release object databases: local modifications + policy */
	user_base_policydb_dbase_release(semanage_user_base_dbase_policy(sh));
	user_extra_file_dbase_release(semanage_user_extra_dbase_policy(sh));
	user_join_dbase_release(semanage_user_dbase_policy(sh));
	port_policydb_dbase_release(semanage_port_dbase_policy(sh));
	iface_policydb_dbase_release(semanage_iface_dbase_policy(sh));
	bool_policydb_dbase_release(semanage_bool_dbase_policy(sh));
	fcontext_file_dbase_release(semanage_fcontext_dbase_policy(sh));
	seuser_file_dbase_release(semanage_seuser_dbase_policy(sh));
	node_policydb_dbase_release(semanage_node_dbase_policy(sh));

	/* Release object databases: active kernel policy */
	bool_activedb_dbase_release(semanage_bool_dbase_active(sh));

	return 0;
}
Exemplo n.º 3
0
/* Commits all changes in sandbox to the actual kernel policy.
 * Returns commit number on success, -1 on error.
 */
static int semanage_direct_commit(semanage_handle_t *sh) {
	char **mod_filenames = NULL;
	const char *linked_filename = NULL, *ofilename = NULL;
	sepol_module_package_t *base = NULL;
	int retval = -1, num_modfiles = 0, i;
	sepol_policydb_t* out = NULL;

	/* Declare some variables */
	int modified, fcontexts_modified, ports_modified, 
		seusers_modified, users_extra_modified;
	dbase_config_t* users = semanage_user_dbase_local(sh);
	dbase_config_t* users_base = semanage_user_base_dbase_local(sh);
	dbase_config_t* pusers_base = semanage_user_base_dbase_policy(sh);
	dbase_config_t* users_extra = semanage_user_extra_dbase_local(sh);
	dbase_config_t* pusers_extra = semanage_user_extra_dbase_policy(sh);
	dbase_config_t* ports = semanage_port_dbase_local(sh);
	dbase_config_t* pports = semanage_port_dbase_policy(sh);
	dbase_config_t* bools = semanage_bool_dbase_local(sh);
	dbase_config_t* pbools = semanage_bool_dbase_policy(sh);
	dbase_config_t* ifaces = semanage_iface_dbase_local(sh);
	dbase_config_t* pifaces = semanage_iface_dbase_policy(sh);
	dbase_config_t* nodes = semanage_node_dbase_local(sh);
	dbase_config_t* pnodes = semanage_node_dbase_policy(sh);
	dbase_config_t* fcontexts = semanage_fcontext_dbase_local(sh);
	dbase_config_t* pfcontexts = semanage_fcontext_dbase_policy(sh);
	dbase_config_t* seusers = semanage_seuser_dbase_local(sh);
	dbase_config_t* pseusers = semanage_seuser_dbase_policy(sh);

	/* Before we do anything else, flush the join to its component parts.
	 * This *does not* flush to disk automatically */
	if (users->dtable->is_modified(users->dbase) &&
	    users->dtable->flush(sh, users->dbase) < 0)
		goto cleanup;

	/* Decide if anything was modified */
	fcontexts_modified = fcontexts->dtable->is_modified(fcontexts->dbase);
	seusers_modified = seusers->dtable->is_modified(seusers->dbase);
	users_extra_modified = users_extra->dtable->is_modified(users_extra->dbase);
	ports_modified = ports->dtable->is_modified(ports->dbase);

	modified = sh->modules_modified;
	modified |= ports_modified;
	modified |= users->dtable->is_modified(users_base->dbase);
	modified |= bools->dtable->is_modified(bools->dbase);
	modified |= ifaces->dtable->is_modified(ifaces->dbase);
	modified |= nodes->dtable->is_modified(nodes->dbase);

	/* FIXME: get rid of these, once we support loading the existing policy,
	 * instead of rebuilding it */
	modified |= seusers_modified;
	modified |= fcontexts_modified;
	modified |= users_extra_modified;

	/* If there were policy changes, or explicitly requested, rebuild the policy */
	if (sh->do_rebuild || modified) {

		/* =================== Module expansion =============== */

		/* link all modules in the sandbox to the base module */
		if (semanage_get_modules_names(sh, &mod_filenames, &num_modfiles) != 0 ||
		    semanage_verify_modules(sh, mod_filenames, num_modfiles) == -1 ||
		    semanage_link_sandbox(sh, &base) < 0) {
			goto cleanup;
		}
	
		/* write the linked base */
		if ((linked_filename = semanage_path(SEMANAGE_TMP, SEMANAGE_LINKED)) == NULL ||
		    semanage_write_module(sh, linked_filename, base) == -1 ||
		    semanage_verify_linked(sh) != 0) {
			goto cleanup;
		}

		/* ==================== File-backed ================== */

		/* File Contexts */
		if ((ofilename = semanage_path(SEMANAGE_TMP, SEMANAGE_FC_TMPL)) == NULL ||
		    write_file(sh, ofilename, sepol_module_package_get_file_contexts(base), 
				sepol_module_package_get_file_contexts_len(base)) == -1) {
			goto cleanup;
		}

		if (semanage_split_fc(sh)) 
			goto cleanup;

		pfcontexts->dtable->drop_cache(pfcontexts->dbase);

		/* Seusers */
		if (sepol_module_package_get_seusers_len(base)) {
			if ((ofilename = semanage_path(SEMANAGE_TMP, SEMANAGE_SEUSERS)) == NULL ||
			    write_file(sh, ofilename, sepol_module_package_get_seusers(base), 
					sepol_module_package_get_seusers_len(base)) == -1) {
				goto cleanup;
			}
			pseusers->dtable->drop_cache(pseusers->dbase);

		} else {
			if (pseusers->dtable->clear(sh, pseusers->dbase) < 0)
				goto cleanup;
		}

		/* Users_extra */
		if (sepol_module_package_get_user_extra_len(base)) {
			if ((ofilename = semanage_path(SEMANAGE_TMP, SEMANAGE_USERS_EXTRA)) == NULL ||
			    write_file(sh, ofilename, sepol_module_package_get_user_extra(base), 
					sepol_module_package_get_user_extra_len(base)) == -1) {
				goto cleanup;
			}
			pusers_extra->dtable->drop_cache(pusers_extra->dbase);

		} else {
			if (pusers_extra->dtable->clear(sh, pusers_extra->dbase) < 0)
				goto cleanup;
		}

		/* ==================== Policydb-backed ================ */

		/* Create new policy object, then attach to policy databases
		 * that work with a policydb */
		if (semanage_expand_sandbox(sh, base, &out) < 0)
			goto cleanup;

		dbase_policydb_attach((dbase_policydb_t*) pusers_base->dbase, out);
		dbase_policydb_attach((dbase_policydb_t*) pports->dbase, out);
		dbase_policydb_attach((dbase_policydb_t*) pifaces->dbase, out);
		dbase_policydb_attach((dbase_policydb_t*) pbools->dbase, out);
		dbase_policydb_attach((dbase_policydb_t*) pnodes->dbase, out);

		/* ============= Apply changes, and verify  =============== */

		if (semanage_base_merge_components(sh) < 0)
			goto cleanup;

		if (semanage_write_policydb(sh, out) < 0)
			goto cleanup;

		if (semanage_verify_kernel(sh) != 0)
			goto cleanup;
	}

	/* FIXME: else if !modified, but seusers_modified, 
	 * load the existing policy instead of rebuilding */

	/* ======= Post-process: Validate non-policydb components ===== */

	/* Validate local modifications to file contexts.
	 * Note: those are still cached, even though they've been 
	 * merged into the main file_contexts. We won't check the 
	 * large file_contexts - checked at compile time */
	if (sh->do_rebuild || modified || fcontexts_modified) {
		if (semanage_fcontext_validate_local(sh, out) < 0)
			goto cleanup;
	}

	/* Validate local seusers against policy */
	if (sh->do_rebuild || modified || seusers_modified) {
		if (semanage_seuser_validate_local(sh, out) < 0) 
			goto cleanup;
	}

	/* Validate local ports for overlap */
	if (sh->do_rebuild || ports_modified) {
		if (semanage_port_validate_local(sh) < 0)
			goto cleanup;
	}

	/* ================== Write non-policydb components ========= */

	/* Commit changes to components */
	if (semanage_commit_components(sh) < 0)
		goto cleanup;

	retval = semanage_install_sandbox(sh);

 cleanup:
	for (i = 0; mod_filenames != NULL && i < num_modfiles; i++) {
		free(mod_filenames[i]);
	}

	/* Detach from policydb, so it can be freed */
	dbase_policydb_detach((dbase_policydb_t*) pusers_base->dbase);
	dbase_policydb_detach((dbase_policydb_t*) pports->dbase);
	dbase_policydb_detach((dbase_policydb_t*) pifaces->dbase);
	dbase_policydb_detach((dbase_policydb_t*) pnodes->dbase);
	dbase_policydb_detach((dbase_policydb_t*) pbools->dbase);

	free(mod_filenames);
	sepol_module_package_free(base);
	sepol_policydb_free(out);
	semanage_release_trans_lock(sh);

	/* regardless if the commit was successful or not, remove the
	   sandbox if it is still there */
	semanage_remove_directory(semanage_path(SEMANAGE_TMP, SEMANAGE_TOPLEVEL));
	return retval;
}