1 /* SPDX-License-Identifier: LGPL-2.1+ */
3 This file is part of systemd.
5 Copyright 2013 Intel Corporation
7 Author: Auke Kok <auke-jan.h.kok@intel.com>
9 systemd is free software; you can redistribute it and/or modify it
10 under the terms of the GNU Lesser General Public License as published by
11 the Free Software Foundation; either version 2.1 of the License, or
12 (at your option) any later version.
14 systemd is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 Lesser General Public License for more details.
19 You should have received a copy of the GNU Lesser General Public License
20 along with systemd; If not, see <http://www.gnu.org/licenses/>.
27 #include <sys/xattr.h>
30 #include "alloc-util.h"
31 //#include "fd-util.h"
35 #include "path-util.h"
36 #include "process-util.h"
37 #include "smack-util.h"
38 //#include "stdio-util.h"
39 #include "string-table.h"
40 #include "xattr-util.h"
43 bool mac_smack_use(void) {
44 static int cached_use = -1;
47 cached_use = access("/sys/fs/smackfs/", F_OK) >= 0;
52 #if 0 /// UNNEEDED by elogind
53 static const char* const smack_attr_table[_SMACK_ATTR_MAX] = {
54 [SMACK_ATTR_ACCESS] = "security.SMACK64",
55 [SMACK_ATTR_EXEC] = "security.SMACK64EXEC",
56 [SMACK_ATTR_MMAP] = "security.SMACK64MMAP",
57 [SMACK_ATTR_TRANSMUTE] = "security.SMACK64TRANSMUTE",
58 [SMACK_ATTR_IPIN] = "security.SMACK64IPIN",
59 [SMACK_ATTR_IPOUT] = "security.SMACK64IPOUT",
62 DEFINE_STRING_TABLE_LOOKUP(smack_attr, SmackAttr);
64 int mac_smack_read(const char *path, SmackAttr attr, char **label) {
66 assert(attr >= 0 && attr < _SMACK_ATTR_MAX);
72 return getxattr_malloc(path, smack_attr_to_string(attr), label, true);
75 int mac_smack_read_fd(int fd, SmackAttr attr, char **label) {
77 assert(attr >= 0 && attr < _SMACK_ATTR_MAX);
83 return fgetxattr_malloc(fd, smack_attr_to_string(attr), label);
86 int mac_smack_apply(const char *path, SmackAttr attr, const char *label) {
90 assert(attr >= 0 && attr < _SMACK_ATTR_MAX);
96 r = lsetxattr(path, smack_attr_to_string(attr), label, strlen(label), 0);
98 r = lremovexattr(path, smack_attr_to_string(attr));
105 int mac_smack_apply_fd(int fd, SmackAttr attr, const char *label) {
109 assert(attr >= 0 && attr < _SMACK_ATTR_MAX);
111 if (!mac_smack_use())
115 r = fsetxattr(fd, smack_attr_to_string(attr), label, strlen(label), 0);
117 r = fremovexattr(fd, smack_attr_to_string(attr));
124 int mac_smack_apply_pid(pid_t pid, const char *label) {
130 if (!mac_smack_use())
133 p = procfs_file_alloca(pid, "attr/current");
134 r = write_string_file(p, label, 0);
142 int mac_smack_fix(const char *path, LabelFixFlags flags) {
143 char procfs_path[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(int)];
144 _cleanup_close_ int fd = -1;
151 if (!mac_smack_use())
154 /* Path must be in /dev */
155 if (!path_startswith(path, "/dev"))
158 fd = open(path, O_NOFOLLOW|O_CLOEXEC|O_PATH);
160 if ((flags & LABEL_IGNORE_ENOENT) && errno == ENOENT)
166 if (fstat(fd, &st) < 0)
170 * Label directories and character devices "*".
171 * Label symlinks "_".
172 * Don't change anything else.
175 if (S_ISDIR(st.st_mode))
176 label = SMACK_STAR_LABEL;
177 else if (S_ISLNK(st.st_mode))
178 label = SMACK_FLOOR_LABEL;
179 else if (S_ISCHR(st.st_mode))
180 label = SMACK_STAR_LABEL;
184 xsprintf(procfs_path, "/proc/self/fd/%i", fd);
185 if (setxattr(procfs_path, "security.SMACK64", label, strlen(label), 0) < 0) {
186 _cleanup_free_ char *old_label = NULL;
190 /* If the FS doesn't support labels, then exit without warning */
191 if (r == -EOPNOTSUPP)
194 /* It the FS is read-only and we were told to ignore failures caused by that, suppress error */
195 if (r == -EROFS && (flags & LABEL_IGNORE_EROFS))
198 /* If the old label is identical to the new one, suppress any kind of error */
199 if (getxattr_malloc(procfs_path, "security.SMACK64", &old_label, false) >= 0 &&
200 streq(old_label, label))
203 return log_debug_errno(r, "Unable to fix SMACK label of %s: %m", path);
209 #if 0 /// UNNEEDED by elogind
210 int mac_smack_copy(const char *dest, const char *src) {
212 _cleanup_free_ char *label = NULL;
217 r = mac_smack_read(src, SMACK_ATTR_ACCESS, &label);
221 r = mac_smack_apply(dest, SMACK_ATTR_ACCESS, label);
230 bool mac_smack_use(void) {
234 #if 0 /// UNNEEDED by elogind
235 int mac_smack_read(const char *path, SmackAttr attr, char **label) {
239 int mac_smack_read_fd(int fd, SmackAttr attr, char **label) {
243 int mac_smack_apply(const char *path, SmackAttr attr, const char *label) {
247 int mac_smack_apply_fd(int fd, SmackAttr attr, const char *label) {
251 int mac_smack_apply_pid(pid_t pid, const char *label) {
256 int mac_smack_fix(const char *path, bool ignore_enoent, bool ignore_erofs) {
260 #if 0 /// UNNEEDED by elogind
261 int mac_smack_copy(const char *dest, const char *src) {