chiark / gitweb /
missing_syscall: add __NR_copy_file_range for powerpc architecture (#3772)
[elogind.git] / src / basic / smack-util.c
1 /***
2   This file is part of systemd.
3
4   Copyright 2013 Intel Corporation
5
6   Author: Auke Kok <auke-jan.h.kok@intel.com>
7
8   systemd is free software; you can redistribute it and/or modify it
9   under the terms of the GNU Lesser General Public License as published by
10   the Free Software Foundation; either version 2.1 of the License, or
11   (at your option) any later version.
12
13   systemd is distributed in the hope that it will be useful, but
14   WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16   Lesser General Public License for more details.
17
18   You should have received a copy of the GNU Lesser General Public License
19   along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21
22 #include <errno.h>
23 #include <string.h>
24 #include <sys/stat.h>
25 #include <sys/xattr.h>
26 #include <unistd.h>
27
28 #include "alloc-util.h"
29 #include "fileio.h"
30 #include "log.h"
31 #include "macro.h"
32 #include "path-util.h"
33 #include "process-util.h"
34 #include "smack-util.h"
35 #include "string-table.h"
36 #include "xattr-util.h"
37
38 #ifdef HAVE_SMACK
39 bool mac_smack_use(void) {
40         static int cached_use = -1;
41
42         if (cached_use < 0)
43                 cached_use = access("/sys/fs/smackfs/", F_OK) >= 0;
44
45         return cached_use;
46 }
47
48 #if 0 /// UNNEEDED by elogind
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 #endif // 0
137
138 int mac_smack_fix(const char *path, bool ignore_enoent, bool ignore_erofs) {
139         struct stat st;
140         int r = 0;
141
142         assert(path);
143
144         if (!mac_smack_use())
145                 return 0;
146
147         /*
148          * Path must be in /dev and must exist
149          */
150         if (!path_startswith(path, "/dev"))
151                 return 0;
152
153         r = lstat(path, &st);
154         if (r >= 0) {
155                 const char *label;
156
157                 /*
158                  * Label directories and character devices "*".
159                  * Label symlinks "_".
160                  * Don't change anything else.
161                  */
162
163                 if (S_ISDIR(st.st_mode))
164                         label = SMACK_STAR_LABEL;
165                 else if (S_ISLNK(st.st_mode))
166                         label = SMACK_FLOOR_LABEL;
167                 else if (S_ISCHR(st.st_mode))
168                         label = SMACK_STAR_LABEL;
169                 else
170                         return 0;
171
172                 r = lsetxattr(path, "security.SMACK64", label, strlen(label), 0);
173
174                 /* If the FS doesn't support labels, then exit without warning */
175                 if (r < 0 && errno == EOPNOTSUPP)
176                         return 0;
177         }
178
179         if (r < 0) {
180                 /* Ignore ENOENT in some cases */
181                 if (ignore_enoent && errno == ENOENT)
182                         return 0;
183
184                 if (ignore_erofs && errno == EROFS)
185                         return 0;
186
187                 r = log_debug_errno(errno, "Unable to fix SMACK label of %s: %m", path);
188         }
189
190         return r;
191 }
192
193 #if 0 /// UNNEEDED by elogind
194 int mac_smack_copy(const char *dest, const char *src) {
195         int r = 0;
196         _cleanup_free_ char *label = NULL;
197
198         assert(dest);
199         assert(src);
200
201         r = mac_smack_read(src, SMACK_ATTR_ACCESS, &label);
202         if (r < 0)
203                 return r;
204
205         r = mac_smack_apply(dest, SMACK_ATTR_ACCESS, label);
206         if (r < 0)
207                 return r;
208
209         return r;
210 }
211 #endif // 0
212
213 #else
214 bool mac_smack_use(void) {
215         return false;
216 }
217
218 #if 0 /// UNNEEDED by elogind
219 int mac_smack_read(const char *path, SmackAttr attr, char **label) {
220         return -EOPNOTSUPP;
221 }
222
223 int mac_smack_read_fd(int fd, SmackAttr attr, char **label) {
224         return -EOPNOTSUPP;
225 }
226
227 int mac_smack_apply(const char *path, SmackAttr attr, const char *label) {
228         return 0;
229 }
230
231 int mac_smack_apply_fd(int fd, SmackAttr attr, const char *label) {
232         return 0;
233 }
234
235 int mac_smack_apply_pid(pid_t pid, const char *label) {
236         return 0;
237 }
238 #endif // 0
239
240 int mac_smack_fix(const char *path, bool ignore_enoent, bool ignore_erofs) {
241         return 0;
242 }
243
244 #if 0 /// UNNEEDED by elogind
245 int mac_smack_copy(const char *dest, const char *src) {
246         return 0;
247 }
248 #endif // 0
249 #endif