示例#1
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);
        }
    }
}
示例#2
0
void label_finish(void) {

#ifdef HAVE_SELINUX
        if (use_selinux() && label_hnd)
                selabel_close(label_hnd);
#endif
}
示例#3
0
文件: selinux.c 项目: Tojaj/rpm
static void sehandle_fini(int close_status)
{
    if (sehandle) {
	selabel_close(sehandle);
	sehandle = NULL;
    }
    if (close_status) {
	selinux_status_close();
    }
}
示例#4
0
void mac_selinux_finish(void) {

#ifdef HAVE_SELINUX
        if (!label_hnd)
                return;

        selabel_close(label_hnd);
        label_hnd = NULL;
#endif
}
int selinux_reload_policy(void)
{
    if (!selinux_enabled) {
        return -1;
    }

    INFO("SELinux: Attempting to reload policy files\n");

    if (selinux_android_reload_policy() == -1) {
        return -1;
    }

    if (sehandle)
        selabel_close(sehandle);

    if (sehandle_prop)
        selabel_close(sehandle_prop);

    selinux_init_all_handles();
    return 0;
}
示例#6
0
文件: selinux.c 项目: guillemj/dpkg
void
dpkg_selabel_close(void)
{
#ifdef WITH_LIBSELINUX
	if (sehandle == NULL)
		return;

	selinux_status_close();
	selabel_close(sehandle);
	sehandle = NULL;
#endif
}
示例#7
0
/*
 * Close the label handle
 * returns 1 on success, 0 if no selinux, negative on error
 */
int selinux_util_close(void)
{
    int retval = 0;

    retval = is_selinux_enabled();
    if (retval <= 0)
        return retval;

    if (hnd) {
        selabel_close(hnd);
        hnd = NULL;
    }

    return 0;
}
示例#8
0
/* Set fcon to the appropriate label for path and mode, or return -1.  */
static int
getContext(const char *newpath, mode_t mode, security_context_t *fcon)
{
#if HAVE_SELINUX_LABEL_H
    struct selabel_handle *handle = selabel_open(SELABEL_CTX_FILE, NULL, 0);
    int ret;

    if (handle == NULL)
        return -1;

    ret = selabel_lookup(handle, fcon, newpath, mode);
    selabel_close(handle);
    return ret;
#else
    return matchpathcon(newpath, mode, fcon);
#endif
}
示例#9
0
static int format_ext4(char *fs_blkdev, char *fs_mnt_point, bool crypt_footer)
{
    uint64_t dev_sz;
    int fd, rc = 0;

    if ((fd = open(fs_blkdev, O_WRONLY)) < 0) {
        PERROR << "Cannot open block device";
        return -1;
    }

    if ((ioctl(fd, BLKGETSIZE64, &dev_sz)) == -1) {
        PERROR << "Cannot get block device size";
        close(fd);
        return -1;
    }

    struct selabel_handle *sehandle = selinux_android_file_context_handle();
    if (!sehandle) {
        /* libselinux logs specific error */
        LERROR << "Cannot initialize android file_contexts";
        close(fd);
        return -1;
    }

    /* Format the partition using the calculated length */
    reset_ext4fs_info();
    info.len = (off64_t)dev_sz;
    if (crypt_footer) {
        info.len -= CRYPT_FOOTER_OFFSET;
    }

    /* Use make_ext4fs_internal to avoid wiping an already-wiped partition. */
    rc = make_ext4fs_internal(fd, NULL, NULL, fs_mnt_point, 0, 0, 0, 0, 0, 0, sehandle, 0, 0, NULL, NULL, NULL);
    if (rc) {
        LERROR << "make_ext4fs returned " << rc;
    }
    close(fd);

    if (sehandle) {
        selabel_close(sehandle);
    }

    return rc;
}
示例#10
0
文件: selinux.c 项目: guillemj/dpkg
void
dpkg_selabel_load(void)
{
#ifdef WITH_LIBSELINUX
	static int selinux_enabled = -1;

	if (selinux_enabled < 0) {
		int rc;

		/* Set selinux_enabled if it is not already set (singleton). */
		selinux_enabled = (in_force(FORCE_SECURITY_MAC) &&
		                   is_selinux_enabled() > 0);
		if (!selinux_enabled)
			return;

		/* Open the SELinux status notification channel, with fallback
		 * enabled for older kernels. */
		rc = selinux_status_open(1);
		if (rc < 0)
			ohshit(_("cannot open security status notification channel"));

		/* XXX: We could use selinux_set_callback() to redirect the
		 * errors from the other SELinux calls, but that does not seem
		 * worth it right now. */
	} else if (selinux_enabled && selinux_status_updated()) {
		/* The SELinux policy got updated in the kernel, usually after
		 * upgrading the package shipping it, we need to reload. */
		selabel_close(sehandle);
	} else {
		/* SELinux is either disabled or it does not need a reload. */
		return;
	}

	sehandle = selabel_open(SELABEL_CTX_FILE, NULL, 0);
	if (sehandle == NULL && security_getenforce() == 1)
		ohshite(_("cannot get security labeling handle"));
#endif
}
示例#11
0
int main(int argc, char **argv)
{
	int backend = 0, rc, opt, validate = 0;
	char *baseonly = NULL, *file = NULL, *digest = (char *)1;
	char **specfiles = NULL;
	unsigned char *sha1_digest = NULL;
	size_t i, num_specfiles;

	char cmd_buf[4096];
	char *cmd_ptr;
	char *sha1_buf;

	struct selabel_handle *hnd;
	struct selinux_opt selabel_option[] = {
		{ SELABEL_OPT_PATH, file },
		{ SELABEL_OPT_BASEONLY, baseonly },
		{ SELABEL_OPT_DIGEST, digest }
	};

	if (argc < 3)
		usage(argv[0]);

	while ((opt = getopt(argc, argv, "ib:Bvf:")) > 0) {
		switch (opt) {
		case 'b':
			if (!strcasecmp(optarg, "file")) {
				backend = SELABEL_CTX_FILE;
			} else if (!strcmp(optarg, "media")) {
				backend = SELABEL_CTX_MEDIA;
			} else if (!strcmp(optarg, "x")) {
				backend = SELABEL_CTX_X;
			} else if (!strcmp(optarg, "db")) {
				backend = SELABEL_CTX_DB;
			} else if (!strcmp(optarg, "prop")) {
				backend = SELABEL_CTX_ANDROID_PROP;
			} else if (!strcmp(optarg, "service")) {
				backend = SELABEL_CTX_ANDROID_SERVICE;
			} else {
				fprintf(stderr, "Unknown backend: %s\n",
								    optarg);
				usage(argv[0]);
			}
			break;
		case 'B':
			baseonly = (char *)1;
			break;
		case 'v':
			validate = 1;
			break;
		case 'i':
			digest = NULL;
			break;
		case 'f':
			file = optarg;
			break;
		default:
			usage(argv[0]);
		}
	}

	memset(cmd_buf, 0, sizeof(cmd_buf));

	selabel_option[0].value = file;
	selabel_option[1].value = baseonly;
	selabel_option[2].value = digest;

	hnd = selabel_open(backend, selabel_option, 3);
	if (!hnd) {
		switch (errno) {
		case EOVERFLOW:
			fprintf(stderr, "ERROR Number of specfiles or specfile"
					" buffer caused an overflow.\n");
			break;
		default:
			fprintf(stderr, "ERROR: selabel_open: %s\n",
						    strerror(errno));
		}
		return -1;
	}

	rc = selabel_digest(hnd, &sha1_digest, &digest_len, &specfiles,
							    &num_specfiles);

	if (rc) {
		switch (errno) {
		case EINVAL:
			fprintf(stderr, "No digest available.\n");
			break;
		default:
			fprintf(stderr, "selabel_digest ERROR: %s\n",
						    strerror(errno));
		}
		goto err;
	}

	sha1_buf = malloc(digest_len * 2 + 1);
	if (!sha1_buf) {
		fprintf(stderr, "Could not malloc buffer ERROR: %s\n",
						    strerror(errno));
		rc = -1;
		goto err;
	}

	printf("SHA1 digest: ");
	for (i = 0; i < digest_len; i++)
		sprintf(&(sha1_buf[i * 2]), "%02x", sha1_digest[i]);

	printf("%s\n", sha1_buf);
	printf("calculated using the following specfile(s):\n");

	if (specfiles) {
		cmd_ptr = &cmd_buf[0];
		sprintf(cmd_ptr, "/usr/bin/cat ");
		cmd_ptr = &cmd_buf[0] + strlen(cmd_buf);

		for (i = 0; i < num_specfiles; i++) {
			sprintf(cmd_ptr, "%s ", specfiles[i]);
			cmd_ptr += strlen(specfiles[i]) + 1;
			printf("%s\n", specfiles[i]);
		}
		sprintf(cmd_ptr, "| /usr/bin/openssl dgst -sha1 -hex");

		if (validate)
			rc = run_check_digest(cmd_buf, sha1_buf);
	}

	free(sha1_buf);
err:
	selabel_close(hnd);
	return rc;
}
int svcmgr_handler(struct binder_state *bs,
                   struct binder_transaction_data *txn,
                   struct binder_io *msg,
                   struct binder_io *reply)
{
    struct svcinfo *si;
    uint16_t *s;
    size_t len;
    uint32_t handle;
    uint32_t strict_policy;
    int allow_isolated;

    //ALOGI("target=%p code=%d pid=%d uid=%d\n",
    //      (void*) txn->target.ptr, txn->code, txn->sender_pid, txn->sender_euid);

    if (txn->target.ptr != BINDER_SERVICE_MANAGER)
        return -1;

    if (txn->code == PING_TRANSACTION)
        return 0;

    // Equivalent to Parcel::enforceInterface(), reading the RPC
    // header with the strict mode policy mask and the interface name.
    // Note that we ignore the strict_policy and don't propagate it
    // further (since we do no outbound RPCs anyway).
    strict_policy = bio_get_uint32(msg);
    s = bio_get_string16(msg, &len);
    if (s == NULL) {
        return -1;
    }

    if ((len != (sizeof(svcmgr_id) / 2)) ||
        memcmp(svcmgr_id, s, sizeof(svcmgr_id))) {
        fprintf(stderr,"invalid id %s\n", str8(s, len));
        return -1;
    }

    if (sehandle && selinux_status_updated() > 0) {
        struct selabel_handle *tmp_sehandle = selinux_android_service_context_handle();
        if (tmp_sehandle) {
            selabel_close(sehandle);
            sehandle = tmp_sehandle;
        }
    }

    switch(txn->code) {
    case SVC_MGR_GET_SERVICE:
    case SVC_MGR_CHECK_SERVICE:
        s = bio_get_string16(msg, &len);
        if (s == NULL) {
            return -1;
        }
        handle = do_find_service(bs, s, len, txn->sender_euid, txn->sender_pid);
        if (!handle)
            break;
        bio_put_ref(reply, handle);
        return 0;

    case SVC_MGR_ADD_SERVICE:
        s = bio_get_string16(msg, &len);
        if (s == NULL) {
            return -1;
        }
        handle = bio_get_ref(msg);
        allow_isolated = bio_get_uint32(msg) ? 1 : 0;
        if (do_add_service(bs, s, len, handle, txn->sender_euid,
            allow_isolated, txn->sender_pid))
            return -1;
        break;

    case SVC_MGR_LIST_SERVICES: {
        uint32_t n = bio_get_uint32(msg);

        if (!svc_can_list(txn->sender_pid, txn->sender_euid)) {
            ALOGE("list_service() uid=%d - PERMISSION DENIED\n",
                    txn->sender_euid);
            return -1;
        }
        si = svclist;
        while ((n-- > 0) && si)
            si = si->next;
        if (si) {
            bio_put_string16(reply, si->name);
            return 0;
        }
        return -1;
    }
    default:
        ALOGE("unknown code %d\n", txn->code);
        return -1;
    }

    bio_put_uint32(reply, 0);
    return 0;
}
示例#13
0
Datum
sepgsql_restorecon(PG_FUNCTION_ARGS)
{
	struct selabel_handle  *sehnd;
	struct selinux_opt		seopts;

	/*
	 * SELinux has to be enabled on the running platform.
	 */
	if (!sepgsql_is_enabled())
		ereport(ERROR,
				(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
				 errmsg("sepgsql is not currently enabled")));
	/*
	 * Check DAC permission. Only superuser can set up initial
	 * security labels, like root-user in filesystems
	 */
	if (!superuser())
		ereport(ERROR,
				(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
				 errmsg("SELinux: must be superuser to restore initial contexts")));

	/*
	 * Open selabel_lookup(3) stuff. It provides a set of mapping
	 * between an initial security label and object class/name due
	 * to the system setting.
	 */
	if (PG_ARGISNULL(0))
	{
		seopts.type = SELABEL_OPT_UNUSED;
		seopts.value = NULL;
	}
	else
	{
		seopts.type = SELABEL_OPT_PATH;
		seopts.value = TextDatumGetCString(PG_GETARG_DATUM(0));
	}
	sehnd = selabel_open(SELABEL_CTX_DB, &seopts, 1);
	if (!sehnd)
		ereport(ERROR,
				(errcode(ERRCODE_INTERNAL_ERROR),
				 errmsg("SELinux: failed to initialize labeling handle: %m")));
	PG_TRY();
	{
		/*
		 * Right now, we have no support labeling on the shared
		 * database objects, such as database, role, or tablespace.
		 */
		exec_object_restorecon(sehnd, NamespaceRelationId);
		exec_object_restorecon(sehnd, RelationRelationId);
		exec_object_restorecon(sehnd, AttributeRelationId);
		exec_object_restorecon(sehnd, ProcedureRelationId);
	}
	PG_CATCH();
	{
		selabel_close(sehnd);
		PG_RE_THROW();
	}
	PG_END_TRY();	

	selabel_close(sehnd);

	PG_RETURN_BOOL(true);
}
示例#14
0
文件: setfiles.c 项目: mgrepl/selinux
int main(int argc, char **argv)
{
	struct stat sb;
	int opt, i = 0;
	const char *input_filename = NULL;
	int use_input_file = 0;
	char *buf = NULL;
	size_t buf_len;
	int recurse; /* Recursive descent. */
	const char *base;
	int mass_relabel = 0, errors = 0;
	const char *ropts = "e:f:hilno:pqrsvFRW0";
	const char *sopts = "c:de:f:hilno:pqr:svFR:W0";
	const char *opts;
	
	memset(&r_opts, 0, sizeof(r_opts));

	/* Initialize variables */
	r_opts.progress = 0;
	r_opts.count = 0;
	r_opts.nfile = 0;
	r_opts.debug = 0;
	r_opts.change = 1;
	r_opts.verbose = 0;
	r_opts.logging = 0;
	r_opts.rootpath = NULL;
	r_opts.rootpathlen = 0;
	r_opts.outfile = NULL;
	r_opts.force = 0;
	r_opts.hard_links = 1;

	altpath = NULL;

	r_opts.progname = strdup(argv[0]);
	if (!r_opts.progname) {
		fprintf(stderr, "%s:  Out of memory!\n", argv[0]);
		exit(-1);
	}
	base = basename(r_opts.progname);
	
	if (!strcmp(base, SETFILES)) {
		/* 
		 * setfiles:  
		 * Recursive descent,
		 * Does not expand paths via realpath, 
		 * Aborts on errors during the file tree walk, 
		 * Try to track inode associations for conflict detection,
		 * Does not follow mounts,
		 * Validates all file contexts at init time. 
		 */
		iamrestorecon = 0;
		recurse = 1;
		r_opts.expand_realpath = 0;
		r_opts.abort_on_error = 1;
		r_opts.add_assoc = 1;
		r_opts.fts_flags = FTS_PHYSICAL | FTS_XDEV;
		ctx_validate = 1;
		opts = sopts;
	} else {
		/*
		 * restorecon:  
		 * No recursive descent unless -r/-R,
		 * Expands paths via realpath, 
		 * Do not abort on errors during the file tree walk,
		 * Do not try to track inode associations for conflict detection,
		 * Follows mounts,
		 * Does lazy validation of contexts upon use. 
		 */
		if (strcmp(base, RESTORECON) && !r_opts.quiet) 
			printf("Executed with an unrecognized name (%s), defaulting to %s behavior.\n", base, RESTORECON);
		iamrestorecon = 1;
		recurse = 0;
		r_opts.expand_realpath = 1;
		r_opts.abort_on_error = 0;
		r_opts.add_assoc = 0;
		r_opts.fts_flags = FTS_PHYSICAL;
		ctx_validate = 0;
		opts = ropts;

		/* restorecon only:  silent exit if no SELinux.
		   Allows unconditional execution by scripts. */
		if (is_selinux_enabled() <= 0)
			exit(0);
	}

	/* This must happen before getopt. */
	r_opts.nfile = exclude_non_seclabel_mounts();

	if (iamrestorecon) 
		opts = ropts;
	else
		opts = sopts;
		
	/* Process any options. */
	while ((opt = getopt(argc, argv, opts)) > 0) {
		switch (opt) {
		case 'c':
			{
				FILE *policystream;

				if (iamrestorecon)
					usage(argv[0]);

				policyfile = optarg;

				policystream = fopen(policyfile, "r");
				if (!policystream) {
					fprintf(stderr,
						"Error opening %s: %s\n",
						policyfile, strerror(errno));
					exit(-1);
				}
				__fsetlocking(policystream,
					      FSETLOCKING_BYCALLER);

				if (sepol_set_policydb_from_file(policystream) <
				    0) {
					fprintf(stderr,
						"Error reading policy %s: %s\n",
						policyfile, strerror(errno));
					exit(-1);
				}
				fclose(policystream);

				ctx_validate = 1;

				break;
			}
		case 'e':
			remove_exclude(optarg);
			if (lstat(optarg, &sb) < 0 && errno != EACCES) {
				fprintf(stderr, "Can't stat exclude path \"%s\", %s - ignoring.\n",
					optarg, strerror(errno));
				break;
			}
			if (add_exclude(optarg))
				exit(-1);
			break;
		case 'f':
			use_input_file = 1;
			input_filename = optarg;
			break;			
		case 'd':
			if (iamrestorecon)
				usage(argv[0]);
			r_opts.debug = 1;
			break;
		case 'i':
			r_opts.ignore_enoent = 1;
			break;
		case 'l':
			r_opts.logging = 1;
			break;
		case 'F':
			r_opts.force = 1;
			break;
		case 'n':
			r_opts.change = 0;
			break;
		case 'o':
			if (strcmp(optarg, "-") == 0) {
				r_opts.outfile = stdout;
				break;
			}

			r_opts.outfile = fopen(optarg, "w");
			if (!r_opts.outfile) {
				fprintf(stderr, "Error opening %s: %s\n",
					optarg, strerror(errno));

				usage(argv[0]);
			}
			__fsetlocking(r_opts.outfile, FSETLOCKING_BYCALLER);
			break;
		case 'q':
			r_opts.quiet = 1;
			break;
		case 'R':
		case 'r':
			if (iamrestorecon) {
				recurse = 1;
				break;
			}
			if (NULL != r_opts.rootpath) {
				fprintf(stderr,
					"%s: only one -r can be specified\n",
					argv[0]);
				exit(-1);
			}
			set_rootpath(optarg);
			break;
		case 's':
			use_input_file = 1;
			input_filename = "-";
			r_opts.add_assoc = 0;
			break;
		case 'v':
			if (r_opts.progress) {
				fprintf(stderr,
					"Progress and Verbose mutually exclusive\n");
				usage(argv[0]);
			}
			r_opts.verbose++;
			break;
		case 'p':
			if (r_opts.verbose) {
				fprintf(stderr,
					"Progress and Verbose mutually exclusive\n");
				usage(argv[0]);
			}
			r_opts.progress++;
			break;
		case 'W':
			warn_no_match = 1;
			break;
		case '0':
			null_terminated = 1;
			break;
		case 'h':
		case '?':
			usage(argv[0]);
		}
	}

	for (i = optind; i < argc; i++) {
		if (!strcmp(argv[i], "/")) {
			mass_relabel = 1;
			if (r_opts.progress)
				r_opts.progress++;
		}
	}

	if (!iamrestorecon) {
		if (policyfile) {
			if (optind != (argc - 1))
				usage(argv[0]);
		} else if (use_input_file) {
			if (optind != (argc - 1)) {
				/* Cannot mix with pathname arguments. */
				usage(argv[0]);
			}
		} else {
			if (optind > (argc - 2))
				usage(argv[0]);
		}

		/* Use our own invalid context checking function so that
		   we can support either checking against the active policy or
		   checking against a binary policy file. */
		selinux_set_callback(SELINUX_CB_VALIDATE,
				     (union selinux_callback)&canoncon);

		if (stat(argv[optind], &sb) < 0) {
			perror(argv[optind]);
			exit(-1);
		}
		if (!S_ISREG(sb.st_mode)) {
			fprintf(stderr, "%s:  spec file %s is not a regular file.\n",
				argv[0], argv[optind]);
			exit(-1);
		}

		altpath = argv[optind];
		optind++;
	} else if (argc == 1)
		usage(argv[0]);

	/* Load the file contexts configuration and check it. */
	r_opts.selabel_opt_validate = (ctx_validate ? (char *)1 : NULL);
	r_opts.selabel_opt_path = altpath;

	if (nerr)
		exit(-1);

	restore_init(&r_opts);
	if (use_input_file) {
		FILE *f = stdin;
		ssize_t len;
		int delim;
		if (strcmp(input_filename, "-") != 0)
			f = fopen(input_filename, "r");
		if (f == NULL) {
			fprintf(stderr, "Unable to open %s: %s\n", input_filename,
				strerror(errno));
			usage(argv[0]);
		}
		__fsetlocking(f, FSETLOCKING_BYCALLER);

		delim = (null_terminated != 0) ? '\0' : '\n';
		while ((len = getdelim(&buf, &buf_len, delim, f)) > 0) {
			buf[len - 1] = 0;
			if (!strcmp(buf, "/"))
				mass_relabel = 1;
			errors |= process_glob(buf, recurse) < 0;
		}
		if (strcmp(input_filename, "-") != 0)
			fclose(f);
	} else {
		for (i = optind; i < argc; i++)
			errors |= process_glob(argv[i], recurse) < 0;
	}
	
	maybe_audit_mass_relabel(mass_relabel, errors);

	if (warn_no_match)
		selabel_stats(r_opts.hnd);

	selabel_close(r_opts.hnd);
	restore_finish();

	if (r_opts.outfile)
		fclose(r_opts.outfile);

	if (r_opts.progress && r_opts.count >= STAR_COUNT)
		printf("\n");
	exit(errors ? -1: 0);
}