Esempio n. 1
0
static bool patch_sepolicy_daemon()
{
    policydb_t pdb;

    if (policydb_init(&pdb) < 0) {
        LOGE("Failed to initialize policydb");
        return false;
    }

    if (!util::selinux_read_policy(SELINUX_POLICY_FILE, &pdb)) {
        LOGE("Failed to read SELinux policy file: %s", SELINUX_POLICY_FILE);
        policydb_destroy(&pdb);
        return false;
    }

    LOGD("Policy version: %u", pdb.policyvers);

    util::selinux_add_rule(&pdb, "untrusted_app", "init",
                           "unix_stream_socket", "connectto");

    if (!util::selinux_write_policy(SELINUX_LOAD_FILE, &pdb)) {
        LOGE("Failed to write SELinux policy file: %s", SELINUX_LOAD_FILE);
        policydb_destroy(&pdb);
        return false;
    }

    policydb_destroy(&pdb);

    return true;
}
Esempio n. 2
0
static bool patch_sepolicy()
{
    policydb_t pdb;

    if (policydb_init(&pdb) < 0) {
        fprintf(stderr, "Failed to initialize policydb\n");
        return false;
    }

    if (!util::selinux_read_policy(SELINUX_POLICY_FILE, &pdb)) {
        fprintf(stderr, "Failed to read SELinux policy file: %s\n",
                SELINUX_POLICY_FILE);
        policydb_destroy(&pdb);
        return false;
    }

    printf("SELinux policy version: %d\n", pdb.policyvers);

    util::selinux_make_all_permissive(&pdb);

    if (!util::selinux_write_policy(SELINUX_LOAD_FILE, &pdb)) {
        fprintf(stderr, "Failed to write SELinux policy file: %s\n",
                SELINUX_LOAD_FILE);
        policydb_destroy(&pdb);
        return false;
    }

    policydb_destroy(&pdb);

    return true;
}
Esempio n. 3
0
static bool patch_sepolicy_internal(const std::string &source,
                                    const std::string &target)
{
    policydb_t pdb;

    if (policydb_init(&pdb) < 0) {
        LOGE("Failed to initialize policydb");
        return false;
    }

    if (!util::selinux_read_policy(source, &pdb)) {
        LOGE("Failed to read SELinux policy file: {}", source);
        policydb_destroy(&pdb);
        return false;
    }

    LOGD("Policy version: {}", pdb.policyvers);

    for (const char **iter = permissive_types; *iter; ++iter) {
        util::selinux_make_permissive(&pdb, *iter);
    }

    if (!util::selinux_write_policy(target, &pdb)) {
        LOGE("Failed to write SELinux policy file: {}", target);
        policydb_destroy(&pdb);
        return false;
    }

    policydb_destroy(&pdb);

    return true;
}
Esempio n. 4
0
int cond_test_cleanup(void)
{
	policydb_destroy(&basemod);
	policydb_destroy(&base_expanded);

	return 0;
}
Esempio n. 5
0
int cond_test_init(void)
{
	if (policydb_init(&base_expanded)) {
		fprintf(stderr, "out of memory!\n");
		policydb_destroy(&basemod);
		return -1;
	}

	if (test_load_policy(&basemod, POLICY_BASE, 1, "test-cond", "refpolicy-base.conf"))
		goto cleanup;

	if (link_modules(NULL, &basemod, NULL, 0, 0)) {
		fprintf(stderr, "link modules failed\n");
		goto cleanup;
	}

	if (expand_module(NULL, &basemod, &base_expanded, 0, 1)) {
		fprintf(stderr, "expand module failed\n");
		goto cleanup;
	}

	return 0;

      cleanup:
	policydb_destroy(&basemod);
	policydb_destroy(&base_expanded);
	return -1;
}
Esempio n. 6
0
int linker_test_cleanup(void)
{
	int i;

	policydb_destroy(&basenomods);
	policydb_destroy(&linkedbase);

	for (i = 0; i < NUM_MODS; i++) {
		policydb_destroy(modules[i]);
		free(modules[i]);
	}
	return 0;
}
Esempio n. 7
0
int test_load_policy(policydb_t * p, int policy_type, int mls, const char *test_name, const char *policy_name)
{
	char filename[PATH_MAX];

	if (mls) {
		if (snprintf(filename, PATH_MAX, "policies/%s/%s.mls", test_name, policy_name) < 0) {
			return -1;
		}
	} else {
		if (snprintf(filename, PATH_MAX, "policies/%s/%s.std", test_name, policy_name) < 0) {
			return -1;
		}
	}

	if (policydb_init(p)) {
		fprintf(stderr, "Out of memory");
		return -1;
	}

	p->policy_type = policy_type;
	p->mls = mls;

	if (read_source_policy(p, filename, test_name)) {
		fprintf(stderr, "failed to read policy %s\n", filename);
		policydb_destroy(p);
		return -1;
	}

	return 0;
}
Esempio n. 8
0
static void selinux_permissive(void)
{
    policydb_t policydb;
    struct policy_file pf;

    policydb_init(&policydb);
    sepol_set_policydb(&policydb);
    policy_file_init(&pf);

    // Read the current policy
    pf.fp = fopen("/sepolicy", "r");
    pf.type = PF_USE_STDIO;
    policydb_read(&policydb, &pf, 0);
    fclose(pf.fp);

    // Make init, recovery, and ueventd permissive
    set_permissive("init", &policydb);
    set_permissive("recovery", &policydb);
    set_permissive("ueventd", &policydb);

    // Write the new policy and load it
    pf.fp = fopen("/dev/sepolicy", "w+");
    policydb_write(&policydb, &pf);
    int size = ftell(pf.fp);
    fseek(pf.fp, SEEK_SET, 0);
    void *map = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fileno(pf.fp), 0);
    int load = open("/sys/fs/selinux/load", O_WRONLY);
    write(load, map, size);
    close(load);
    munmap(map, size);
    fclose(pf.fp);

    policydb_destroy(&policydb);
}
Esempio n. 9
0
bool selinux_mount()
{
    // Try /sys/fs/selinux
    if (!util::mount(SELINUX_FS_TYPE, SELINUX_MOUNT_POINT,
                     SELINUX_FS_TYPE, 0, nullptr)) {
        LOGW("Failed to mount %s at %s: %s",
             SELINUX_FS_TYPE, SELINUX_MOUNT_POINT, strerror(errno));
        if (errno == ENODEV || errno == ENOENT) {
            LOGI("Kernel does not support SELinux");
        }
        return false;
    }

    // Load default policy
    struct stat sb;
    if (stat(DEFAULT_SEPOLICY_FILE, &sb) == 0) {
        if (!selinux_set_enforcing(0)) {
            LOGW("Failed to set SELinux to permissive mode");
        }

        policydb_t pdb;

        if (policydb_init(&pdb) < 0) {
            LOGE("Failed to initialize policydb");
            return false;
        }

        if (!selinux_read_policy(DEFAULT_SEPOLICY_FILE, &pdb)) {
            LOGE("Failed to read SELinux policy file: %s",
                 DEFAULT_SEPOLICY_FILE);
            policydb_destroy(&pdb);
            return false;
        }
        if (!util::selinux_write_policy(SELINUX_LOAD_FILE, &pdb)) {
            LOGE("Failed to write SELinux policy file: %s",
                 SELINUX_LOAD_FILE);
            policydb_destroy(&pdb);
            return false;
        }

        policydb_destroy(&pdb);

        return true;
    }

    return true;
}
Esempio n. 10
0
/*
 * To work around denials (on Samsung devices):
 * 1. Mount the system and data partitions
 *
 *      $ mount /system
 *      $ mount /data
 *
 * 2. Start the audit daemon
 *
 *      $ /system/bin/auditd
 *
 * 3. From another window, run mbtool's update-binary wrapper
 *
 *      $ /tmp/mbtool_recovery updater 3 1 /path/to/file_patched.zip
 *
 * 4. Pull /data/misc/audit/audit.log and run it through audit2allow
 *
 *      $ adb pull /data/misc/audit/audit.log
 *      $ grep denied audit.log | audit2allow
 *
 * 5. Allow the rule using util::selinux_add_rule()
 *
 *    Rules of the form:
 *      allow source target:class perm;
 *    Are allowed by calling:
 *      util::selinux_add_rule(&pdb, source, target, class, perm);
 *
 * --
 *
 * To view the allow rules for the currently loaded policy:
 *
 * 1. Pull the current policy file
 *
 *      $ adb pull /sys/fs/selinux/policy
 *
 * 2. View the rules (the -s, -t, -c, and -p parameters can be used to filter
 *    the rules by source, target, class, and permission, respectively)
 *
 *      $ sesearch -A policy
 */
bool RecoveryInstaller::patch_sepolicy()
{
    policydb_t pdb;

    if (policydb_init(&pdb) < 0) {
        LOGE("Failed to initialize policydb");
        return false;
    }

    if (!util::selinux_read_policy(SELINUX_POLICY_FILE, &pdb)) {
        LOGE("Failed to read SELinux policy file: %s", SELINUX_POLICY_FILE);
        policydb_destroy(&pdb);
        return false;
    }

    LOGD("Policy version: %u", pdb.policyvers);

    // Debugging rules (for CWM and Philz)
    util::selinux_add_rule(&pdb, "adbd",  "block_device",    "blk_file",   "relabelto");
    util::selinux_add_rule(&pdb, "adbd",  "graphics_device", "chr_file",   "relabelto");
    util::selinux_add_rule(&pdb, "adbd",  "graphics_device", "dir",        "relabelto");
    util::selinux_add_rule(&pdb, "adbd",  "input_device",    "chr_file",   "relabelto");
    util::selinux_add_rule(&pdb, "adbd",  "input_device",    "dir",        "relabelto");
    util::selinux_add_rule(&pdb, "adbd",  "rootfs",          "dir",        "relabelto");
    util::selinux_add_rule(&pdb, "adbd",  "rootfs",          "file",       "relabelto");
    util::selinux_add_rule(&pdb, "adbd",  "rootfs",          "lnk_file",   "relabelto");
    util::selinux_add_rule(&pdb, "adbd",  "system_file",     "file",       "relabelto");
    util::selinux_add_rule(&pdb, "adbd",  "tmpfs",           "file",       "relabelto");

    util::selinux_add_rule(&pdb, "rootfs", "tmpfs",          "filesystem", "associate");
    util::selinux_add_rule(&pdb, "tmpfs",  "rootfs",         "filesystem", "associate");

    if (!util::selinux_write_policy(SELINUX_LOAD_FILE, &pdb)) {
        LOGE("Failed to write SELinux policy file: %s", SELINUX_LOAD_FILE);
        policydb_destroy(&pdb);
        return false;
    }

    policydb_destroy(&pdb);

    return true;
}
int main(int argc, char **argv)
{
    char *policy = NULL;
    struct policy_file pf;
    policydb_t policydb;
    char ch;
    char equiv = 0, diff = 0, dups = 0;

    struct option long_options[] = {
        {"equiv", no_argument, NULL, 'e'},
        {"diff", no_argument, NULL, 'd'},
        {"dups", no_argument, NULL, 'D'},
        {"policy", required_argument, NULL, 'P'},
        {NULL, 0, NULL, 0}
    };

    while ((ch = getopt_long(argc, argv, "edDP:", long_options, NULL)) != -1) {
        switch (ch) {
        case 'e':
            equiv = 1;
            break;
        case 'd':
            diff = 1;
            break;
        case 'D':
            dups = 1;
            break;
        case 'P':
            policy = optarg;
            break;
        default:
            usage(argv[0]);
        }
    }

    if (!policy || (!equiv && !diff && !dups))
        usage(argv[0]);

    if (load_policy(policy, &policydb, &pf))
        exit(1);

    if (equiv || diff)
        analyze_types(&policydb, equiv, diff);

    if (dups)
        find_dups(&policydb);

    policydb_destroy(&policydb);

    return 0;
}
int main(int argc, char **argv)
{
	char *file = txtfile, *outfile = NULL;
	unsigned int binary = 0;
	int ch;
	int show_version = 0;
	policydb_t modpolicydb;
	struct option long_options[] = {
		{"help", no_argument, NULL, 'h'},
		{"output", required_argument, NULL, 'o'},
		{"binary", no_argument, NULL, 'b'},
		{"version", no_argument, NULL, 'V'},
		{"handle-unknown", optional_argument, NULL, 'U'},
		{"mls", no_argument, NULL, 'M'},
		{NULL, 0, NULL, 0}
	};

	while ((ch = getopt_long(argc, argv, "ho:bVU:mM", long_options, NULL)) != -1) {
		switch (ch) {
		case 'h':
			usage(argv[0]);
			break;
		case 'o':
			outfile = optarg;
			break;
		case 'b':
			binary = 1;
			file = binfile;
			break;
		case 'V':
			show_version = 1;
			break;
		case 'U':
			if (!strcasecmp(optarg, "deny")) {
				handle_unknown = DENY_UNKNOWN;
				break;
			}
			if (!strcasecmp(optarg, "reject")) {
				handle_unknown = REJECT_UNKNOWN;
				break;
			}
			if (!strcasecmp(optarg, "allow")) {
				handle_unknown = ALLOW_UNKNOWN;
				break;
			}
			usage(argv[0]);
		case 'm':
			policy_type = POLICY_MOD;
			policyvers = MOD_POLICYDB_VERSION_MAX;
			break;
		case 'M':
			mlspol = 1;
			break;
		default:
			usage(argv[0]);
		}
	}

	if (show_version) {
		printf("Module versions %d-%d\n",
		       MOD_POLICYDB_VERSION_MIN, MOD_POLICYDB_VERSION_MAX);
		exit(0);
	}

	if (handle_unknown && (policy_type != POLICY_BASE)) {
		printf("Handling of unknown classes and permissions is only ");
		printf("valid in the base module\n");
		exit(1);
	}

	if (optind != argc) {
		file = argv[optind++];
		if (optind != argc)
			usage(argv[0]);
	}
	printf("%s:  loading policy configuration from %s\n", argv[0], file);

	/* Set policydb and sidtab used by libsepol service functions
	   to my structures, so that I can directly populate and
	   manipulate them. */
	sepol_set_policydb(&modpolicydb);
	sepol_set_sidtab(&sidtab);

	if (binary) {
		if (read_binary_policy(&modpolicydb, file, argv[0]) == -1) {
			exit(1);
		}
	} else {
		if (policydb_init(&modpolicydb)) {
			fprintf(stderr, "%s: out of memory!\n", argv[0]);
			return -1;
		}

		modpolicydb.policy_type = policy_type;
		modpolicydb.mls = mlspol;
		modpolicydb.handle_unknown = handle_unknown;

		if (read_source_policy(&modpolicydb, file, argv[0]) == -1) {
			exit(1);
		}

		if (hierarchy_check_constraints(NULL, &modpolicydb)) {
			return -1;
		}
	}

	if (modpolicydb.policy_type == POLICY_BASE) {
		/* Verify that we can successfully expand the base module. */
		policydb_t kernpolicydb;

		if (policydb_init(&kernpolicydb)) {
			fprintf(stderr, "%s:  policydb_init failed\n", argv[0]);
			exit(1);
		}
		if (link_modules(NULL, &modpolicydb, NULL, 0, 0)) {
			fprintf(stderr, "%s:  link modules failed\n", argv[0]);
			exit(1);
		}
		if (expand_module(NULL, &modpolicydb, &kernpolicydb, 0, 1)) {
			fprintf(stderr, "%s:  expand module failed\n", argv[0]);
			exit(1);
		}
		policydb_destroy(&kernpolicydb);
	}

	if (policydb_load_isids(&modpolicydb, &sidtab))
		exit(1);

	sepol_sidtab_destroy(&sidtab);

	printf("%s:  policy configuration loaded\n", argv[0]);

	if (outfile &&
	    write_binary_policy(&modpolicydb, outfile, argv[0]) == -1) {
		exit(1);
	}
	policydb_destroy(&modpolicydb);

	return 0;
}
int main_seinject(int argc, char **argv) {
	char *policy = NULL, *source = NULL, *target = NULL, *clazz = NULL, *perm = NULL, *perm_token = NULL, *perm_saveptr = NULL, *outfile = NULL, *permissive = NULL;
	policydb_t policydb;
	struct policy_file pf, outpf;
	sidtab_t sidtab;
	int ret_add_rule;
	int load = 0;
	int quiet = 0;
	FILE *fp;
	int i;

	for (i=1; i<argc; i++) {
		if (argv[i][0] == '-') {
			if (argv[i][1] == 's') {
				i++;
				source = argv[i];
				continue;
			}
			if (argv[i][1] == 't') {
				i++;
				target = argv[i];
				continue;
			}
			if (argv[i][1] == 'c') {
				i++;
				clazz = argv[i];
				continue;
			}
			if (argv[i][1] == 'p') {
				i++;
				perm = argv[i];
				continue;
			}
			if (argv[i][1] == 'P') {
				i++;
				policy = argv[i];
				continue;
			}
			if (argv[i][1] == 'o') {
				i++;
				outfile = argv[i];
				continue;
			}
			if (argv[i][1] == 'Z') {
				i++;
				permissive = argv[i];
				continue;
			}
			if (argv[i][1] == 'l') {
				load = 1;
				continue;
			}
			if (argv[i][1] == 'q') {
				quiet = 1;
				continue;
			}
			break;
		}
	}

	if (i < argc || argc == 1 || ((!source || !target || !clazz || !perm) && !permissive)) {
		fprintf(stderr, "%s -s <source type> -t <target type> -c <class> -p <perm>[,<perm2>,<perm3>,...] [-P <policy file>] [-o <output file>] [-l|--load]\n", argv[0]);
		fprintf(stderr, "%s -Z permissive_type [-P <policy file>] [-o <output file>] [-l|--load]\n", argv[0]);
		exit(1);
	}

	if (!policy)
		policy = "/sys/fs/selinux/policy";

	sepol_set_policydb(&policydb);
	sepol_set_sidtab(&sidtab);

	if (load_policy(policy, &policydb, &pf)) {
		fprintf(stderr, "Could not load policy\n");
		return 1;
	}

	if (policydb_load_isids(&policydb, &sidtab))
		return 1;

	if (permissive) {
		type_datum_t *type;
		type = hashtab_search(policydb.p_types.table, permissive);
		if (type == NULL) {
			fprintf(stderr, "type %s does not exist\n", permissive);
			return 2;
		}
		if (ebitmap_set_bit(&policydb.permissive_map, type->s.value, 1)) {
			fprintf(stderr, "Could not set bit in permissive map\n");
			return 1;
		}
	} else {
		perm_token = strtok_r(perm, ",", &perm_saveptr);
		while (perm_token) {
			ret_add_rule = add_rule(source, target, clazz, perm_token, &policydb);
			if (ret_add_rule) {
				fprintf(stderr, "Could not add rule for perm: %s\n", perm_token);
				return ret_add_rule;
			}
			perm_token = strtok_r(NULL, ",", &perm_saveptr);
		}
	}

	if (outfile) {
		fp = fopen(outfile, "wb");
		if (!fp) {
			fprintf(stderr, "Could not open outfile\n");
			return 1;
		}

		policy_file_init(&outpf);
		outpf.type = PF_USE_STDIO;
		outpf.fp = fp;

		if (policydb_write(&policydb, &outpf)) {
			fprintf(stderr, "Could not write policy\n");
			return 1;
		}

		fclose(fp);
	}

	if (load) {
		if (load_policy_into_kernel(&policydb)) {
			fprintf(stderr, "Could not load new policy into kernel\n");
			return 1;
		}
	}

	policydb_destroy(&policydb);

	if (quiet == 0)
		fprintf(stdout, "Success\n");
	return 0;
}
Esempio n. 14
0
static int load_booleans(struct policydb *policydb, const char *path,
			 int *changesp)
{
	FILE *boolf;
	char *buffer = NULL;
	size_t size = 0;
	char localbools[BUFSIZ];
	char name[BUFSIZ];
	int val;
	int errors = 0, changes = 0;
	struct cond_bool_datum *datum;

	boolf = fopen(path, "r");
	if (boolf == NULL)
		goto localbool;

#ifdef DARWIN
        if ((buffer = (char *)malloc(255 * sizeof(char))) == NULL) {
          ERR(NULL, "out of memory");
	  return -1;
	}

        while(fgets(buffer, 255, boolf) != NULL) {
#else
	while (getline(&buffer, &size, boolf) > 0) {
#endif
		int ret = process_boolean(buffer, name, sizeof(name), &val);
		if (ret == -1)
			errors++;
		if (ret == 1) {
			datum = hashtab_search(policydb->p_bools.table, name);
			if (!datum) {
				ERR(NULL, "unknown boolean %s", name);
				errors++;
				continue;
			}
			if (datum->state != val) {
				datum->state = val;
				changes++;
			}
		}
	}
	fclose(boolf);
      localbool:
	snprintf(localbools, sizeof(localbools), "%s.local", path);
	boolf = fopen(localbools, "r");
	if (boolf != NULL) {

#ifdef DARWIN

	  while(fgets(buffer, 255, boolf) != NULL) {
#else

	    while (getline(&buffer, &size, boolf) > 0) {
#endif
			int ret =
			    process_boolean(buffer, name, sizeof(name), &val);
			if (ret == -1)
				errors++;
			if (ret == 1) {
				datum =
				    hashtab_search(policydb->p_bools.table,
						   name);
				if (!datum) {
					ERR(NULL, "unknown boolean %s", name);
					errors++;
					continue;
				}
				if (datum->state != val) {
					datum->state = val;
					changes++;
				}
			}
		}
		fclose(boolf);
	}
	free(buffer);
	if (errors)
		errno = EINVAL;
	*changesp = changes;
	return errors ? -1 : 0;
}

int sepol_genbools(void *data, size_t len, char *booleans)
{
	struct policydb policydb;
	struct policy_file pf;
	int rc, changes = 0;

	if (policydb_init(&policydb))
		goto err;
	if (policydb_from_image(NULL, data, len, &policydb) < 0)
		goto err;

	if (load_booleans(&policydb, booleans, &changes) < 0) {
		WARN(NULL, "error while reading %s", booleans);
	}

	if (!changes)
		goto out;

	if (evaluate_conds(&policydb) < 0) {
		ERR(NULL, "error while re-evaluating conditionals");
		errno = EINVAL;
		goto err_destroy;
	}

	policy_file_init(&pf);
	pf.type = PF_USE_MEMORY;
	pf.data = data;
	pf.len = len;
	rc = policydb_write(&policydb, &pf);
	if (rc) {
		ERR(NULL, "unable to write new binary policy image");
		errno = EINVAL;
		goto err_destroy;
	}

      out:
	policydb_destroy(&policydb);
	return 0;

      err_destroy:
	policydb_destroy(&policydb);

      err:
	return -1;
}

int hidden sepol_genbools_policydb(policydb_t * policydb, const char *booleans)
{
	int rc, changes = 0;

	rc = load_booleans(policydb, booleans, &changes);
	if (!rc && changes)
		rc = evaluate_conds(policydb);
	if (rc)
		errno = EINVAL;
	return rc;
}

/* -- End Deprecated -- */

int sepol_genbools_array(void *data, size_t len, char **names, int *values,
			 int nel)
{
	struct policydb policydb;
	struct policy_file pf;
	int rc, i, errors = 0;
	struct cond_bool_datum *datum;

	/* Create policy database from image */
	if (policydb_init(&policydb))
		goto err;
	if (policydb_from_image(NULL, data, len, &policydb) < 0)
		goto err;

	for (i = 0; i < nel; i++) {
		datum = hashtab_search(policydb.p_bools.table, names[i]);
		if (!datum) {
			ERR(NULL, "boolean %s no longer in policy", names[i]);
			errors++;
			continue;
		}
		if (values[i] != 0 && values[i] != 1) {
			ERR(NULL, "illegal value %d for boolean %s",
			    values[i], names[i]);
			errors++;
			continue;
		}
		datum->state = values[i];
	}

	if (evaluate_conds(&policydb) < 0) {
		ERR(NULL, "error while re-evaluating conditionals");
		errno = EINVAL;
		goto err_destroy;
	}

	policy_file_init(&pf);
	pf.type = PF_USE_MEMORY;
	pf.data = data;
	pf.len = len;
	rc = policydb_write(&policydb, &pf);
	if (rc) {
		ERR(NULL, "unable to write binary policy");
		errno = EINVAL;
		goto err_destroy;
	}
	if (errors) {
		errno = EINVAL;
		goto err_destroy;
	}

	policydb_destroy(&policydb);
	return 0;

      err_destroy:
	policydb_destroy(&policydb);

      err:
	return -1;
}
Esempio n. 15
0
/**
 * security_load_policy - Load a security policy configuration.
 * @data: binary policy data
 * @len: length of data in bytes
 *
 * Load a new set of security policy configuration data,
 * validate it and convert the SID table as necessary.
 * This function will flush the access vector cache after
 * loading the new policy.
 */
int security_load_policy(void *data, size_t len)
{
	struct policydb oldpolicydb, newpolicydb;
	struct sidtab oldsidtab, newsidtab;
	struct convert_context_args args;
	u32 seqno;
	int rc = 0;
	struct policy_file file = { data, len }, *fp = &file;

	LOAD_LOCK;

	if (!ss_initialized) {
		if (policydb_read(&policydb, fp)) {
			LOAD_UNLOCK;
			return -EINVAL;
		}
		if (policydb_load_isids(&policydb, &sidtab)) {
			LOAD_UNLOCK;
			policydb_destroy(&policydb);
			return -EINVAL;
		}
		ss_initialized = 1;
		LOAD_UNLOCK;
		selinux_complete_init();
		return 0;
	}

#if 0
	sidtab_hash_eval(&sidtab, "sids");
#endif

	if (policydb_read(&newpolicydb, fp)) {
		LOAD_UNLOCK;
		return -EINVAL;
	}

	sidtab_init(&newsidtab);

	/* Verify that the existing classes did not change. */
	if (hashtab_map(policydb.p_classes.table, validate_class, &newpolicydb)) {
		printk(KERN_ERR "security:  the definition of an existing "
		       "class changed\n");
		rc = -EINVAL;
		goto err;
	}

	/* Clone the SID table. */
	sidtab_shutdown(&sidtab);
	if (sidtab_map(&sidtab, clone_sid, &newsidtab)) {
		rc = -ENOMEM;
		goto err;
	}

	/* Convert the internal representations of contexts
	   in the new SID table and remove invalid SIDs. */
	args.oldp = &policydb;
	args.newp = &newpolicydb;
	sidtab_map_remove_on_error(&newsidtab, convert_context, &args);

	/* Save the old policydb and SID table to free later. */
	memcpy(&oldpolicydb, &policydb, sizeof policydb);
	sidtab_set(&oldsidtab, &sidtab);

	/* Install the new policydb and SID table. */
	POLICY_WRLOCK;
	memcpy(&policydb, &newpolicydb, sizeof policydb);
	sidtab_set(&sidtab, &newsidtab);
	seqno = ++latest_granting;
	POLICY_WRUNLOCK;
	LOAD_UNLOCK;

	/* Free the old policydb and SID table. */
	policydb_destroy(&oldpolicydb);
	sidtab_destroy(&oldsidtab);

	avc_ss_reset(seqno);

	return 0;

err:
	LOAD_UNLOCK;
	sidtab_destroy(&newsidtab);
	policydb_destroy(&newpolicydb);
	return rc;

}
Esempio n. 16
0
int expander_test_cleanup(void)
{
	policydb_destroy(&basemod);
	policydb_destroy(&base_expanded);
	policydb_destroy(&basemod2);
	policydb_destroy(&base_expanded2);
	policydb_destroy(&mod2);
	policydb_destroy(&base_only_mod);
	policydb_destroy(&base_only_expanded);
	policydb_destroy(&role_basemod);
	policydb_destroy(&role_expanded);
	policydb_destroy(&role_mod);
	policydb_destroy(&user_basemod);
	policydb_destroy(&user_expanded);
	policydb_destroy(&user_mod);
	policydb_destroy(&alias_basemod);
	policydb_destroy(&alias_expanded);
	policydb_destroy(&alias_mod);
	free(typemap);

	return 0;
}