static int write_binary_policy(policydb_t * p, char *file, char *progname)
{
	FILE *outfp = NULL;
	struct policy_file pf;
	int ret;

	printf("%s:  writing binary representation (version %d) to %s\n",
	       progname, policyvers, file);

	outfp = fopen(file, "w");
	if (!outfp) {
		perror(file);
		exit(1);
	}

	p->policy_type = policy_type;
	p->policyvers = policyvers;
	p->handle_unknown = handle_unknown;

	policy_file_init(&pf);
	pf.type = PF_USE_STDIO;
	pf.fp = outfp;
	ret = policydb_write(p, &pf);
	if (ret) {
		fprintf(stderr, "%s:  error writing %s\n", progname, file);
		return -1;
	}
	fclose(outfp);
	return 0;
}
Ejemplo n.º 2
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);
}
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;
}
Ejemplo n.º 4
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;
}
Ejemplo n.º 5
0
int sepol_module_package_write(sepol_module_package_t *p, 
			       struct sepol_policy_file *spf)
{
	struct policy_file *file = &spf->pf;
	policy_file_t polfile;
	uint32_t buf[5], offsets[5], len, nsec = 0;
	int i;

	if (p->policy) {
		/* compute policy length */
		polfile.type = PF_LEN;
		polfile.data = NULL;
		polfile.len = 0;
		polfile.handle = file->handle;
		if (policydb_write(&p->policy->p, &polfile))
			return -1;
		len = polfile.len;
		if (!polfile.len)
			return -1;
		nsec++;
		
	} else {
		/* We don't support writing a package without a module at this point */
		return -1;
	}

	/* seusers and user_extra only supported in base at the moment */
	if ((p->seusers || p->user_extra) && (p->policy->p.policy_type != SEPOL_POLICY_BASE)) {
		ERR(file->handle, "seuser and user_extra sections only supported in base");	
		return -1;
	}

	if (p->file_contexts)
		nsec++;

	if (p->seusers)
		nsec++;

	if (p->user_extra)
		nsec++;

	buf[0] = cpu_to_le32(SEPOL_MODULE_PACKAGE_MAGIC);
	buf[1] = cpu_to_le32(p->version);
	buf[2] = cpu_to_le32(nsec);
	if (put_entry(buf, sizeof(uint32_t), 3, file) != 3)
		return -1;

	/* calculate offsets */
	offsets[0] = (nsec + 3) * sizeof(uint32_t);
	buf[0] = cpu_to_le32(offsets[0]);

	i = 1;
	if (p->file_contexts) {
		offsets[i] = offsets[i-1] + len;
		buf[i] = cpu_to_le32(offsets[i]);
		/* add a uint32_t to compensate for the magic number */
		len = p->file_contexts_len + sizeof(uint32_t);
		i++;
	}
	if (p->seusers) {
		offsets[i] = offsets[i-1] + len;
		buf[i] = cpu_to_le32(offsets[i]);
		len = p->seusers_len + sizeof(uint32_t);
		i++;
	}
	if (p->user_extra) {
		offsets[i] = offsets[i-1] + len;
		buf[i] = cpu_to_le32(offsets[i]);
		len = p->user_extra_len + sizeof(uint32_t);
		i++;
	}
	if (put_entry(buf, sizeof(uint32_t), nsec, file) != nsec)
		return -1;

	/* write sections */

	if (policydb_write(&p->policy->p, file))
		return -1;

	if (p->file_contexts) {	
		buf[0] = cpu_to_le32(SEPOL_PACKAGE_SECTION_FC);
		if (put_entry(buf, sizeof(uint32_t), 1, file) != 1)
			return -1;
		if (write_helper(p->file_contexts, p->file_contexts_len, file))
			return -1;
	}
	if (p->seusers) {	
		buf[0] = cpu_to_le32(SEPOL_PACKAGE_SECTION_SEUSER);
		if (put_entry(buf, sizeof(uint32_t), 1, file) != 1)
			return -1;
		if (write_helper(p->seusers, p->seusers_len, file))
			return -1;
		
	}
	if (p->user_extra) {
		buf[0] = cpu_to_le32(SEPOL_PACKAGE_SECTION_USER_EXTRA);
		if (put_entry(buf, sizeof(uint32_t), 1, file) != 1)
			return -1;
		if (write_helper(p->user_extra, p->user_extra_len, file))
			return -1;
	}
	return 0;
}