]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/basic/smack-util.c
Add SPDX license identifiers to source files under the LGPL
[thirdparty/systemd.git] / src / basic / smack-util.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
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
23 #include <errno.h>
24 #include <string.h>
25 #include <sys/stat.h>
26 #include <sys/xattr.h>
27 #include <unistd.h>
28
29 #include "alloc-util.h"
30 #include "fileio.h"
31 #include "log.h"
32 #include "macro.h"
33 #include "path-util.h"
34 #include "process-util.h"
35 #include "smack-util.h"
36 #include "string-table.h"
37 #include "xattr-util.h"
38
39 #if ENABLE_SMACK
40 bool mac_smack_use(void) {
41 static int cached_use = -1;
42
43 if (cached_use < 0)
44 cached_use = access("/sys/fs/smackfs/", F_OK) >= 0;
45
46 return cached_use;
47 }
48
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);
59
60 int mac_smack_read(const char *path, SmackAttr attr, char **label) {
61 assert(path);
62 assert(attr >= 0 && attr < _SMACK_ATTR_MAX);
63 assert(label);
64
65 if (!mac_smack_use())
66 return 0;
67
68 return getxattr_malloc(path, smack_attr_to_string(attr), label, true);
69 }
70
71 int mac_smack_read_fd(int fd, SmackAttr attr, char **label) {
72 assert(fd >= 0);
73 assert(attr >= 0 && attr < _SMACK_ATTR_MAX);
74 assert(label);
75
76 if (!mac_smack_use())
77 return 0;
78
79 return fgetxattr_malloc(fd, smack_attr_to_string(attr), label);
80 }
81
82 int mac_smack_apply(const char *path, SmackAttr attr, const char *label) {
83 int r;
84
85 assert(path);
86 assert(attr >= 0 && attr < _SMACK_ATTR_MAX);
87
88 if (!mac_smack_use())
89 return 0;
90
91 if (label)
92 r = lsetxattr(path, smack_attr_to_string(attr), label, strlen(label), 0);
93 else
94 r = lremovexattr(path, smack_attr_to_string(attr));
95 if (r < 0)
96 return -errno;
97
98 return 0;
99 }
100
101 int mac_smack_apply_fd(int fd, SmackAttr attr, const char *label) {
102 int r;
103
104 assert(fd >= 0);
105 assert(attr >= 0 && attr < _SMACK_ATTR_MAX);
106
107 if (!mac_smack_use())
108 return 0;
109
110 if (label)
111 r = fsetxattr(fd, smack_attr_to_string(attr), label, strlen(label), 0);
112 else
113 r = fremovexattr(fd, smack_attr_to_string(attr));
114 if (r < 0)
115 return -errno;
116
117 return 0;
118 }
119
120 int mac_smack_apply_pid(pid_t pid, const char *label) {
121 const char *p;
122 int r = 0;
123
124 assert(label);
125
126 if (!mac_smack_use())
127 return 0;
128
129 p = procfs_file_alloca(pid, "attr/current");
130 r = write_string_file(p, label, 0);
131 if (r < 0)
132 return r;
133
134 return r;
135 }
136
137 int mac_smack_fix(const char *path, bool ignore_enoent, bool ignore_erofs) {
138 struct stat st;
139 int r = 0;
140
141 assert(path);
142
143 if (!mac_smack_use())
144 return 0;
145
146 /*
147 * Path must be in /dev and must exist
148 */
149 if (!path_startswith(path, "/dev"))
150 return 0;
151
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;
170
171 r = lsetxattr(path, "security.SMACK64", label, strlen(label), 0);
172
173 /* If the FS doesn't support labels, then exit without warning */
174 if (r < 0 && errno == EOPNOTSUPP)
175 return 0;
176 }
177
178 if (r < 0) {
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
186 r = log_debug_errno(errno, "Unable to fix SMACK label of %s: %m", path);
187 }
188
189 return r;
190 }
191
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 }
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 }
238
239 int mac_smack_copy(const char *dest, const char *src) {
240 return 0;
241 }
242 #endif