• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /***
2   This file is part of eudev, forked from systemd.
3 
4   Copyright 2013 Intel Corporation
5 
6   Author: Auke Kok <auke-jan.h.kok@intel.com>
7 
8   systemd is free software; you can redistribute it and/or modify it
9   under the terms of the GNU Lesser General Public License as published by
10   the Free Software Foundation; either version 2.1 of the License, or
11   (at your option) any later version.
12 
13   systemd is distributed in the hope that it will be useful, but
14   WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16   Lesser General Public License for more details.
17 
18   You should have received a copy of the GNU Lesser General Public License
19   along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21 
22 #ifdef HAVE_XATTR
23 #include <attr/xattr.h>
24 #endif
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 
mac_smack_use(void)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 
mac_smack_apply(const char * path,const char * label)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 
mac_smack_apply_fd(int fd,const char * label)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 
mac_smack_apply_ip_out_fd(int fd,const char * label)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 
mac_smack_apply_ip_in_fd(int fd,const char * label)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 
mac_smack_apply_pid(pid_t pid,const char * label)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 
mac_smack_fix(const char * path,bool ignore_enoent,bool ignore_erofs)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 }
209