chiark / gitweb /
sd-rtnl: rename sd_rtnl_message_route_get_{dst,src}_len to *_prefixlen
[elogind.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         int r = 0;
129         const char *p;
130
131         assert(label);
132
133 #ifdef HAVE_SMACK
134         if (!mac_smack_use())
135                 return 0;
136
137         p = procfs_file_alloca(pid, "attr/current");
138         r = write_string_file(p, label);
139         if (r < 0)
140                 return r;
141 #endif
142
143         return r;
144 }
145
146 int mac_smack_fix(const char *path, bool ignore_enoent, bool ignore_erofs) {
147         int r = 0;
148
149 #ifdef HAVE_SMACK
150         struct stat st;
151
152         assert(path);
153
154         if (!mac_smack_use())
155                 return 0;
156
157         /*
158          * Path must be in /dev and must exist
159          */
160         if (!path_startswith(path, "/dev"))
161                 return 0;
162
163         r = lstat(path, &st);
164         if (r >= 0) {
165                 const char *label;
166
167                 /*
168                  * Label directories and character devices "*".
169                  * Label symlinks "_".
170                  * Don't change anything else.
171                  */
172
173                 if (S_ISDIR(st.st_mode))
174                         label = SMACK_STAR_LABEL;
175                 else if (S_ISLNK(st.st_mode))
176                         label = SMACK_FLOOR_LABEL;
177                 else if (S_ISCHR(st.st_mode))
178                         label = SMACK_STAR_LABEL;
179                 else
180                         return 0;
181
182                 r = lsetxattr(path, "security.SMACK64", label, strlen(label), 0);
183
184                 /* If the FS doesn't support labels, then exit without warning */
185                 if (r < 0 && errno == ENOTSUP)
186                         return 0;
187         }
188
189         if (r < 0) {
190                 /* Ignore ENOENT in some cases */
191                 if (ignore_enoent && errno == ENOENT)
192                         return 0;
193
194                 if (ignore_erofs && errno == EROFS)
195                         return 0;
196
197                 log_debug_errno(errno, "Unable to fix SMACK label of %s: %m", path);
198                 r = -errno;
199         }
200 #endif
201
202         return r;
203 }