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 len = snprintf(buf, size, "%s %s %hu",
79 scon, tcon, unmap_class(tclass));
80 if (objname &&
81 object_name_encode(objname, buf + len, size - len) < 0) {
82 errno = ENAMETOOLONG;
83 ret = -1;
84 goto out2;
85 }
86
87 ret = write(fd, buf, strlen(buf));
88 if (ret < 0)
89 goto out2;
90
91 memset(buf, 0, size);
92 ret = read(fd, buf, size - 1);
93 if (ret < 0)
94 goto out2;
95
96 *newcon = strdup(buf);
97 if (!(*newcon)) {
98 ret = -1;
99 goto out2;
100 }
101 ret = 0;
102 out2:
103 free(buf);
104 out:
105 close(fd);
106 return ret;
107 }
hidden_def(security_compute_create_name_raw)108 hidden_def(security_compute_create_name_raw)
109
110 int security_compute_create_raw(const char * scon,
111 const char * tcon,
112 security_class_t tclass,
113 char ** newcon)
114 {
115 return security_compute_create_name_raw(scon, tcon, tclass,
116 NULL, newcon);
117 }
hidden_def(security_compute_create_raw)118 hidden_def(security_compute_create_raw)
119
120 int security_compute_create_name(const char * scon,
121 const char * tcon,
122 security_class_t tclass,
123 const char *objname,
124 char ** newcon)
125 {
126 int ret;
127 char * rscon;
128 char * rtcon;
129 char * rnewcon;
130
131 if (selinux_trans_to_raw_context(scon, &rscon))
132 return -1;
133 if (selinux_trans_to_raw_context(tcon, &rtcon)) {
134 freecon(rscon);
135 return -1;
136 }
137
138 ret = security_compute_create_name_raw(rscon, rtcon, tclass,
139 objname, &rnewcon);
140 freecon(rscon);
141 freecon(rtcon);
142 if (!ret) {
143 ret = selinux_raw_to_trans_context(rnewcon, newcon);
144 freecon(rnewcon);
145 }
146
147 return ret;
148 }
hidden_def(security_compute_create_name)149 hidden_def(security_compute_create_name)
150
151 int security_compute_create(const char * scon,
152 const char * tcon,
153 security_class_t tclass,
154 char ** newcon)
155 {
156 return security_compute_create_name(scon, tcon, tclass, NULL, newcon);
157 }
158 hidden_def(security_compute_create)
159