]>
Commit | Line | Data |
---|---|---|
53e1b683 | 1 | /* SPDX-License-Identifier: LGPL-2.1+ */ |
8552b176 AK |
2 | /*** |
3 | This file is part of systemd. | |
4 | ||
5 | Copyright 2013 Intel Corporation | |
6 | ||
7 | Author: Auke Kok <auke-jan.h.kok@intel.com> | |
8 | ||
9 | systemd is free software; you can redistribute it and/or modify it | |
10 | under the terms of the GNU Lesser General Public License as published by | |
11 | the Free Software Foundation; either version 2.1 of the License, or | |
12 | (at your option) any later version. | |
13 | ||
14 | systemd is distributed in the hope that it will be useful, but | |
15 | WITHOUT ANY WARRANTY; without even the implied warranty of | |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
17 | Lesser General Public License for more details. | |
18 | ||
19 | You should have received a copy of the GNU Lesser General Public License | |
20 | along with systemd; If not, see <http://www.gnu.org/licenses/>. | |
21 | ***/ | |
22 | ||
11c3a366 TA |
23 | #include <errno.h> |
24 | #include <string.h> | |
25 | #include <sys/stat.h> | |
d2edfae0 | 26 | #include <sys/xattr.h> |
11c3a366 | 27 | #include <unistd.h> |
8552b176 | 28 | |
b5efdb8a | 29 | #include "alloc-util.h" |
2ca620c4 | 30 | #include "fileio.h" |
93cc7779 TA |
31 | #include "log.h" |
32 | #include "macro.h" | |
89a5a90c LP |
33 | #include "path-util.h" |
34 | #include "process-util.h" | |
d682b3a7 | 35 | #include "smack-util.h" |
8b43440b | 36 | #include "string-table.h" |
89a5a90c | 37 | #include "xattr-util.h" |
8552b176 | 38 | |
f9fa32f0 | 39 | #if ENABLE_SMACK |
5ab58c20 | 40 | bool mac_smack_use(void) { |
6baa7db0 | 41 | static int cached_use = -1; |
d682b3a7 | 42 | |
6baa7db0 LP |
43 | if (cached_use < 0) |
44 | cached_use = access("/sys/fs/smackfs/", F_OK) >= 0; | |
8552b176 | 45 | |
6baa7db0 | 46 | return cached_use; |
8552b176 | 47 | } |
9a4e038c | 48 | |
5ab58c20 WC |
49 | static const char* const smack_attr_table[_SMACK_ATTR_MAX] = { |
50 | [SMACK_ATTR_ACCESS] = "security.SMACK64", | |
51 | [SMACK_ATTR_EXEC] = "security.SMACK64EXEC", | |
52 | [SMACK_ATTR_MMAP] = "security.SMACK64MMAP", | |
53 | [SMACK_ATTR_TRANSMUTE] = "security.SMACK64TRANSMUTE", | |
54 | [SMACK_ATTR_IPIN] = "security.SMACK64IPIN", | |
55 | [SMACK_ATTR_IPOUT] = "security.SMACK64IPOUT", | |
56 | }; | |
57 | ||
58 | DEFINE_STRING_TABLE_LOOKUP(smack_attr, SmackAttr); | |
d53e386d | 59 | |
5ab58c20 | 60 | int mac_smack_read(const char *path, SmackAttr attr, char **label) { |
d53e386d | 61 | assert(path); |
5ab58c20 WC |
62 | assert(attr >= 0 && attr < _SMACK_ATTR_MAX); |
63 | assert(label); | |
d53e386d | 64 | |
6baa7db0 | 65 | if (!mac_smack_use()) |
9a4e038c KS |
66 | return 0; |
67 | ||
5ab58c20 | 68 | return getxattr_malloc(path, smack_attr_to_string(attr), label, true); |
9a4e038c KS |
69 | } |
70 | ||
5ab58c20 | 71 | int mac_smack_read_fd(int fd, SmackAttr attr, char **label) { |
d53e386d | 72 | assert(fd >= 0); |
5ab58c20 WC |
73 | assert(attr >= 0 && attr < _SMACK_ATTR_MAX); |
74 | assert(label); | |
d53e386d | 75 | |
6baa7db0 | 76 | if (!mac_smack_use()) |
9a4e038c KS |
77 | return 0; |
78 | ||
5ab58c20 | 79 | return fgetxattr_malloc(fd, smack_attr_to_string(attr), label); |
9a4e038c KS |
80 | } |
81 | ||
5ab58c20 WC |
82 | int mac_smack_apply(const char *path, SmackAttr attr, const char *label) { |
83 | int r; | |
d53e386d | 84 | |
5ab58c20 WC |
85 | assert(path); |
86 | assert(attr >= 0 && attr < _SMACK_ATTR_MAX); | |
d53e386d | 87 | |
6baa7db0 | 88 | if (!mac_smack_use()) |
9a4e038c KS |
89 | return 0; |
90 | ||
d53e386d | 91 | if (label) |
5ab58c20 | 92 | r = lsetxattr(path, smack_attr_to_string(attr), label, strlen(label), 0); |
d53e386d | 93 | else |
5ab58c20 | 94 | r = lremovexattr(path, smack_attr_to_string(attr)); |
d53e386d LP |
95 | if (r < 0) |
96 | return -errno; | |
d53e386d | 97 | |
5ab58c20 | 98 | return 0; |
9a4e038c KS |
99 | } |
100 | ||
5ab58c20 WC |
101 | int mac_smack_apply_fd(int fd, SmackAttr attr, const char *label) { |
102 | int r; | |
d53e386d LP |
103 | |
104 | assert(fd >= 0); | |
5ab58c20 | 105 | assert(attr >= 0 && attr < _SMACK_ATTR_MAX); |
d53e386d | 106 | |
6baa7db0 | 107 | if (!mac_smack_use()) |
9a4e038c KS |
108 | return 0; |
109 | ||
d53e386d | 110 | if (label) |
5ab58c20 | 111 | r = fsetxattr(fd, smack_attr_to_string(attr), label, strlen(label), 0); |
d53e386d | 112 | else |
5ab58c20 | 113 | r = fremovexattr(fd, smack_attr_to_string(attr)); |
d53e386d LP |
114 | if (r < 0) |
115 | return -errno; | |
d53e386d | 116 | |
5ab58c20 | 117 | return 0; |
9a4e038c | 118 | } |
66b6d9d5 | 119 | |
2ca620c4 | 120 | int mac_smack_apply_pid(pid_t pid, const char *label) { |
2ca620c4 | 121 | const char *p; |
fae5694e | 122 | int r = 0; |
2ca620c4 WC |
123 | |
124 | assert(label); | |
125 | ||
2ca620c4 WC |
126 | if (!mac_smack_use()) |
127 | return 0; | |
128 | ||
129 | p = procfs_file_alloca(pid, "attr/current"); | |
ad118bda | 130 | r = write_string_file(p, label, 0); |
2ca620c4 WC |
131 | if (r < 0) |
132 | return r; | |
2ca620c4 WC |
133 | |
134 | return r; | |
135 | } | |
136 | ||
5dfc5461 | 137 | int mac_smack_fix(const char *path, bool ignore_enoent, bool ignore_erofs) { |
5dfc5461 | 138 | struct stat st; |
fae5694e | 139 | int r = 0; |
d53e386d LP |
140 | |
141 | assert(path); | |
142 | ||
d53e386d LP |
143 | if (!mac_smack_use()) |
144 | return 0; | |
66b6d9d5 WC |
145 | |
146 | /* | |
147 | * Path must be in /dev and must exist | |
148 | */ | |
149 | if (!path_startswith(path, "/dev")) | |
150 | return 0; | |
151 | ||
5dfc5461 LP |
152 | r = lstat(path, &st); |
153 | if (r >= 0) { | |
154 | const char *label; | |
155 | ||
156 | /* | |
157 | * Label directories and character devices "*". | |
158 | * Label symlinks "_". | |
159 | * Don't change anything else. | |
160 | */ | |
161 | ||
162 | if (S_ISDIR(st.st_mode)) | |
163 | label = SMACK_STAR_LABEL; | |
164 | else if (S_ISLNK(st.st_mode)) | |
165 | label = SMACK_FLOOR_LABEL; | |
166 | else if (S_ISCHR(st.st_mode)) | |
167 | label = SMACK_STAR_LABEL; | |
168 | else | |
169 | return 0; | |
66b6d9d5 | 170 | |
5dfc5461 LP |
171 | r = lsetxattr(path, "security.SMACK64", label, strlen(label), 0); |
172 | ||
173 | /* If the FS doesn't support labels, then exit without warning */ | |
15411c0c | 174 | if (r < 0 && errno == EOPNOTSUPP) |
5dfc5461 LP |
175 | return 0; |
176 | } | |
66b6d9d5 | 177 | |
66b6d9d5 | 178 | if (r < 0) { |
5dfc5461 LP |
179 | /* Ignore ENOENT in some cases */ |
180 | if (ignore_enoent && errno == ENOENT) | |
181 | return 0; | |
182 | ||
183 | if (ignore_erofs && errno == EROFS) | |
184 | return 0; | |
185 | ||
fae5694e | 186 | r = log_debug_errno(errno, "Unable to fix SMACK label of %s: %m", path); |
66b6d9d5 | 187 | } |
66b6d9d5 WC |
188 | |
189 | return r; | |
190 | } | |
5ab58c20 | 191 | |
ba056b73 SW |
192 | int mac_smack_copy(const char *dest, const char *src) { |
193 | int r = 0; | |
194 | _cleanup_free_ char *label = NULL; | |
195 | ||
196 | assert(dest); | |
197 | assert(src); | |
198 | ||
199 | r = mac_smack_read(src, SMACK_ATTR_ACCESS, &label); | |
200 | if (r < 0) | |
201 | return r; | |
202 | ||
203 | r = mac_smack_apply(dest, SMACK_ATTR_ACCESS, label); | |
204 | if (r < 0) | |
205 | return r; | |
206 | ||
207 | return r; | |
208 | } | |
5ab58c20 WC |
209 | |
210 | #else | |
211 | bool mac_smack_use(void) { | |
212 | return false; | |
213 | } | |
214 | ||
215 | int mac_smack_read(const char *path, SmackAttr attr, char **label) { | |
216 | return -EOPNOTSUPP; | |
217 | } | |
218 | ||
219 | int mac_smack_read_fd(int fd, SmackAttr attr, char **label) { | |
220 | return -EOPNOTSUPP; | |
221 | } | |
222 | ||
223 | int mac_smack_apply(const char *path, SmackAttr attr, const char *label) { | |
224 | return 0; | |
225 | } | |
226 | ||
227 | int mac_smack_apply_fd(int fd, SmackAttr attr, const char *label) { | |
228 | return 0; | |
229 | } | |
230 | ||
231 | int mac_smack_apply_pid(pid_t pid, const char *label) { | |
232 | return 0; | |
233 | } | |
234 | ||
235 | int mac_smack_fix(const char *path, bool ignore_enoent, bool ignore_erofs) { | |
236 | return 0; | |
237 | } | |
ba056b73 SW |
238 | |
239 | int mac_smack_copy(const char *dest, const char *src) { | |
240 | return 0; | |
241 | } | |
5ab58c20 | 242 | #endif |