Branch data Line data Source code
1 : : /* SPDX-License-Identifier: LGPL-2.1+ */
2 : : /***
3 : : Copyright © 2013 Intel Corporation
4 : :
5 : : Author: Auke Kok <auke-jan.h.kok@intel.com>
6 : : ***/
7 : :
8 : : #include <errno.h>
9 : : #include <fcntl.h>
10 : : #include <string.h>
11 : : #include <sys/stat.h>
12 : : #include <sys/xattr.h>
13 : : #include <unistd.h>
14 : :
15 : : #include "alloc-util.h"
16 : : #include "fd-util.h"
17 : : #include "fileio.h"
18 : : #include "log.h"
19 : : #include "macro.h"
20 : : #include "path-util.h"
21 : : #include "process-util.h"
22 : : #include "smack-util.h"
23 : : #include "stdio-util.h"
24 : : #include "string-table.h"
25 : : #include "xattr-util.h"
26 : :
27 : : #if ENABLE_SMACK
28 : 248 : bool mac_smack_use(void) {
29 : : static int cached_use = -1;
30 : :
31 [ + + ]: 248 : if (cached_use < 0)
32 : 184 : cached_use = access("/sys/fs/smackfs/", F_OK) >= 0;
33 : :
34 : 248 : return cached_use;
35 : : }
36 : :
37 : : static const char* const smack_attr_table[_SMACK_ATTR_MAX] = {
38 : : [SMACK_ATTR_ACCESS] = "security.SMACK64",
39 : : [SMACK_ATTR_EXEC] = "security.SMACK64EXEC",
40 : : [SMACK_ATTR_MMAP] = "security.SMACK64MMAP",
41 : : [SMACK_ATTR_TRANSMUTE] = "security.SMACK64TRANSMUTE",
42 : : [SMACK_ATTR_IPIN] = "security.SMACK64IPIN",
43 : : [SMACK_ATTR_IPOUT] = "security.SMACK64IPOUT",
44 : : };
45 : :
46 [ # # # # ]: 0 : DEFINE_STRING_TABLE_LOOKUP(smack_attr, SmackAttr);
47 : :
48 : 0 : int mac_smack_read(const char *path, SmackAttr attr, char **label) {
49 [ # # ]: 0 : assert(path);
50 [ # # # # ]: 0 : assert(attr >= 0 && attr < _SMACK_ATTR_MAX);
51 [ # # ]: 0 : assert(label);
52 : :
53 [ # # ]: 0 : if (!mac_smack_use())
54 : 0 : return 0;
55 : :
56 : 0 : return getxattr_malloc(path, smack_attr_to_string(attr), label, true);
57 : : }
58 : :
59 : 0 : int mac_smack_read_fd(int fd, SmackAttr attr, char **label) {
60 [ # # ]: 0 : assert(fd >= 0);
61 [ # # # # ]: 0 : assert(attr >= 0 && attr < _SMACK_ATTR_MAX);
62 [ # # ]: 0 : assert(label);
63 : :
64 [ # # ]: 0 : if (!mac_smack_use())
65 : 0 : return 0;
66 : :
67 : 0 : return fgetxattr_malloc(fd, smack_attr_to_string(attr), label);
68 : : }
69 : :
70 : 0 : int mac_smack_apply(const char *path, SmackAttr attr, const char *label) {
71 : : int r;
72 : :
73 [ # # ]: 0 : assert(path);
74 [ # # # # ]: 0 : assert(attr >= 0 && attr < _SMACK_ATTR_MAX);
75 : :
76 [ # # ]: 0 : if (!mac_smack_use())
77 : 0 : return 0;
78 : :
79 [ # # ]: 0 : if (label)
80 : 0 : r = lsetxattr(path, smack_attr_to_string(attr), label, strlen(label), 0);
81 : : else
82 : 0 : r = lremovexattr(path, smack_attr_to_string(attr));
83 [ # # ]: 0 : if (r < 0)
84 : 0 : return -errno;
85 : :
86 : 0 : return 0;
87 : : }
88 : :
89 : 0 : int mac_smack_apply_fd(int fd, SmackAttr attr, const char *label) {
90 : : int r;
91 : :
92 [ # # ]: 0 : assert(fd >= 0);
93 [ # # # # ]: 0 : assert(attr >= 0 && attr < _SMACK_ATTR_MAX);
94 : :
95 [ # # ]: 0 : if (!mac_smack_use())
96 : 0 : return 0;
97 : :
98 [ # # ]: 0 : if (label)
99 : 0 : r = fsetxattr(fd, smack_attr_to_string(attr), label, strlen(label), 0);
100 : : else
101 : 0 : r = fremovexattr(fd, smack_attr_to_string(attr));
102 [ # # ]: 0 : if (r < 0)
103 : 0 : return -errno;
104 : :
105 : 0 : return 0;
106 : : }
107 : :
108 : 0 : int mac_smack_apply_pid(pid_t pid, const char *label) {
109 : : const char *p;
110 : 0 : int r = 0;
111 : :
112 [ # # ]: 0 : assert(label);
113 : :
114 [ # # ]: 0 : if (!mac_smack_use())
115 : 0 : return 0;
116 : :
117 [ # # # # : 0 : p = procfs_file_alloca(pid, "attr/current");
# # ]
118 : 0 : r = write_string_file(p, label, WRITE_STRING_FILE_DISABLE_BUFFER);
119 [ # # ]: 0 : if (r < 0)
120 : 0 : return r;
121 : :
122 : 0 : return r;
123 : : }
124 : :
125 : 0 : static int smack_fix_fd(int fd , const char *abspath, LabelFixFlags flags) {
126 : : char procfs_path[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(int)];
127 : : const char *label;
128 : : struct stat st;
129 : : int r;
130 : :
131 : : /* The caller should have done the sanity checks. */
132 [ # # ]: 0 : assert(abspath);
133 [ # # ]: 0 : assert(path_is_absolute(abspath));
134 : :
135 : : /* Path must be in /dev. */
136 [ # # ]: 0 : if (!path_startswith(abspath, "/dev"))
137 : 0 : return 0;
138 : :
139 [ # # ]: 0 : if (fstat(fd, &st) < 0)
140 : 0 : return -errno;
141 : :
142 : : /*
143 : : * Label directories and character devices "*".
144 : : * Label symlinks "_".
145 : : * Don't change anything else.
146 : : */
147 : :
148 [ # # ]: 0 : if (S_ISDIR(st.st_mode))
149 : 0 : label = SMACK_STAR_LABEL;
150 [ # # ]: 0 : else if (S_ISLNK(st.st_mode))
151 : 0 : label = SMACK_FLOOR_LABEL;
152 [ # # ]: 0 : else if (S_ISCHR(st.st_mode))
153 : 0 : label = SMACK_STAR_LABEL;
154 : : else
155 : 0 : return 0;
156 : :
157 [ # # ]: 0 : xsprintf(procfs_path, "/proc/self/fd/%i", fd);
158 [ # # ]: 0 : if (setxattr(procfs_path, "security.SMACK64", label, strlen(label), 0) < 0) {
159 : 0 : _cleanup_free_ char *old_label = NULL;
160 : :
161 : 0 : r = -errno;
162 : :
163 : : /* If the FS doesn't support labels, then exit without warning */
164 [ # # ]: 0 : if (r == -EOPNOTSUPP)
165 : 0 : return 0;
166 : :
167 : : /* It the FS is read-only and we were told to ignore failures caused by that, suppress error */
168 [ # # # # ]: 0 : if (r == -EROFS && (flags & LABEL_IGNORE_EROFS))
169 : 0 : return 0;
170 : :
171 : : /* If the old label is identical to the new one, suppress any kind of error */
172 [ # # ]: 0 : if (getxattr_malloc(procfs_path, "security.SMACK64", &old_label, false) >= 0 &&
173 [ # # ]: 0 : streq(old_label, label))
174 : 0 : return 0;
175 : :
176 [ # # ]: 0 : return log_debug_errno(r, "Unable to fix SMACK label of %s: %m", abspath);
177 : : }
178 : :
179 : 0 : return 0;
180 : : }
181 : :
182 : 0 : int mac_smack_fix_at(int dirfd, const char *path, LabelFixFlags flags) {
183 : 0 : _cleanup_free_ char *p = NULL;
184 : 0 : _cleanup_close_ int fd = -1;
185 : : int r;
186 : :
187 [ # # ]: 0 : assert(path);
188 : :
189 [ # # ]: 0 : if (!mac_smack_use())
190 : 0 : return 0;
191 : :
192 : 0 : fd = openat(dirfd, path, O_NOFOLLOW|O_CLOEXEC|O_PATH);
193 [ # # ]: 0 : if (fd < 0) {
194 [ # # # # ]: 0 : if ((flags & LABEL_IGNORE_ENOENT) && errno == ENOENT)
195 : 0 : return 0;
196 : :
197 : 0 : return -errno;
198 : : }
199 : :
200 [ # # ]: 0 : if (!path_is_absolute(path)) {
201 : 0 : r = fd_get_path(fd, &p);
202 [ # # ]: 0 : if (r < 0)
203 : 0 : return r;
204 : 0 : path = p;
205 : : }
206 : :
207 : 0 : return smack_fix_fd(fd, path, flags);
208 : : }
209 : :
210 : 236 : int mac_smack_fix(const char *path, LabelFixFlags flags) {
211 : 236 : _cleanup_free_ char *abspath = NULL;
212 : 236 : _cleanup_close_ int fd = -1;
213 : : int r;
214 : :
215 [ - + ]: 236 : assert(path);
216 : :
217 [ + - ]: 236 : if (!mac_smack_use())
218 : 236 : return 0;
219 : :
220 : 0 : r = path_make_absolute_cwd(path, &abspath);
221 [ # # ]: 0 : if (r < 0)
222 : 0 : return r;
223 : :
224 : 0 : fd = open(abspath, O_NOFOLLOW|O_CLOEXEC|O_PATH);
225 [ # # ]: 0 : if (fd < 0) {
226 [ # # # # ]: 0 : if ((flags & LABEL_IGNORE_ENOENT) && errno == ENOENT)
227 : 0 : return 0;
228 : :
229 : 0 : return -errno;
230 : : }
231 : :
232 : 0 : return smack_fix_fd(fd, abspath, flags);
233 : : }
234 : :
235 : 0 : int mac_smack_copy(const char *dest, const char *src) {
236 : 0 : int r = 0;
237 : 0 : _cleanup_free_ char *label = NULL;
238 : :
239 [ # # ]: 0 : assert(dest);
240 [ # # ]: 0 : assert(src);
241 : :
242 : 0 : r = mac_smack_read(src, SMACK_ATTR_ACCESS, &label);
243 [ # # ]: 0 : if (r < 0)
244 : 0 : return r;
245 : :
246 : 0 : r = mac_smack_apply(dest, SMACK_ATTR_ACCESS, label);
247 [ # # ]: 0 : if (r < 0)
248 : 0 : return r;
249 : :
250 : 0 : return r;
251 : : }
252 : :
253 : : #else
254 : : bool mac_smack_use(void) {
255 : : return false;
256 : : }
257 : :
258 : : int mac_smack_read(const char *path, SmackAttr attr, char **label) {
259 : : return -EOPNOTSUPP;
260 : : }
261 : :
262 : : int mac_smack_read_fd(int fd, SmackAttr attr, char **label) {
263 : : return -EOPNOTSUPP;
264 : : }
265 : :
266 : : int mac_smack_apply(const char *path, SmackAttr attr, const char *label) {
267 : : return 0;
268 : : }
269 : :
270 : : int mac_smack_apply_fd(int fd, SmackAttr attr, const char *label) {
271 : : return 0;
272 : : }
273 : :
274 : : int mac_smack_apply_pid(pid_t pid, const char *label) {
275 : : return 0;
276 : : }
277 : :
278 : : int mac_smack_fix(const char *path, LabelFixFlags flags) {
279 : : return 0;
280 : : }
281 : :
282 : : int mac_smack_fix_at(int dirfd, const char *path, LabelFixFlags flags) {
283 : : return 0;
284 : : }
285 : :
286 : : int mac_smack_copy(const char *dest, const char *src) {
287 : : return 0;
288 : : }
289 : : #endif
|