]>
Commit | Line | Data |
---|---|---|
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 | ||
34 | bool 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 | ||
47 | int 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 |
67 | int 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 |
87 | int 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 |
107 | int 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 |
127 | int 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 | ||
149 | int 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 | } |