• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <ctype.h>
10 #include "selinux_internal.h"
11 #include "policy.h"
12 #include "mapping.h"
13 
object_name_encode(const char * objname,char * buffer,size_t buflen)14 static int object_name_encode(const char *objname, char *buffer, size_t buflen)
15 {
16 	int	code;
17 	size_t	offset = 0;
18 
19 	if (buflen - offset < 1)
20 		return -1;
21 	buffer[offset++] = ' ';
22 
23 	do {
24 		code = *objname++;
25 
26 		if (isalnum(code) || code == '\0' || code == '-' ||
27 		    code == '.' || code == '_' || code == '~') {
28 			if (buflen - offset < 1)
29 				return -1;
30 			buffer[offset++] = code;
31 		} else if (code == ' ') {
32 			if (buflen - offset < 1)
33 				return -1;
34 			buffer[offset++] = '+';
35 		} else {
36 			static const char *table = "0123456789ABCDEF";
37 			int	l = (code & 0x0f);
38 			int	h = (code & 0xf0) >> 4;
39 
40 			if (buflen - offset < 3)
41 				return -1;
42 			buffer[offset++] = '%';
43 			buffer[offset++] = table[h];
44 			buffer[offset++] = table[l];
45 		}
46 	} while (code != '\0');
47 
48 	return 0;
49 }
50 
security_compute_create_name_raw(const char * scon,const char * tcon,security_class_t tclass,const char * objname,char ** newcon)51 int security_compute_create_name_raw(const char * scon,
52 				     const char * tcon,
53 				     security_class_t tclass,
54 				     const char *objname,
55 				     char ** newcon)
56 {
57 	char path[PATH_MAX];
58 	char *buf;
59 	size_t size;
60 	int fd, ret, len;
61 
62 	if (!selinux_mnt) {
63 		errno = ENOENT;
64 		return -1;
65 	}
66 
67 	snprintf(path, sizeof path, "%s/create", selinux_mnt);
68 	fd = open(path, O_RDWR | O_CLOEXEC);
69 	if (fd < 0)
70 		return -1;
71 
72 	size = selinux_page_size;
73 	buf = malloc(size);
74 	if (!buf) {
75 		ret = -1;
76 		goto out;
77 	}
78 
79 	len = snprintf(buf, size, "%s %s %hu",
80 		       scon, tcon, unmap_class(tclass));
81 	if (len < 0 || (size_t)len >= size) {
82 		errno = EOVERFLOW;
83 		ret = -1;
84 		goto out2;
85 	}
86 
87 	if (objname &&
88 	    object_name_encode(objname, buf + len, size - len) < 0) {
89 		errno = ENAMETOOLONG;
90 		ret = -1;
91 		goto out2;
92 	}
93 
94 	ret = write(fd, buf, strlen(buf));
95 	if (ret < 0)
96 		goto out2;
97 
98 	memset(buf, 0, size);
99 	ret = read(fd, buf, size - 1);
100 	if (ret < 0)
101 		goto out2;
102 
103 	*newcon = strdup(buf);
104 	if (!(*newcon)) {
105 		ret = -1;
106 		goto out2;
107 	}
108 	ret = 0;
109       out2:
110 	free(buf);
111       out:
112 	close(fd);
113 	return ret;
114 }
115 
security_compute_create_raw(const char * scon,const char * tcon,security_class_t tclass,char ** newcon)116 int security_compute_create_raw(const char * scon,
117 				const char * tcon,
118 				security_class_t tclass,
119 				char ** newcon)
120 {
121 	return security_compute_create_name_raw(scon, tcon, tclass,
122 						NULL, newcon);
123 }
124 
security_compute_create_name(const char * scon,const char * tcon,security_class_t tclass,const char * objname,char ** newcon)125 int security_compute_create_name(const char * scon,
126 				 const char * tcon,
127 				 security_class_t tclass,
128 				 const char *objname,
129 				 char ** newcon)
130 {
131 	int ret;
132 	char * rscon;
133 	char * rtcon;
134 	char * rnewcon;
135 
136 	if (selinux_trans_to_raw_context(scon, &rscon))
137 		return -1;
138 	if (selinux_trans_to_raw_context(tcon, &rtcon)) {
139 		freecon(rscon);
140 		return -1;
141 	}
142 
143 	ret = security_compute_create_name_raw(rscon, rtcon, tclass,
144 					       objname, &rnewcon);
145 	freecon(rscon);
146 	freecon(rtcon);
147 	if (!ret) {
148 		ret = selinux_raw_to_trans_context(rnewcon, newcon);
149 		freecon(rnewcon);
150 	}
151 
152 	return ret;
153 }
154 
security_compute_create(const char * scon,const char * tcon,security_class_t tclass,char ** newcon)155 int security_compute_create(const char * scon,
156 				const char * tcon,
157 			    security_class_t tclass,
158 				char ** newcon)
159 {
160 	return security_compute_create_name(scon, tcon, tclass, NULL, newcon);
161 }
162