]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/shared/smack-util.c
shared: add process-util.[ch]
[thirdparty/systemd.git] / src / shared / smack-util.c
CommitLineData
8552b176
AK
1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3/***
4 This file is part of systemd.
5
6 Copyright 2013 Intel Corporation
7
8 Author: Auke Kok <auke-jan.h.kok@intel.com>
9
10 systemd is free software; you can redistribute it and/or modify it
11 under the terms of the GNU Lesser General Public License as published by
12 the Free Software Foundation; either version 2.1 of the License, or
13 (at your option) any later version.
14
15 systemd is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 Lesser General Public License for more details.
19
20 You should have received a copy of the GNU Lesser General Public License
21 along with systemd; If not, see <http://www.gnu.org/licenses/>.
22***/
23
d2edfae0 24#include <sys/xattr.h>
8552b176 25
66b6d9d5 26#include "util.h"
0b452006 27#include "process-util.h"
66b6d9d5 28#include "path-util.h"
2ca620c4 29#include "fileio.h"
d682b3a7 30#include "smack-util.h"
8552b176 31
376a2980
LP
32#define SMACK_FLOOR_LABEL "_"
33#define SMACK_STAR_LABEL "*"
34
6baa7db0 35bool mac_smack_use(void) {
d682b3a7 36#ifdef HAVE_SMACK
6baa7db0 37 static int cached_use = -1;
d682b3a7 38
6baa7db0
LP
39 if (cached_use < 0)
40 cached_use = access("/sys/fs/smackfs/", F_OK) >= 0;
8552b176 41
6baa7db0 42 return cached_use;
d682b3a7
LP
43#else
44 return false;
45#endif
8552b176 46}
9a4e038c 47
c80d766c 48int mac_smack_apply(const char *path, const char *label) {
d53e386d
LP
49 int r = 0;
50
51 assert(path);
52
9a4e038c 53#ifdef HAVE_SMACK
6baa7db0 54 if (!mac_smack_use())
9a4e038c
KS
55 return 0;
56
57 if (label)
d1ce2089 58 r = lsetxattr(path, "security.SMACK64", label, strlen(label), 0);
9a4e038c 59 else
d53e386d
LP
60 r = lremovexattr(path, "security.SMACK64");
61 if (r < 0)
62 return -errno;
9a4e038c 63#endif
d53e386d
LP
64
65 return r;
9a4e038c
KS
66}
67
c80d766c 68int mac_smack_apply_fd(int fd, const char *label) {
d53e386d
LP
69 int r = 0;
70
71 assert(fd >= 0);
72
9a4e038c 73#ifdef HAVE_SMACK
6baa7db0 74 if (!mac_smack_use())
9a4e038c
KS
75 return 0;
76
d53e386d
LP
77 if (label)
78 r = fsetxattr(fd, "security.SMACK64", label, strlen(label), 0);
79 else
80 r = fremovexattr(fd, "security.SMACK64");
81 if (r < 0)
82 return -errno;
9a4e038c 83#endif
d53e386d
LP
84
85 return r;
9a4e038c
KS
86}
87
c80d766c 88int mac_smack_apply_ip_out_fd(int fd, const char *label) {
d53e386d
LP
89 int r = 0;
90
91 assert(fd >= 0);
92
9a4e038c 93#ifdef HAVE_SMACK
6baa7db0 94 if (!mac_smack_use())
9a4e038c
KS
95 return 0;
96
d53e386d
LP
97 if (label)
98 r = fsetxattr(fd, "security.SMACK64IPOUT", label, strlen(label), 0);
99 else
100 r = fremovexattr(fd, "security.SMACK64IPOUT");
101 if (r < 0)
102 return -errno;
9a4e038c 103#endif
d53e386d
LP
104
105 return r;
9a4e038c
KS
106}
107
c80d766c 108int mac_smack_apply_ip_in_fd(int fd, const char *label) {
d53e386d
LP
109 int r = 0;
110
111 assert(fd >= 0);
112
9a4e038c 113#ifdef HAVE_SMACK
6baa7db0 114 if (!mac_smack_use())
9a4e038c
KS
115 return 0;
116
d53e386d
LP
117 if (label)
118 r = fsetxattr(fd, "security.SMACK64IPIN", label, strlen(label), 0);
119 else
120 r = fremovexattr(fd, "security.SMACK64IPIN");
121 if (r < 0)
122 return -errno;
9a4e038c 123#endif
d53e386d
LP
124
125 return r;
9a4e038c 126}
66b6d9d5 127
2ca620c4 128int mac_smack_apply_pid(pid_t pid, const char *label) {
fae5694e
LP
129
130#ifdef HAVE_SMACK
2ca620c4 131 const char *p;
fae5694e
LP
132#endif
133 int r = 0;
2ca620c4
WC
134
135 assert(label);
136
137#ifdef HAVE_SMACK
138 if (!mac_smack_use())
139 return 0;
140
141 p = procfs_file_alloca(pid, "attr/current");
142 r = write_string_file(p, label);
143 if (r < 0)
144 return r;
145#endif
146
147 return r;
148}
149
5dfc5461 150int mac_smack_fix(const char *path, bool ignore_enoent, bool ignore_erofs) {
66b6d9d5
WC
151
152#ifdef HAVE_SMACK
5dfc5461 153 struct stat st;
fae5694e
LP
154#endif
155 int r = 0;
d53e386d
LP
156
157 assert(path);
158
fae5694e 159#ifdef HAVE_SMACK
d53e386d
LP
160 if (!mac_smack_use())
161 return 0;
66b6d9d5
WC
162
163 /*
164 * Path must be in /dev and must exist
165 */
166 if (!path_startswith(path, "/dev"))
167 return 0;
168
5dfc5461
LP
169 r = lstat(path, &st);
170 if (r >= 0) {
171 const char *label;
172
173 /*
174 * Label directories and character devices "*".
175 * Label symlinks "_".
176 * Don't change anything else.
177 */
178
179 if (S_ISDIR(st.st_mode))
180 label = SMACK_STAR_LABEL;
181 else if (S_ISLNK(st.st_mode))
182 label = SMACK_FLOOR_LABEL;
183 else if (S_ISCHR(st.st_mode))
184 label = SMACK_STAR_LABEL;
185 else
186 return 0;
66b6d9d5 187
5dfc5461
LP
188 r = lsetxattr(path, "security.SMACK64", label, strlen(label), 0);
189
190 /* If the FS doesn't support labels, then exit without warning */
15411c0c 191 if (r < 0 && errno == EOPNOTSUPP)
5dfc5461
LP
192 return 0;
193 }
66b6d9d5 194
66b6d9d5 195 if (r < 0) {
5dfc5461
LP
196 /* Ignore ENOENT in some cases */
197 if (ignore_enoent && errno == ENOENT)
198 return 0;
199
200 if (ignore_erofs && errno == EROFS)
201 return 0;
202
fae5694e 203 r = log_debug_errno(errno, "Unable to fix SMACK label of %s: %m", path);
66b6d9d5
WC
204 }
205#endif
206
207 return r;
208}