]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/shared/smack-util.c
treewide: use log_*_errno whenever %m is in the format string
[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
WC
26#include "util.h"
27#include "path-util.h"
2ca620c4 28#include "fileio.h"
d682b3a7 29#include "smack-util.h"
8552b176 30
376a2980
LP
31#define SMACK_FLOOR_LABEL "_"
32#define SMACK_STAR_LABEL "*"
33
6baa7db0 34bool mac_smack_use(void) {
d682b3a7 35#ifdef HAVE_SMACK
6baa7db0 36 static int cached_use = -1;
d682b3a7 37
6baa7db0
LP
38 if (cached_use < 0)
39 cached_use = access("/sys/fs/smackfs/", F_OK) >= 0;
8552b176 40
6baa7db0 41 return cached_use;
d682b3a7
LP
42#else
43 return false;
44#endif
8552b176 45}
9a4e038c 46
c80d766c 47int mac_smack_apply(const char *path, const char *label) {
d53e386d
LP
48 int r = 0;
49
50 assert(path);
51
9a4e038c 52#ifdef HAVE_SMACK
6baa7db0 53 if (!mac_smack_use())
9a4e038c
KS
54 return 0;
55
56 if (label)
d1ce2089 57 r = lsetxattr(path, "security.SMACK64", label, strlen(label), 0);
9a4e038c 58 else
d53e386d
LP
59 r = lremovexattr(path, "security.SMACK64");
60 if (r < 0)
61 return -errno;
9a4e038c 62#endif
d53e386d
LP
63
64 return r;
9a4e038c
KS
65}
66
c80d766c 67int mac_smack_apply_fd(int fd, const char *label) {
d53e386d
LP
68 int r = 0;
69
70 assert(fd >= 0);
71
9a4e038c 72#ifdef HAVE_SMACK
6baa7db0 73 if (!mac_smack_use())
9a4e038c
KS
74 return 0;
75
d53e386d
LP
76 if (label)
77 r = fsetxattr(fd, "security.SMACK64", label, strlen(label), 0);
78 else
79 r = fremovexattr(fd, "security.SMACK64");
80 if (r < 0)
81 return -errno;
9a4e038c 82#endif
d53e386d
LP
83
84 return r;
9a4e038c
KS
85}
86
c80d766c 87int mac_smack_apply_ip_out_fd(int fd, const char *label) {
d53e386d
LP
88 int r = 0;
89
90 assert(fd >= 0);
91
9a4e038c 92#ifdef HAVE_SMACK
6baa7db0 93 if (!mac_smack_use())
9a4e038c
KS
94 return 0;
95
d53e386d
LP
96 if (label)
97 r = fsetxattr(fd, "security.SMACK64IPOUT", label, strlen(label), 0);
98 else
99 r = fremovexattr(fd, "security.SMACK64IPOUT");
100 if (r < 0)
101 return -errno;
9a4e038c 102#endif
d53e386d
LP
103
104 return r;
9a4e038c
KS
105}
106
c80d766c 107int mac_smack_apply_ip_in_fd(int fd, const char *label) {
d53e386d
LP
108 int r = 0;
109
110 assert(fd >= 0);
111
9a4e038c 112#ifdef HAVE_SMACK
6baa7db0 113 if (!mac_smack_use())
9a4e038c
KS
114 return 0;
115
d53e386d
LP
116 if (label)
117 r = fsetxattr(fd, "security.SMACK64IPIN", label, strlen(label), 0);
118 else
119 r = fremovexattr(fd, "security.SMACK64IPIN");
120 if (r < 0)
121 return -errno;
9a4e038c 122#endif
d53e386d
LP
123
124 return r;
9a4e038c 125}
66b6d9d5 126
2ca620c4
WC
127int mac_smack_apply_pid(pid_t pid, const char *label) {
128 int r = 0;
129 const char *p;
130
131 assert(label);
132
133#ifdef HAVE_SMACK
134 if (!mac_smack_use())
135 return 0;
136
137 p = procfs_file_alloca(pid, "attr/current");
138 r = write_string_file(p, label);
139 if (r < 0)
140 return r;
141#endif
142
143 return r;
144}
145
5dfc5461 146int mac_smack_fix(const char *path, bool ignore_enoent, bool ignore_erofs) {
66b6d9d5
WC
147 int r = 0;
148
149#ifdef HAVE_SMACK
5dfc5461 150 struct stat st;
d53e386d
LP
151
152 assert(path);
153
d53e386d
LP
154 if (!mac_smack_use())
155 return 0;
66b6d9d5
WC
156
157 /*
158 * Path must be in /dev and must exist
159 */
160 if (!path_startswith(path, "/dev"))
161 return 0;
162
5dfc5461
LP
163 r = lstat(path, &st);
164 if (r >= 0) {
165 const char *label;
166
167 /*
168 * Label directories and character devices "*".
169 * Label symlinks "_".
170 * Don't change anything else.
171 */
172
173 if (S_ISDIR(st.st_mode))
174 label = SMACK_STAR_LABEL;
175 else if (S_ISLNK(st.st_mode))
176 label = SMACK_FLOOR_LABEL;
177 else if (S_ISCHR(st.st_mode))
178 label = SMACK_STAR_LABEL;
179 else
180 return 0;
66b6d9d5 181
5dfc5461
LP
182 r = lsetxattr(path, "security.SMACK64", label, strlen(label), 0);
183
184 /* If the FS doesn't support labels, then exit without warning */
185 if (r < 0 && errno == ENOTSUP)
186 return 0;
187 }
66b6d9d5 188
66b6d9d5 189 if (r < 0) {
5dfc5461
LP
190 /* Ignore ENOENT in some cases */
191 if (ignore_enoent && errno == ENOENT)
192 return 0;
193
194 if (ignore_erofs && errno == EROFS)
195 return 0;
196
56f64d95 197 log_debug_errno(errno, "Unable to fix SMACK label of %s: %m", path);
5dfc5461 198 r = -errno;
66b6d9d5
WC
199 }
200#endif
201
202 return r;
203}