1#include <unistd.h>
2#include <sys/types.h>
3#include <fcntl.h>
4#include <stdlib.h>
5#include <stdio.h>
6#include <errno.h>
7#include <string.h>
8#include "selinux_internal.h"
9#include "policy.h"
10#include <limits.h>
11
12int security_canonicalize_context(const char * con,
13				      char ** canoncon)
14{
15	char path[PATH_MAX];
16	char *buf;
17	size_t size;
18	int fd, ret;
19
20	if (!selinux_mnt) {
21		errno = ENOENT;
22		return -1;
23	}
24
25	snprintf(path, sizeof path, "%s/context", selinux_mnt);
26	fd = open(path, O_RDWR);
27	if (fd < 0)
28		return -1;
29
30	size = selinux_page_size;
31	buf = malloc(size);
32	if (!buf) {
33		ret = -1;
34		goto out;
35	}
36	strncpy(buf, con, size);
37
38	ret = write(fd, buf, strlen(buf) + 1);
39	if (ret < 0)
40		goto out2;
41
42	memset(buf, 0, size);
43	ret = read(fd, buf, size - 1);
44	if (ret < 0 && errno == EINVAL) {
45		/* Fall back to the original context for kernels
46		   that do not support the extended interface. */
47		strncpy(buf, con, size);
48	}
49
50	*canoncon = strdup(buf);
51	if (!(*canoncon)) {
52		ret = -1;
53		goto out2;
54	}
55	ret = 0;
56      out2:
57	free(buf);
58      out:
59	close(fd);
60	return ret;
61}
62
63