3 * Copyright © 2012 Serge Hallyn <serge.hallyn@ubuntu.com>.
4 * Copyright © 2012 Canonical Ltd.
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
27 #include <sys/mount.h>
29 #include <sys/types.h>
36 #include "initutils.h"
40 #include "raw_syscalls.h"
43 lxc_log_define(apparmor
, lsm
);
45 /* set by lsm_apparmor_drv_init if true */
46 static int aa_enabled
= 0;
47 static bool aa_parser_available
= false;
48 static bool aa_supports_unix
= false;
49 static bool aa_can_stack
= false;
50 static bool aa_is_stacked
= false;
51 static bool aa_admin
= false;
53 static int mount_features_enabled
= 0;
55 #define AA_DEF_PROFILE "lxc-container-default"
56 #define AA_DEF_PROFILE_CGNS "lxc-container-default-cgns"
57 #define AA_MOUNT_RESTR "/sys/kernel/security/apparmor/features/mount/mask"
58 #define AA_ENABLED_FILE "/sys/module/apparmor/parameters/enabled"
59 #define AA_UNCHANGED "unchanged"
60 #define AA_GENERATED "generated"
62 #define AA_CMD_LOAD 'r'
63 #define AA_CMD_UNLOAD 'R'
64 #define AA_CMD_PARSE 'Q'
66 static const char AA_PROFILE_BASE
[] =
74 " # Allow us to receive signals from anywhere.\n"
75 " signal (receive),\n"
77 " # Allow us to send signals to ourselves\n"
78 " signal peer=@{profile_name},\n"
80 " # Allow other processes to read our /proc entries, futexes, perf tracing and\n"
81 " # kcmp for now (they will need 'read' in the first place). Administrators can\n"
83 " # deny ptrace (readby) ...\n"
86 " # Allow other processes to trace us by default (they will need 'trace' in\n"
87 " # the first place). Administrators can override with:\n"
88 " # deny ptrace (tracedby) ...\n"
89 " ptrace (tracedby),\n"
91 " # Allow us to ptrace ourselves\n"
92 " ptrace peer=@{profile_name},\n"
94 " # ignore DENIED message on / remount\n"
95 " deny mount options=(ro, remount) -> /,\n"
96 " deny mount options=(ro, remount, silent) -> /,\n"
98 " # allow tmpfs mounts everywhere\n"
99 " mount fstype=tmpfs,\n"
101 " # allow hugetlbfs mounts everywhere\n"
102 " mount fstype=hugetlbfs,\n"
104 " # allow mqueue mounts everywhere\n"
105 " mount fstype=mqueue,\n"
107 " # allow fuse mounts everywhere\n"
108 " mount fstype=fuse,\n"
109 " mount fstype=fuse.*,\n"
111 " # deny access under /proc/bus to avoid e.g. messing with pci devices directly\n"
112 " deny @{PROC}/bus/** wklx,\n"
114 " # deny writes in /proc/sys/fs but allow binfmt_misc to be mounted\n"
115 " mount fstype=binfmt_misc -> /proc/sys/fs/binfmt_misc/,\n"
116 " deny @{PROC}/sys/fs/** wklx,\n"
118 " # allow efivars to be mounted, writing to it will be blocked though\n"
119 " mount fstype=efivarfs -> /sys/firmware/efi/efivars/,\n"
121 " # block some other dangerous paths\n"
122 " deny @{PROC}/kcore rwklx,\n"
123 " deny @{PROC}/sysrq-trigger rwklx,\n"
124 " deny @{PROC}/acpi/** rwklx,\n"
126 " # deny writes in /sys except for /sys/fs/cgroup, also allow\n"
127 " # fusectl, securityfs and debugfs to be mounted there (read-only)\n"
128 " mount fstype=fusectl -> /sys/fs/fuse/connections/,\n"
129 " mount fstype=securityfs -> /sys/kernel/security/,\n"
130 " mount fstype=debugfs -> /sys/kernel/debug/,\n"
131 " deny mount fstype=debugfs -> /var/lib/ureadahead/debugfs/,\n"
132 " mount fstype=proc -> /proc/,\n"
133 " mount fstype=sysfs -> /sys/,\n"
134 " mount options=(rw, nosuid, nodev, noexec, remount) -> /sys/,\n"
135 " deny /sys/firmware/efi/efivars/** rwklx,\n"
136 " # note, /sys/kernel/security/** handled below\n"
137 " mount options=(ro, nosuid, nodev, noexec, remount, strictatime) -> /sys/fs/cgroup/,\n"
139 " # deny reads from debugfs\n"
140 " deny /sys/kernel/debug/{,**} rwklx,\n"
142 " # allow paths to be made slave, shared, private or unbindable\n"
143 " # FIXME: This currently doesn't work due to the apparmor parser treating those as allowing all mounts.\n"
144 "# mount options=(rw,make-slave) -> **,\n"
145 "# mount options=(rw,make-rslave) -> **,\n"
146 "# mount options=(rw,make-shared) -> **,\n"
147 "# mount options=(rw,make-rshared) -> **,\n"
148 "# mount options=(rw,make-private) -> **,\n"
149 "# mount options=(rw,make-rprivate) -> **,\n"
150 "# mount options=(rw,make-unbindable) -> **,\n"
151 "# mount options=(rw,make-runbindable) -> **,\n"
153 " # allow bind-mounts of anything except /proc, /sys and /dev\n"
154 " mount options=(rw,bind) /[^spd]*{,/**},\n"
155 " mount options=(rw,bind) /d[^e]*{,/**},\n"
156 " mount options=(rw,bind) /de[^v]*{,/**},\n"
157 " mount options=(rw,bind) /dev/.[^l]*{,/**},\n"
158 " mount options=(rw,bind) /dev/.l[^x]*{,/**},\n"
159 " mount options=(rw,bind) /dev/.lx[^c]*{,/**},\n"
160 " mount options=(rw,bind) /dev/.lxc?*{,/**},\n"
161 " mount options=(rw,bind) /dev/[^.]*{,/**},\n"
162 " mount options=(rw,bind) /dev?*{,/**},\n"
163 " mount options=(rw,bind) /p[^r]*{,/**},\n"
164 " mount options=(rw,bind) /pr[^o]*{,/**},\n"
165 " mount options=(rw,bind) /pro[^c]*{,/**},\n"
166 " mount options=(rw,bind) /proc?*{,/**},\n"
167 " mount options=(rw,bind) /s[^y]*{,/**},\n"
168 " mount options=(rw,bind) /sy[^s]*{,/**},\n"
169 " mount options=(rw,bind) /sys?*{,/**},\n"
171 " # allow various ro-bind-*re*-mounts\n"
172 " mount options=(ro,remount,bind),\n"
173 " mount options=(ro,remount,bind,nosuid),\n"
174 " mount options=(ro,remount,bind,noexec),\n"
175 " mount options=(ro,remount,bind,nodev),\n"
176 " mount options=(ro,remount,bind,nosuid,noexec),\n"
177 " mount options=(ro,remount,bind,noexec,nodev),\n"
178 " mount options=(ro,remount,bind,nodev,nosuid),\n"
179 " mount options=(ro,remount,bind,nosuid,noexec,nodev),\n"
181 " # allow moving mounts except for /proc, /sys and /dev\n"
182 " mount options=(rw,move) /[^spd]*{,/**},\n"
183 " mount options=(rw,move) /d[^e]*{,/**},\n"
184 " mount options=(rw,move) /de[^v]*{,/**},\n"
185 " mount options=(rw,move) /dev/.[^l]*{,/**},\n"
186 " mount options=(rw,move) /dev/.l[^x]*{,/**},\n"
187 " mount options=(rw,move) /dev/.lx[^c]*{,/**},\n"
188 " mount options=(rw,move) /dev/.lxc?*{,/**},\n"
189 " mount options=(rw,move) /dev/[^.]*{,/**},\n"
190 " mount options=(rw,move) /dev?*{,/**},\n"
191 " mount options=(rw,move) /p[^r]*{,/**},\n"
192 " mount options=(rw,move) /pr[^o]*{,/**},\n"
193 " mount options=(rw,move) /pro[^c]*{,/**},\n"
194 " mount options=(rw,move) /proc?*{,/**},\n"
195 " mount options=(rw,move) /s[^y]*{,/**},\n"
196 " mount options=(rw,move) /sy[^s]*{,/**},\n"
197 " mount options=(rw,move) /sys?*{,/**},\n"
199 " # generated by: lxc-generate-aa-rules.py container-rules.base\n"
200 " deny /proc/sys/[^kn]*{,/**} wklx,\n"
201 " deny /proc/sys/k[^e]*{,/**} wklx,\n"
202 " deny /proc/sys/ke[^r]*{,/**} wklx,\n"
203 " deny /proc/sys/ker[^n]*{,/**} wklx,\n"
204 " deny /proc/sys/kern[^e]*{,/**} wklx,\n"
205 " deny /proc/sys/kerne[^l]*{,/**} wklx,\n"
206 " deny /proc/sys/kernel/[^smhd]*{,/**} wklx,\n"
207 " deny /proc/sys/kernel/d[^o]*{,/**} wklx,\n"
208 " deny /proc/sys/kernel/do[^m]*{,/**} wklx,\n"
209 " deny /proc/sys/kernel/dom[^a]*{,/**} wklx,\n"
210 " deny /proc/sys/kernel/doma[^i]*{,/**} wklx,\n"
211 " deny /proc/sys/kernel/domai[^n]*{,/**} wklx,\n"
212 " deny /proc/sys/kernel/domain[^n]*{,/**} wklx,\n"
213 " deny /proc/sys/kernel/domainn[^a]*{,/**} wklx,\n"
214 " deny /proc/sys/kernel/domainna[^m]*{,/**} wklx,\n"
215 " deny /proc/sys/kernel/domainnam[^e]*{,/**} wklx,\n"
216 " deny /proc/sys/kernel/domainname?*{,/**} wklx,\n"
217 " deny /proc/sys/kernel/h[^o]*{,/**} wklx,\n"
218 " deny /proc/sys/kernel/ho[^s]*{,/**} wklx,\n"
219 " deny /proc/sys/kernel/hos[^t]*{,/**} wklx,\n"
220 " deny /proc/sys/kernel/host[^n]*{,/**} wklx,\n"
221 " deny /proc/sys/kernel/hostn[^a]*{,/**} wklx,\n"
222 " deny /proc/sys/kernel/hostna[^m]*{,/**} wklx,\n"
223 " deny /proc/sys/kernel/hostnam[^e]*{,/**} wklx,\n"
224 " deny /proc/sys/kernel/hostname?*{,/**} wklx,\n"
225 " deny /proc/sys/kernel/m[^s]*{,/**} wklx,\n"
226 " deny /proc/sys/kernel/ms[^g]*{,/**} wklx,\n"
227 " deny /proc/sys/kernel/msg*/** wklx,\n"
228 " deny /proc/sys/kernel/s[^he]*{,/**} wklx,\n"
229 " deny /proc/sys/kernel/se[^m]*{,/**} wklx,\n"
230 " deny /proc/sys/kernel/sem*/** wklx,\n"
231 " deny /proc/sys/kernel/sh[^m]*{,/**} wklx,\n"
232 " deny /proc/sys/kernel/shm*/** wklx,\n"
233 " deny /proc/sys/kernel?*{,/**} wklx,\n"
234 " deny /proc/sys/n[^e]*{,/**} wklx,\n"
235 " deny /proc/sys/ne[^t]*{,/**} wklx,\n"
236 " deny /proc/sys/net?*{,/**} wklx,\n"
237 " deny /sys/[^fdck]*{,/**} wklx,\n"
238 " deny /sys/c[^l]*{,/**} wklx,\n"
239 " deny /sys/cl[^a]*{,/**} wklx,\n"
240 " deny /sys/cla[^s]*{,/**} wklx,\n"
241 " deny /sys/clas[^s]*{,/**} wklx,\n"
242 " deny /sys/class/[^n]*{,/**} wklx,\n"
243 " deny /sys/class/n[^e]*{,/**} wklx,\n"
244 " deny /sys/class/ne[^t]*{,/**} wklx,\n"
245 " deny /sys/class/net?*{,/**} wklx,\n"
246 " deny /sys/class?*{,/**} wklx,\n"
247 " deny /sys/d[^e]*{,/**} wklx,\n"
248 " deny /sys/de[^v]*{,/**} wklx,\n"
249 " deny /sys/dev[^i]*{,/**} wklx,\n"
250 " deny /sys/devi[^c]*{,/**} wklx,\n"
251 " deny /sys/devic[^e]*{,/**} wklx,\n"
252 " deny /sys/device[^s]*{,/**} wklx,\n"
253 " deny /sys/devices/[^v]*{,/**} wklx,\n"
254 " deny /sys/devices/v[^i]*{,/**} wklx,\n"
255 " deny /sys/devices/vi[^r]*{,/**} wklx,\n"
256 " deny /sys/devices/vir[^t]*{,/**} wklx,\n"
257 " deny /sys/devices/virt[^u]*{,/**} wklx,\n"
258 " deny /sys/devices/virtu[^a]*{,/**} wklx,\n"
259 " deny /sys/devices/virtua[^l]*{,/**} wklx,\n"
260 " deny /sys/devices/virtual/[^n]*{,/**} wklx,\n"
261 " deny /sys/devices/virtual/n[^e]*{,/**} wklx,\n"
262 " deny /sys/devices/virtual/ne[^t]*{,/**} wklx,\n"
263 " deny /sys/devices/virtual/net?*{,/**} wklx,\n"
264 " deny /sys/devices/virtual?*{,/**} wklx,\n"
265 " deny /sys/devices?*{,/**} wklx,\n"
266 " deny /sys/f[^s]*{,/**} wklx,\n"
267 " deny /sys/fs/[^c]*{,/**} wklx,\n"
268 " deny /sys/fs/c[^g]*{,/**} wklx,\n"
269 " deny /sys/fs/cg[^r]*{,/**} wklx,\n"
270 " deny /sys/fs/cgr[^o]*{,/**} wklx,\n"
271 " deny /sys/fs/cgro[^u]*{,/**} wklx,\n"
272 " deny /sys/fs/cgrou[^p]*{,/**} wklx,\n"
273 " deny /sys/fs/cgroup?*{,/**} wklx,\n"
274 " deny /sys/fs?*{,/**} wklx,\n"
277 static const char AA_PROFILE_UNIX_SOCKETS
[] =
279 " ### Feature: unix\n"
280 " # Allow receive via unix sockets from anywhere\n"
283 " # Allow all unix sockets in the container\n"
284 " unix peer=(label=@{profile_name}),\n"
287 static const char AA_PROFILE_CGROUP_NAMESPACES
[] =
289 " ### Feature: cgroup namespace\n"
290 " mount fstype=cgroup -> /sys/fs/cgroup/**,\n"
291 " mount fstype=cgroup2 -> /sys/fs/cgroup/**,\n"
294 /* '_BASE' because we still need to append generated change_profile rules */
295 static const char AA_PROFILE_STACKING_BASE
[] =
297 " ### Feature: apparmor stacking\n"
298 " ### Configuration: apparmor profile loading (in namespace)\n"
299 " deny /sys/k[^e]*{,/**} wklx,\n"
300 " deny /sys/ke[^r]*{,/**} wklx,\n"
301 " deny /sys/ker[^n]*{,/**} wklx,\n"
302 " deny /sys/kern[^e]*{,/**} wklx,\n"
303 " deny /sys/kerne[^l]*{,/**} wklx,\n"
304 " deny /sys/kernel/[^s]*{,/**} wklx,\n"
305 " deny /sys/kernel/s[^e]*{,/**} wklx,\n"
306 " deny /sys/kernel/se[^c]*{,/**} wklx,\n"
307 " deny /sys/kernel/sec[^u]*{,/**} wklx,\n"
308 " deny /sys/kernel/secu[^r]*{,/**} wklx,\n"
309 " deny /sys/kernel/secur[^i]*{,/**} wklx,\n"
310 " deny /sys/kernel/securi[^t]*{,/**} wklx,\n"
311 " deny /sys/kernel/securit[^y]*{,/**} wklx,\n"
312 " deny /sys/kernel/security/[^a]*{,/**} wklx,\n"
313 " deny /sys/kernel/security/a[^p]*{,/**} wklx,\n"
314 " deny /sys/kernel/security/ap[^p]*{,/**} wklx,\n"
315 " deny /sys/kernel/security/app[^a]*{,/**} wklx,\n"
316 " deny /sys/kernel/security/appa[^r]*{,/**} wklx,\n"
317 " deny /sys/kernel/security/appar[^m]*{,/**} wklx,\n"
318 " deny /sys/kernel/security/apparm[^o]*{,/**} wklx,\n"
319 " deny /sys/kernel/security/apparmo[^r]*{,/**} wklx,\n"
320 " deny /sys/kernel/security/apparmor?*{,/**} wklx,\n"
321 " deny /sys/kernel/security?*{,/**} wklx,\n"
322 " deny /sys/kernel?*{,/**} wklx,\n"
325 static const char AA_PROFILE_NO_STACKING
[] =
327 " ### Feature: apparmor stacking (not present)\n"
328 " deny /sys/k*{,/**} rwklx,\n"
331 /* '_BASE' because we need to append change_profile for stacking */
332 static const char AA_PROFILE_NESTING_BASE
[] =
334 " ### Configuration: nesting\n"
339 /* NOTE: See conf.c's "nesting_helpers" for details. */
340 " deny /dev/.lxc/proc/** rw,\n"
341 " deny /dev/.lxc/sys/** rw,\n"
343 " mount fstype=proc -> /usr/lib/*/lxc/**,\n"
344 " mount fstype=sysfs -> /usr/lib/*/lxc/**,\n"
345 " mount options=(rw,bind),\n"
346 " mount options=(rw,rbind),\n"
347 " mount options=(rw,make-rshared),\n"
349 /* FIXME: What's the state here on apparmor's side? */
350 " # there doesn't seem to be a way to ask for:\n"
351 " # mount options=(ro,nosuid,nodev,noexec,remount,bind),\n"
352 " # as we always get mount to $cdir/proc/sys with those flags denied\n"
353 " # So allow all mounts until that is straightened out:\n"
357 static const char AA_PROFILE_UNPRIVILEGED
[] =
359 " ### Configuration: unprivileged container\n"
362 " # Allow modifying mount propagation\n"
363 " mount options=(rw,make-slave) -> **,\n"
364 " mount options=(rw,make-rslave) -> **,\n"
365 " mount options=(rw,make-shared) -> **,\n"
366 " mount options=(rw,make-rshared) -> **,\n"
367 " mount options=(rw,make-private) -> **,\n"
368 " mount options=(rw,make-rprivate) -> **,\n"
369 " mount options=(rw,make-unbindable) -> **,\n"
370 " mount options=(rw,make-runbindable) -> **,\n"
372 " # Allow all bind-mounts\n"
373 " mount options=(rw,bind),\n"
374 " mount options=(rw,rbind),\n"
376 " # Allow remounting things read-only\n"
377 " mount options=(ro,remount),\n"
380 static bool check_mount_feature_enabled(void)
382 return mount_features_enabled
== 1;
385 static void load_mount_features_enabled(void)
390 ret
= stat(AA_MOUNT_RESTR
, &statbuf
);
392 mount_features_enabled
= 1;
395 /* aa_getcon is not working right now. Use our hand-rolled version below */
396 static int apparmor_enabled(void)
402 fin
= fopen_cloexec(AA_ENABLED_FILE
, "r");
405 ret
= fscanf(fin
, "%c", &e
);
407 if (ret
== 1 && e
== 'Y') {
408 load_mount_features_enabled();
415 static char *apparmor_process_label_get(pid_t pid
)
417 char path
[100], *space
;
419 char *buf
= NULL
, *newbuf
;
423 ret
= snprintf(path
, 100, "/proc/%d/attr/current", pid
);
424 if (ret
< 0 || ret
>= 100) {
425 ERROR("path name too long");
429 f
= fopen_cloexec(path
, "r");
431 SYSERROR("opening %s", path
);
436 newbuf
= realloc(buf
, sz
);
439 ERROR("out of memory");
445 ret
= fread(buf
, 1, sz
- 1, f
);
448 ERROR("reading %s", path
);
454 space
= strchr(buf
, '\n');
457 space
= strchr(buf
, ' ');
464 * Probably makes sense to reorganize these to only read
467 static bool apparmor_am_unconfined(void)
469 char *p
= apparmor_process_label_get(lxc_raw_getpid());
471 if (!p
|| strcmp(p
, "unconfined") == 0)
477 static bool aa_needs_transition(char *curlabel
)
481 if (strcmp(curlabel
, "unconfined") == 0)
483 if (strcmp(curlabel
, "/usr/bin/lxc-start") == 0)
488 static inline void uint64hex(char *buf
, uint64_t num
)
494 char c
= (char)(num
& 0xf);
495 buf
[i
] = c
+ (c
< 0xa ? '0' : 'a' - 0xa);
500 static inline char *shorten_apparmor_name(char *name
)
502 size_t len
= strlen(name
);
505 hash
= fnv_64a_buf(name
, len
, FNV1A_64_INIT
);
506 name
= must_realloc(name
, 16 + 1);
507 uint64hex(name
, hash
);
513 /* Replace slashes with hyphens */
514 static inline void sanitize_path(char *path
)
518 for (i
= 0; path
[i
]; i
++)
523 static inline char *apparmor_dir(const char *ctname
, const char *lxcpath
)
525 return must_make_path(lxcpath
, ctname
, "apparmor", NULL
);
529 static inline char *apparmor_profile_full(const char *ctname
, const char *lxcpath
)
531 return shorten_apparmor_name(must_concat("lxc-", ctname
, "_<", lxcpath
, ">", NULL
));
534 /* Like apparmor_profile_full() but with slashes replaced by hyphens */
535 static inline char *apparmor_namespace(const char *ctname
, const char *lxcpath
)
539 full
= apparmor_profile_full(ctname
, lxcpath
);
545 /* FIXME: This is currently run only in the context of a constructor (via the
546 * initial lsm_init() called due to its __attribute__((constructor)), so we
547 * do not have ERROR/... macros available, so there are some fprintf(stderr)s
550 static bool check_apparmor_parser_version()
552 struct lxc_popen_FILE
*parserpipe
;
554 int major
= 0, minor
= 0, micro
= 0;
556 parserpipe
= lxc_popen("apparmor_parser --version");
558 fprintf(stderr
, "Failed to run check for apparmor_parser\n");
562 rc
= fscanf(parserpipe
->f
, "AppArmor parser version %d.%d.%d", &major
, &minor
, µ
);
564 lxc_pclose(parserpipe
);
565 /* We stay silent for now as this most likely means the shell
566 * lxc_popen executed failed to find the apparmor_parser binary.
567 * See the FIXME comment above for details.
572 rc
= lxc_pclose(parserpipe
);
574 fprintf(stderr
, "Error waiting for child process\n");
578 fprintf(stderr
, "'apparmor_parser --version' executed with an error status\n");
582 aa_supports_unix
= (major
> 2) ||
583 (major
== 2 && minor
> 10) ||
584 (major
== 2 && minor
== 10 && micro
>= 95);
589 static bool file_is_yes(const char *path
)
593 char buf
[8]; /* we actually just expect "yes" or "no" */
595 fd
= open(path
, O_RDONLY
| O_CLOEXEC
);
599 rd
= lxc_read_nointr(fd
, buf
, sizeof(buf
));
602 return rd
>= 4 && strncmp(buf
, "yes\n", 4) == 0;
605 static bool apparmor_can_stack()
607 int major
, minor
, scanned
;
610 if (!file_is_yes("/sys/kernel/security/apparmor/features/domain/stack"))
613 f
= fopen_cloexec("/sys/kernel/security/apparmor/features/domain/version", "r");
617 scanned
= fscanf(f
, "%d.%d", &major
, &minor
);
622 return major
> 1 || (major
== 1 && minor
>= 2);
625 static void must_append_sized_full(char **buf
, size_t *bufsz
, const char *data
,
626 size_t size
, bool append_newline
)
628 size_t newsize
= *bufsz
+ size
;
633 *buf
= must_realloc(*buf
, newsize
);
634 memcpy(*buf
+ *bufsz
, data
, size
);
637 (*buf
)[newsize
- 1] = '\n';
642 static void must_append_sized(char **buf
, size_t *bufsz
, const char *data
, size_t size
)
644 return must_append_sized_full(buf
, bufsz
, data
, size
, false);
647 static bool is_privileged(struct lxc_conf
*conf
)
649 return lxc_list_empty(&conf
->id_map
);
652 static char *get_apparmor_profile_content(struct lxc_conf
*conf
, const char *lxcpath
)
654 char *profile
, *profile_name_full
;
658 profile_name_full
= apparmor_profile_full(conf
->name
, lxcpath
);
660 profile
= must_concat(
661 "#include <tunables/global>\n"
662 "profile \"", profile_name_full
, "\" flags=(attach_disconnected,mediate_deleted) {\n",
664 size
= strlen(profile
);
666 must_append_sized(&profile
, &size
, AA_PROFILE_BASE
,
667 STRARRAYLEN(AA_PROFILE_BASE
));
669 if (aa_supports_unix
)
670 must_append_sized(&profile
, &size
, AA_PROFILE_UNIX_SOCKETS
,
671 STRARRAYLEN(AA_PROFILE_UNIX_SOCKETS
));
673 if (file_exists("/proc/self/ns/cgroup"))
674 must_append_sized(&profile
, &size
, AA_PROFILE_CGROUP_NAMESPACES
,
675 STRARRAYLEN(AA_PROFILE_CGROUP_NAMESPACES
));
677 if (aa_can_stack
&& !aa_is_stacked
) {
678 char *namespace, *temp
;
680 must_append_sized(&profile
, &size
, AA_PROFILE_STACKING_BASE
,
681 STRARRAYLEN(AA_PROFILE_STACKING_BASE
));
683 namespace = apparmor_namespace(conf
->name
, lxcpath
);
684 temp
= must_concat(" change_profile -> \":", namespace, ":*\",\n"
685 " change_profile -> \":", namespace, "://*\",\n",
689 must_append_sized(&profile
, &size
, temp
, strlen(temp
));
692 must_append_sized(&profile
, &size
, AA_PROFILE_NO_STACKING
,
693 STRARRAYLEN(AA_PROFILE_NO_STACKING
));
696 if (conf
->lsm_aa_allow_nesting
) {
697 must_append_sized(&profile
, &size
, AA_PROFILE_NESTING_BASE
,
698 STRARRAYLEN(AA_PROFILE_NESTING_BASE
));
700 if (!aa_can_stack
|| aa_is_stacked
) {
703 temp
= must_concat(" change_profile -> \"",
704 profile_name_full
, "\",\n", NULL
);
705 must_append_sized(&profile
, &size
, temp
, strlen(temp
));
710 if (!is_privileged(conf
) || am_host_unpriv())
711 must_append_sized(&profile
, &size
, AA_PROFILE_UNPRIVILEGED
,
712 STRARRAYLEN(AA_PROFILE_UNPRIVILEGED
));
714 lxc_list_for_each(it
, &conf
->lsm_aa_raw
) {
715 const char *line
= it
->elem
;
717 must_append_sized_full(&profile
, &size
, line
, strlen(line
), true);
720 /* include terminating \0 byte */
721 must_append_sized(&profile
, &size
, "}\n", 3);
723 free(profile_name_full
);
729 * apparmor_parser creates a cache file using the parsed file's name as a name.
730 * This means there may be multiple containers with the same name but different
731 * lxcpaths. Therefore we need a sanitized version of the complete profile name
732 * as profile file-name.
733 * We already get this exactly from apparmor_namespace().
735 static char *make_apparmor_profile_path(const char *ctname
, const char *lxcpath
)
737 char *ret
, *filename
;
739 filename
= apparmor_namespace(ctname
, lxcpath
);
740 ret
= must_make_path(lxcpath
, ctname
, "apparmor", filename
, NULL
);
746 static char *make_apparmor_namespace_path(const char *ctname
, const char *lxcpath
)
748 char *ret
, *namespace;
750 namespace = apparmor_namespace(ctname
, lxcpath
);
751 ret
= must_make_path("/sys/kernel/security/apparmor/policy/namespaces", namespace, NULL
);
757 static bool make_apparmor_namespace(struct lxc_conf
*conf
, const char *lxcpath
)
761 if (!aa_can_stack
|| aa_is_stacked
)
764 path
= make_apparmor_namespace_path(conf
->name
, lxcpath
);
766 if (mkdir(path
, 0755) < 0 && errno
!= EEXIST
) {
767 SYSERROR("Error creating AppArmor namespace: %s", path
);
776 static void remove_apparmor_namespace(struct lxc_conf
*conf
, const char *lxcpath
)
780 path
= make_apparmor_namespace_path(conf
->name
, lxcpath
);
781 if (rmdir(path
) != 0)
782 SYSERROR("Error removing AppArmor namespace");
786 struct apparmor_parser_args
{
791 static int apparmor_parser_exec(void *data
)
793 struct apparmor_parser_args
*args
= data
;
794 char cmdbuf
[] = { '-', args
->cmd
, 'W', 'L', 0 };
796 execlp("apparmor_parser", "apparmor_parser", cmdbuf
, APPARMOR_CACHE_DIR
, args
->file
, NULL
);
801 static int run_apparmor_parser(char command
,
802 struct lxc_conf
*conf
,
805 char output
[PATH_MAX
];
807 struct apparmor_parser_args args
= {
809 .file
= make_apparmor_profile_path(conf
->name
, lxcpath
),
812 ret
= run_command(output
, sizeof(output
), apparmor_parser_exec
, (void*)&args
);
814 ERROR("Failed to run apparmor_parser on \"%s\": %s", args
.file
, output
);
823 static void remove_apparmor_profile(struct lxc_conf
*conf
, const char *lxcpath
)
827 /* It's ok if these deletes fail: if the container was never started,
828 * we'll have never written a profile or cached it.
831 path
= make_apparmor_profile_path(conf
->name
, lxcpath
);
835 /* Also remove the apparmor/ subdirectory */
836 path
= apparmor_dir(conf
->name
, lxcpath
);
841 static int load_apparmor_profile(struct lxc_conf
*conf
, const char *lxcpath
)
843 struct stat profile_sb
;
847 char *profile_path
= NULL
, *old_content
= NULL
, *new_content
= NULL
;
850 if (!make_apparmor_namespace(conf
, lxcpath
))
853 /* In order to avoid forcing a profile parse (potentially slow) on
854 * every container start, let's use apparmor's binary policy cache,
855 * which checks mtime of the files to figure out if the policy needs to
858 * Since it uses mtimes, we shouldn't just always write out our local
859 * apparmor template; instead we should check to see whether the
860 * template is the same as ours. If it isn't we should write our
861 * version out so that the new changes are reflected and we definitely
865 profile_path
= make_apparmor_profile_path(conf
->name
, lxcpath
);
866 profile_fd
= open(profile_path
, O_RDONLY
| O_CLOEXEC
);
867 if (profile_fd
>= 0) {
868 if (fstat(profile_fd
, &profile_sb
) < 0) {
869 SYSERROR("Error accessing old profile from %s",
873 old_len
= profile_sb
.st_size
;
874 old_content
= lxc_strmmap(NULL
, old_len
, PROT_READ
,
875 MAP_PRIVATE
, profile_fd
, 0);
877 SYSERROR("Failed to mmap old profile from %s",
881 } else if (errno
!= ENOENT
) {
882 SYSERROR("Error reading old profile from %s", profile_path
);
886 new_content
= get_apparmor_profile_content(conf
, lxcpath
);
890 content_len
= strlen(new_content
);
892 if (!old_content
|| old_len
!= content_len
|| memcmp(old_content
, new_content
, content_len
) != 0) {
895 ret
= mkdir_p(APPARMOR_CACHE_DIR
, 0755);
897 SYSERROR("Error creating AppArmor profile cache directory " APPARMOR_CACHE_DIR
);
901 path
= apparmor_dir(conf
->name
, lxcpath
);
902 ret
= mkdir_p(path
, 0755);
904 SYSERROR("Error creating AppArmor profile directory: %s", path
);
910 ret
= lxc_write_to_file(profile_path
, new_content
, content_len
, false, 0600);
912 SYSERROR("Error writing profile to %s", profile_path
);
917 ret
= run_apparmor_parser(AA_CMD_LOAD
, conf
, lxcpath
);
919 goto out_remove_profile
;
921 conf
->lsm_aa_profile_created
= true;
926 remove_apparmor_profile(conf
, lxcpath
);
928 remove_apparmor_namespace(conf
, lxcpath
);
930 if (profile_fd
>= 0) {
932 lxc_strmunmap(old_content
, old_len
);
941 * Ensure that the container's policy namespace is unloaded to free kernel
942 * memory. This does not delete the policy from disk or cache.
944 static void apparmor_cleanup(struct lxc_conf
*conf
, const char *lxcpath
)
949 if (!conf
->lsm_aa_profile_created
)
952 remove_apparmor_namespace(conf
, lxcpath
);
953 (void)run_apparmor_parser(AA_CMD_UNLOAD
, conf
, lxcpath
);
955 remove_apparmor_profile(conf
, lxcpath
);
958 static int apparmor_prepare(struct lxc_conf
*conf
, const char *lxcpath
)
962 char *curlabel
= NULL
, *genlabel
= NULL
;
965 ERROR("AppArmor not enabled");
969 label
= conf
->lsm_aa_profile
;
971 /* user may request that we just ignore apparmor */
972 if (label
&& strcmp(label
, AA_UNCHANGED
) == 0) {
973 INFO("AppArmor profile unchanged per user request");
974 conf
->lsm_aa_profile_computed
= must_copy_string(label
);
978 if (label
&& strcmp(label
, AA_GENERATED
) == 0) {
979 if (!aa_parser_available
) {
980 ERROR("Cannot use generated profile: apparmor_parser not available");
984 /* auto-generate profile based on available/requested security features */
985 if (load_apparmor_profile(conf
, lxcpath
) != 0) {
986 ERROR("Failed to load generated AppArmor profile");
990 genlabel
= apparmor_profile_full(conf
->name
, lxcpath
);
992 ERROR("Failed to build AppArmor profile name");
996 if (aa_can_stack
&& !aa_is_stacked
) {
997 char *namespace = apparmor_namespace(conf
->name
, lxcpath
);
998 size_t llen
= strlen(genlabel
);
999 must_append_sized(&genlabel
, &llen
, "//&:", STRARRAYLEN("//&:"));
1000 must_append_sized(&genlabel
, &llen
, namespace, strlen(namespace));
1001 must_append_sized(&genlabel
, &llen
, ":", STRARRAYLEN(":") + 1); /* with the nul byte */
1008 curlabel
= apparmor_process_label_get(lxc_raw_getpid());
1010 if (!aa_can_stack
&& aa_needs_transition(curlabel
)) {
1011 /* we're already confined, and stacking isn't supported */
1013 if (!label
|| strcmp(curlabel
, label
) == 0) {
1014 /* no change requested */
1019 ERROR("Already AppArmor confined, but new label requested.");
1024 if (cgns_supported())
1025 label
= AA_DEF_PROFILE_CGNS
;
1027 label
= AA_DEF_PROFILE
;
1030 if (!check_mount_feature_enabled() && strcmp(label
, "unconfined") != 0) {
1031 WARN("Incomplete AppArmor support in your kernel");
1032 if (!conf
->lsm_aa_allow_incomplete
) {
1033 ERROR("If you really want to start this container, set");
1034 ERROR("lxc.apparmor.allow_incomplete = 1");
1035 ERROR("in your container configuration file");
1040 conf
->lsm_aa_profile_computed
= must_copy_string(label
);
1047 apparmor_cleanup(conf
, lxcpath
);
1054 * apparmor_process_label_set: Set AppArmor process profile
1056 * @label : the profile to set
1057 * @conf : the container configuration to use if @label is NULL
1058 * @default : use the default profile if @label is NULL
1059 * @on_exec : this is ignored. Apparmor profile will be changed immediately
1061 * Returns 0 on success, < 0 on failure
1063 * Notes: This relies on /proc being available.
1065 static int apparmor_process_label_set(const char *inlabel
, struct lxc_conf
*conf
,
1073 ERROR("AppArmor not enabled");
1077 label
= inlabel
? inlabel
: conf
->lsm_aa_profile_computed
;
1079 ERROR("LSM wasn't prepared");
1083 /* user may request that we just ignore apparmor */
1084 if (strcmp(label
, AA_UNCHANGED
) == 0) {
1085 INFO("AppArmor profile unchanged per user request");
1089 if (strcmp(label
, "unconfined") == 0 && apparmor_am_unconfined()) {
1090 INFO("AppArmor profile unchanged");
1093 tid
= lxc_raw_gettid();
1094 label_fd
= lsm_process_label_fd_get(tid
, on_exec
);
1096 SYSERROR("Failed to change AppArmor profile to %s", label
);
1100 ret
= lsm_process_label_set_at(label_fd
, label
, on_exec
);
1103 ERROR("Failed to change AppArmor profile to %s", label
);
1107 INFO("Changed AppArmor profile to %s", label
);
1111 static struct lsm_drv apparmor_drv
= {
1113 .enabled
= apparmor_enabled
,
1114 .process_label_get
= apparmor_process_label_get
,
1115 .process_label_set
= apparmor_process_label_set
,
1116 .prepare
= apparmor_prepare
,
1117 .cleanup
= apparmor_cleanup
,
1120 struct lsm_drv
*lsm_apparmor_drv_init(void)
1122 bool have_mac_admin
= false;
1124 if (!apparmor_enabled())
1127 /* We only support generated profiles when apparmor_parser is usable */
1128 if (!check_apparmor_parser_version())
1131 aa_parser_available
= true;
1133 aa_can_stack
= apparmor_can_stack();
1135 aa_is_stacked
= file_is_yes("/sys/kernel/security/apparmor/.ns_stacked");
1138 have_mac_admin
= lxc_proc_cap_is_set(CAP_SETGID
, CAP_EFFECTIVE
);
1141 if (!have_mac_admin
)
1142 WARN("Per-container AppArmor profiles are disabled because the mac_admin capability is missing");
1143 else if (am_host_unpriv() && !aa_is_stacked
)
1144 WARN("Per-container AppArmor profiles are disabled because LXC is running in an unprivileged container without stacking");
1150 return &apparmor_drv
;