]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/shared/smack-util.c
shared: add process-util.[ch]
[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 "process-util.h"
28 #include "path-util.h"
29 #include "fileio.h"
30 #include "smack-util.h"
31
32 #define SMACK_FLOOR_LABEL "_"
33 #define SMACK_STAR_LABEL "*"
34
35 bool mac_smack_use(void) {
36 #ifdef HAVE_SMACK
37 static int cached_use = -1;
38
39 if (cached_use < 0)
40 cached_use = access("/sys/fs/smackfs/", F_OK) >= 0;
41
42 return cached_use;
43 #else
44 return false;
45 #endif
46 }
47
48 int mac_smack_apply(const char *path, const char *label) {
49 int r = 0;
50
51 assert(path);
52
53 #ifdef HAVE_SMACK
54 if (!mac_smack_use())
55 return 0;
56
57 if (label)
58 r = lsetxattr(path, "security.SMACK64", label, strlen(label), 0);
59 else
60 r = lremovexattr(path, "security.SMACK64");
61 if (r < 0)
62 return -errno;
63 #endif
64
65 return r;
66 }
67
68 int mac_smack_apply_fd(int fd, const char *label) {
69 int r = 0;
70
71 assert(fd >= 0);
72
73 #ifdef HAVE_SMACK
74 if (!mac_smack_use())
75 return 0;
76
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;
83 #endif
84
85 return r;
86 }
87
88 int mac_smack_apply_ip_out_fd(int fd, const char *label) {
89 int r = 0;
90
91 assert(fd >= 0);
92
93 #ifdef HAVE_SMACK
94 if (!mac_smack_use())
95 return 0;
96
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;
103 #endif
104
105 return r;
106 }
107
108 int mac_smack_apply_ip_in_fd(int fd, const char *label) {
109 int r = 0;
110
111 assert(fd >= 0);
112
113 #ifdef HAVE_SMACK
114 if (!mac_smack_use())
115 return 0;
116
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;
123 #endif
124
125 return r;
126 }
127
128 int mac_smack_apply_pid(pid_t pid, const char *label) {
129
130 #ifdef HAVE_SMACK
131 const char *p;
132 #endif
133 int r = 0;
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
150 int mac_smack_fix(const char *path, bool ignore_enoent, bool ignore_erofs) {
151
152 #ifdef HAVE_SMACK
153 struct stat st;
154 #endif
155 int r = 0;
156
157 assert(path);
158
159 #ifdef HAVE_SMACK
160 if (!mac_smack_use())
161 return 0;
162
163 /*
164 * Path must be in /dev and must exist
165 */
166 if (!path_startswith(path, "/dev"))
167 return 0;
168
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;
187
188 r = lsetxattr(path, "security.SMACK64", label, strlen(label), 0);
189
190 /* If the FS doesn't support labels, then exit without warning */
191 if (r < 0 && errno == EOPNOTSUPP)
192 return 0;
193 }
194
195 if (r < 0) {
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
203 r = log_debug_errno(errno, "Unable to fix SMACK label of %s: %m", path);
204 }
205 #endif
206
207 return r;
208 }