16cd6a6acSopenharmony_ci#include <unistd.h>
26cd6a6acSopenharmony_ci#include <sys/types.h>
36cd6a6acSopenharmony_ci#include <fcntl.h>
46cd6a6acSopenharmony_ci#include <stdlib.h>
56cd6a6acSopenharmony_ci#include <stdio.h>
66cd6a6acSopenharmony_ci#include <errno.h>
76cd6a6acSopenharmony_ci#include <string.h>
86cd6a6acSopenharmony_ci#include "selinux_internal.h"
96cd6a6acSopenharmony_ci#include "policy.h"
106cd6a6acSopenharmony_ci#include <limits.h>
116cd6a6acSopenharmony_ci
126cd6a6acSopenharmony_ci#define SELINUX_INITCON_DIR "/initial_contexts/"
136cd6a6acSopenharmony_ci
146cd6a6acSopenharmony_ciint security_get_initial_context_raw(const char * name, char ** con)
156cd6a6acSopenharmony_ci{
166cd6a6acSopenharmony_ci	char path[PATH_MAX];
176cd6a6acSopenharmony_ci	char *buf;
186cd6a6acSopenharmony_ci	size_t size;
196cd6a6acSopenharmony_ci	int fd, ret;
206cd6a6acSopenharmony_ci
216cd6a6acSopenharmony_ci	if (!selinux_mnt) {
226cd6a6acSopenharmony_ci		errno = ENOENT;
236cd6a6acSopenharmony_ci		return -1;
246cd6a6acSopenharmony_ci	}
256cd6a6acSopenharmony_ci
266cd6a6acSopenharmony_ci	if (strchr(name, '/')) {
276cd6a6acSopenharmony_ci		errno = EINVAL;
286cd6a6acSopenharmony_ci		return -1;
296cd6a6acSopenharmony_ci	}
306cd6a6acSopenharmony_ci
316cd6a6acSopenharmony_ci	ret = snprintf(path, sizeof path, "%s%s%s", selinux_mnt, SELINUX_INITCON_DIR, name);
326cd6a6acSopenharmony_ci	if (ret < 0 || (size_t)ret >= sizeof path) {
336cd6a6acSopenharmony_ci		errno = EOVERFLOW;
346cd6a6acSopenharmony_ci		return -1;
356cd6a6acSopenharmony_ci	}
366cd6a6acSopenharmony_ci
376cd6a6acSopenharmony_ci	fd = open(path, O_RDONLY | O_CLOEXEC);
386cd6a6acSopenharmony_ci	if (fd < 0)
396cd6a6acSopenharmony_ci		return -1;
406cd6a6acSopenharmony_ci
416cd6a6acSopenharmony_ci	size = selinux_page_size;
426cd6a6acSopenharmony_ci	buf = malloc(size);
436cd6a6acSopenharmony_ci	if (!buf) {
446cd6a6acSopenharmony_ci		ret = -1;
456cd6a6acSopenharmony_ci		goto out;
466cd6a6acSopenharmony_ci	}
476cd6a6acSopenharmony_ci	memset(buf, 0, size);
486cd6a6acSopenharmony_ci	ret = read(fd, buf, size - 1);
496cd6a6acSopenharmony_ci	if (ret < 0)
506cd6a6acSopenharmony_ci		goto out2;
516cd6a6acSopenharmony_ci
526cd6a6acSopenharmony_ci	*con = strdup(buf);
536cd6a6acSopenharmony_ci	if (!(*con)) {
546cd6a6acSopenharmony_ci		ret = -1;
556cd6a6acSopenharmony_ci		goto out2;
566cd6a6acSopenharmony_ci	}
576cd6a6acSopenharmony_ci	ret = 0;
586cd6a6acSopenharmony_ci      out2:
596cd6a6acSopenharmony_ci	free(buf);
606cd6a6acSopenharmony_ci      out:
616cd6a6acSopenharmony_ci	close(fd);
626cd6a6acSopenharmony_ci	return ret;
636cd6a6acSopenharmony_ci}
646cd6a6acSopenharmony_ci
656cd6a6acSopenharmony_ci
666cd6a6acSopenharmony_ciint security_get_initial_context(const char * name, char ** con)
676cd6a6acSopenharmony_ci{
686cd6a6acSopenharmony_ci	int ret;
696cd6a6acSopenharmony_ci	char * rcon;
706cd6a6acSopenharmony_ci
716cd6a6acSopenharmony_ci	ret = security_get_initial_context_raw(name, &rcon);
726cd6a6acSopenharmony_ci	if (!ret) {
736cd6a6acSopenharmony_ci		ret = selinux_raw_to_trans_context(rcon, con);
746cd6a6acSopenharmony_ci		freecon(rcon);
756cd6a6acSopenharmony_ci	}
766cd6a6acSopenharmony_ci
776cd6a6acSopenharmony_ci	return ret;
786cd6a6acSopenharmony_ci}
796cd6a6acSopenharmony_ci
80