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