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 <limits.h>
9#include "selinux_internal.h"
10#include "policy.h"
11#include "mapping.h"
12
13int security_compute_member_raw(const char * scon,
14				const char * tcon,
15				security_class_t tclass,
16				char ** newcon)
17{
18	char path[PATH_MAX];
19	char *buf;
20	size_t size;
21	int fd, ret;
22
23	if (!selinux_mnt) {
24		errno = ENOENT;
25		return -1;
26	}
27
28	snprintf(path, sizeof path, "%s/member", selinux_mnt);
29	fd = open(path, O_RDWR | O_CLOEXEC);
30	if (fd < 0)
31		return -1;
32
33	size = selinux_page_size;
34	buf = malloc(size);
35	if (!buf) {
36		ret = -1;
37		goto out;
38	}
39
40	ret = snprintf(buf, size, "%s %s %hu", scon, tcon, unmap_class(tclass));
41	if (ret < 0 || (size_t)ret >= size) {
42		errno = EOVERFLOW;
43		ret = -1;
44		goto out2;
45	}
46
47	ret = write(fd, buf, strlen(buf));
48	if (ret < 0)
49		goto out2;
50
51	memset(buf, 0, size);
52	ret = read(fd, buf, size - 1);
53	if (ret < 0)
54		goto out2;
55
56	*newcon = strdup(buf);
57	if (!(*newcon)) {
58		ret = -1;
59		goto out2;
60	}
61	ret = 0;
62      out2:
63	free(buf);
64      out:
65	close(fd);
66	return ret;
67}
68
69
70int security_compute_member(const char * scon,
71			    const char * tcon,
72			    security_class_t tclass,
73			    char ** newcon)
74{
75	int ret;
76	char * rscon;
77	char * rtcon;
78	char * rnewcon;
79
80	if (selinux_trans_to_raw_context(scon, &rscon))
81		return -1;
82	if (selinux_trans_to_raw_context(tcon, &rtcon)) {
83		freecon(rscon);
84		return -1;
85	}
86
87	ret = security_compute_member_raw(rscon, rtcon, tclass, &rnewcon);
88
89	freecon(rscon);
90	freecon(rtcon);
91	if (!ret) {
92		if (selinux_raw_to_trans_context(rnewcon, newcon)) {
93			*newcon = NULL;
94			ret = -1;
95		}
96		freecon(rnewcon);
97	}
98
99	return ret;
100}
101