]> git.proxmox.com Git - systemd.git/blame - src/shared/smack-util.c
Imported Upstream version 218
[systemd.git] / src / shared / smack-util.c
CommitLineData
60f067b4
JS
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
60f067b4
JS
24#include <sys/xattr.h>
25
5eef597e
MP
26#include "util.h"
27#include "path-util.h"
f47781d8 28#include "fileio.h"
60f067b4
JS
29#include "smack-util.h"
30
5eef597e
MP
31#define SMACK_FLOOR_LABEL "_"
32#define SMACK_STAR_LABEL "*"
33
34bool mac_smack_use(void) {
60f067b4 35#ifdef HAVE_SMACK
5eef597e 36 static int cached_use = -1;
60f067b4 37
5eef597e
MP
38 if (cached_use < 0)
39 cached_use = access("/sys/fs/smackfs/", F_OK) >= 0;
60f067b4 40
5eef597e 41 return cached_use;
60f067b4
JS
42#else
43 return false;
44#endif
5eef597e
MP
45}
46
47int mac_smack_apply(const char *path, const char *label) {
48 int r = 0;
60f067b4 49
5eef597e
MP
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;
60f067b4
JS
65}
66
5eef597e
MP
67int mac_smack_apply_fd(int fd, const char *label) {
68 int r = 0;
69
70 assert(fd >= 0);
71
60f067b4 72#ifdef HAVE_SMACK
5eef597e 73 if (!mac_smack_use())
60f067b4
JS
74 return 0;
75
76 if (label)
5eef597e 77 r = fsetxattr(fd, "security.SMACK64", label, strlen(label), 0);
60f067b4 78 else
5eef597e
MP
79 r = fremovexattr(fd, "security.SMACK64");
80 if (r < 0)
81 return -errno;
60f067b4 82#endif
5eef597e
MP
83
84 return r;
60f067b4
JS
85}
86
5eef597e
MP
87int mac_smack_apply_ip_out_fd(int fd, const char *label) {
88 int r = 0;
89
90 assert(fd >= 0);
91
60f067b4 92#ifdef HAVE_SMACK
5eef597e 93 if (!mac_smack_use())
60f067b4
JS
94 return 0;
95
5eef597e
MP
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;
60f067b4 102#endif
5eef597e
MP
103
104 return r;
60f067b4
JS
105}
106
5eef597e
MP
107int mac_smack_apply_ip_in_fd(int fd, const char *label) {
108 int r = 0;
109
110 assert(fd >= 0);
111
60f067b4 112#ifdef HAVE_SMACK
5eef597e 113 if (!mac_smack_use())
60f067b4
JS
114 return 0;
115
5eef597e
MP
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;
60f067b4 122#endif
5eef597e
MP
123
124 return r;
60f067b4
JS
125}
126
f47781d8
MP
127int mac_smack_apply_pid(pid_t pid, const char *label) {
128
129#ifdef HAVE_SMACK
130 const char *p;
131#endif
5eef597e
MP
132 int r = 0;
133
f47781d8
MP
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
149int mac_smack_fix(const char *path, bool ignore_enoent, bool ignore_erofs) {
150
60f067b4 151#ifdef HAVE_SMACK
5eef597e 152 struct stat st;
f47781d8
MP
153#endif
154 int r = 0;
5eef597e
MP
155
156 assert(path);
157
f47781d8 158#ifdef HAVE_SMACK
5eef597e 159 if (!mac_smack_use())
60f067b4
JS
160 return 0;
161
5eef597e
MP
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
f47781d8 202 r = log_debug_errno(errno, "Unable to fix SMACK label of %s: %m", path);
5eef597e 203 }
60f067b4 204#endif
5eef597e
MP
205
206 return r;
60f067b4 207}