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