]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blame - security/apparmor/lsm.c
apparmor: add mount mediation
[mirror_ubuntu-artful-kernel.git] / security / apparmor / lsm.c
CommitLineData
b5e95b48
JJ
1/*
2 * AppArmor security module
3 *
4 * This file contains AppArmor LSM hooks.
5 *
6 * Copyright (C) 1998-2008 Novell/SUSE
7 * Copyright 2009-2010 Canonical Ltd.
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation, version 2 of the
12 * License.
13 */
14
3c4ed7bd 15#include <linux/lsm_hooks.h>
b5e95b48
JJ
16#include <linux/moduleparam.h>
17#include <linux/mm.h>
18#include <linux/mman.h>
19#include <linux/mount.h>
20#include <linux/namei.h>
21#include <linux/ptrace.h>
22#include <linux/ctype.h>
23#include <linux/sysctl.h>
24#include <linux/audit.h>
3486740a 25#include <linux/user_namespace.h>
e025be0f 26#include <linux/kmemleak.h>
b5e95b48
JJ
27#include <net/sock.h>
28
29#include "include/apparmor.h"
30#include "include/apparmorfs.h"
31#include "include/audit.h"
32#include "include/capability.h"
33#include "include/context.h"
34#include "include/file.h"
35#include "include/ipc.h"
36#include "include/path.h"
637f688d 37#include "include/label.h"
b5e95b48 38#include "include/policy.h"
cff281f6 39#include "include/policy_ns.h"
b5e95b48 40#include "include/procattr.h"
21fad8c3 41#include "include/mount.h"
b5e95b48
JJ
42
43/* Flag indicating whether initialization completed */
545de8fe 44int apparmor_initialized;
b5e95b48 45
d4669f0b
JJ
46DEFINE_PER_CPU(struct aa_buffers, aa_buffers);
47
48
b5e95b48
JJ
49/*
50 * LSM hook functions
51 */
52
53/*
637f688d 54 * free the associated aa_task_ctx and put its labels
b5e95b48
JJ
55 */
56static void apparmor_cred_free(struct cred *cred)
57{
55a26ebf
JJ
58 aa_free_task_context(cred_ctx(cred));
59 cred_ctx(cred) = NULL;
b5e95b48
JJ
60}
61
62/*
63 * allocate the apparmor part of blank credentials
64 */
65static int apparmor_cred_alloc_blank(struct cred *cred, gfp_t gfp)
66{
67 /* freed by apparmor_cred_free */
55a26ebf
JJ
68 struct aa_task_ctx *ctx = aa_alloc_task_context(gfp);
69
70 if (!ctx)
b5e95b48
JJ
71 return -ENOMEM;
72
55a26ebf 73 cred_ctx(cred) = ctx;
b5e95b48
JJ
74 return 0;
75}
76
77/*
55a26ebf 78 * prepare new aa_task_ctx for modification by prepare_cred block
b5e95b48
JJ
79 */
80static int apparmor_cred_prepare(struct cred *new, const struct cred *old,
81 gfp_t gfp)
82{
83 /* freed by apparmor_cred_free */
55a26ebf
JJ
84 struct aa_task_ctx *ctx = aa_alloc_task_context(gfp);
85
86 if (!ctx)
b5e95b48
JJ
87 return -ENOMEM;
88
55a26ebf
JJ
89 aa_dup_task_context(ctx, cred_ctx(old));
90 cred_ctx(new) = ctx;
b5e95b48
JJ
91 return 0;
92}
93
94/*
95 * transfer the apparmor data to a blank set of creds
96 */
97static void apparmor_cred_transfer(struct cred *new, const struct cred *old)
98{
55a26ebf
JJ
99 const struct aa_task_ctx *old_ctx = cred_ctx(old);
100 struct aa_task_ctx *new_ctx = cred_ctx(new);
b5e95b48 101
55a26ebf 102 aa_dup_task_context(new_ctx, old_ctx);
b5e95b48
JJ
103}
104
105static int apparmor_ptrace_access_check(struct task_struct *child,
106 unsigned int mode)
107{
b2d09ae4
JJ
108 struct aa_label *tracer, *tracee;
109 int error;
110
111 tracer = begin_current_label_crit_section();
112 tracee = aa_get_task_label(child);
113 error = aa_may_ptrace(tracer, tracee,
114 mode == PTRACE_MODE_READ ? AA_PTRACE_READ : AA_PTRACE_TRACE);
115 aa_put_label(tracee);
116 end_current_label_crit_section(tracer);
117
118 return error;
b5e95b48
JJ
119}
120
121static int apparmor_ptrace_traceme(struct task_struct *parent)
122{
b2d09ae4
JJ
123 struct aa_label *tracer, *tracee;
124 int error;
125
126 tracee = begin_current_label_crit_section();
127 tracer = aa_get_task_label(parent);
128 error = aa_may_ptrace(tracer, tracee, AA_PTRACE_TRACE);
129 aa_put_label(tracer);
130 end_current_label_crit_section(tracee);
131
132 return error;
b5e95b48
JJ
133}
134
135/* Derived from security/commoncap.c:cap_capget */
136static int apparmor_capget(struct task_struct *target, kernel_cap_t *effective,
137 kernel_cap_t *inheritable, kernel_cap_t *permitted)
138{
637f688d 139 struct aa_label *label;
b5e95b48
JJ
140 const struct cred *cred;
141
142 rcu_read_lock();
143 cred = __task_cred(target);
637f688d 144 label = aa_get_newest_cred_label(cred);
c70c86c4 145
b1d9e6b0
CS
146 /*
147 * cap_capget is stacked ahead of this and will
148 * initialize effective and permitted.
149 */
c70c86c4
JJ
150 if (!unconfined(label)) {
151 struct aa_profile *profile;
152 struct label_it i;
153
154 label_for_each_confined(i, label, profile) {
155 if (COMPLAIN_MODE(profile))
156 continue;
157 *effective = cap_intersect(*effective,
158 profile->caps.allow);
159 *permitted = cap_intersect(*permitted,
160 profile->caps.allow);
161 }
b5e95b48
JJ
162 }
163 rcu_read_unlock();
637f688d 164 aa_put_label(label);
b5e95b48
JJ
165
166 return 0;
167}
168
6a9de491
EP
169static int apparmor_capable(const struct cred *cred, struct user_namespace *ns,
170 int cap, int audit)
b5e95b48 171{
637f688d 172 struct aa_label *label;
b1d9e6b0
CS
173 int error = 0;
174
637f688d
JJ
175 label = aa_get_newest_cred_label(cred);
176 if (!unconfined(label))
c70c86c4 177 error = aa_capable(label, cap, audit);
637f688d 178 aa_put_label(label);
cf797c0e 179
b5e95b48
JJ
180 return error;
181}
182
183/**
184 * common_perm - basic common permission check wrapper fn for paths
185 * @op: operation being checked
186 * @path: path to check permission of (NOT NULL)
187 * @mask: requested permissions mask
188 * @cond: conditional info for the permission request (NOT NULL)
189 *
190 * Returns: %0 else error code if error or permission denied
191 */
47f6e5cc 192static int common_perm(const char *op, const struct path *path, u32 mask,
b5e95b48
JJ
193 struct path_cond *cond)
194{
637f688d 195 struct aa_label *label;
b5e95b48
JJ
196 int error = 0;
197
637f688d
JJ
198 label = __begin_current_label_crit_section();
199 if (!unconfined(label))
aebd873e 200 error = aa_path_perm(op, label, path, 0, mask, cond);
637f688d 201 __end_current_label_crit_section(label);
b5e95b48
JJ
202
203 return error;
204}
205
206/**
31f75bfe 207 * common_perm_cond - common permission wrapper around inode cond
b5e95b48 208 * @op: operation being checked
31f75bfe 209 * @path: location to check (NOT NULL)
b5e95b48 210 * @mask: requested permissions mask
b5e95b48
JJ
211 *
212 * Returns: %0 else error code if error or permission denied
213 */
31f75bfe 214static int common_perm_cond(const char *op, const struct path *path, u32 mask)
b5e95b48 215{
31f75bfe
JJ
216 struct path_cond cond = { d_backing_inode(path->dentry)->i_uid,
217 d_backing_inode(path->dentry)->i_mode
218 };
b5e95b48 219
31f75bfe
JJ
220 if (!path_mediated_fs(path->dentry))
221 return 0;
222
223 return common_perm(op, path, mask, &cond);
b5e95b48
JJ
224}
225
226/**
31f75bfe 227 * common_perm_dir_dentry - common permission wrapper when path is dir, dentry
b5e95b48 228 * @op: operation being checked
31f75bfe
JJ
229 * @dir: directory of the dentry (NOT NULL)
230 * @dentry: dentry to check (NOT NULL)
b5e95b48 231 * @mask: requested permissions mask
31f75bfe 232 * @cond: conditional info for the permission request (NOT NULL)
b5e95b48
JJ
233 *
234 * Returns: %0 else error code if error or permission denied
235 */
31f75bfe
JJ
236static int common_perm_dir_dentry(const char *op, const struct path *dir,
237 struct dentry *dentry, u32 mask,
238 struct path_cond *cond)
b5e95b48 239{
31f75bfe 240 struct path path = { .mnt = dir->mnt, .dentry = dentry };
b5e95b48 241
31f75bfe 242 return common_perm(op, &path, mask, cond);
b5e95b48
JJ
243}
244
245/**
246 * common_perm_rm - common permission wrapper for operations doing rm
247 * @op: operation being checked
248 * @dir: directory that the dentry is in (NOT NULL)
249 * @dentry: dentry being rm'd (NOT NULL)
250 * @mask: requested permission mask
251 *
252 * Returns: %0 else error code if error or permission denied
253 */
47f6e5cc 254static int common_perm_rm(const char *op, const struct path *dir,
b5e95b48
JJ
255 struct dentry *dentry, u32 mask)
256{
c6f493d6 257 struct inode *inode = d_backing_inode(dentry);
b5e95b48
JJ
258 struct path_cond cond = { };
259
efeee83a 260 if (!inode || !path_mediated_fs(dentry))
b5e95b48
JJ
261 return 0;
262
263 cond.uid = inode->i_uid;
264 cond.mode = inode->i_mode;
265
266 return common_perm_dir_dentry(op, dir, dentry, mask, &cond);
267}
268
269/**
270 * common_perm_create - common permission wrapper for operations doing create
271 * @op: operation being checked
272 * @dir: directory that dentry will be created in (NOT NULL)
273 * @dentry: dentry to create (NOT NULL)
274 * @mask: request permission mask
275 * @mode: created file mode
276 *
277 * Returns: %0 else error code if error or permission denied
278 */
47f6e5cc 279static int common_perm_create(const char *op, const struct path *dir,
d6b49f7a 280 struct dentry *dentry, u32 mask, umode_t mode)
b5e95b48
JJ
281{
282 struct path_cond cond = { current_fsuid(), mode };
283
efeee83a 284 if (!path_mediated_fs(dir->dentry))
b5e95b48
JJ
285 return 0;
286
287 return common_perm_dir_dentry(op, dir, dentry, mask, &cond);
288}
289
989f74e0 290static int apparmor_path_unlink(const struct path *dir, struct dentry *dentry)
b5e95b48
JJ
291{
292 return common_perm_rm(OP_UNLINK, dir, dentry, AA_MAY_DELETE);
293}
294
d3607752 295static int apparmor_path_mkdir(const struct path *dir, struct dentry *dentry,
4572befe 296 umode_t mode)
b5e95b48
JJ
297{
298 return common_perm_create(OP_MKDIR, dir, dentry, AA_MAY_CREATE,
299 S_IFDIR);
300}
301
989f74e0 302static int apparmor_path_rmdir(const struct path *dir, struct dentry *dentry)
b5e95b48
JJ
303{
304 return common_perm_rm(OP_RMDIR, dir, dentry, AA_MAY_DELETE);
305}
306
d3607752 307static int apparmor_path_mknod(const struct path *dir, struct dentry *dentry,
04fc66e7 308 umode_t mode, unsigned int dev)
b5e95b48
JJ
309{
310 return common_perm_create(OP_MKNOD, dir, dentry, AA_MAY_CREATE, mode);
311}
312
81f4c506 313static int apparmor_path_truncate(const struct path *path)
b5e95b48 314{
e53cfe6c 315 return common_perm_cond(OP_TRUNC, path, MAY_WRITE | AA_MAY_SETATTR);
b5e95b48
JJ
316}
317
d3607752 318static int apparmor_path_symlink(const struct path *dir, struct dentry *dentry,
b5e95b48
JJ
319 const char *old_name)
320{
321 return common_perm_create(OP_SYMLINK, dir, dentry, AA_MAY_CREATE,
322 S_IFLNK);
323}
324
3ccee46a 325static int apparmor_path_link(struct dentry *old_dentry, const struct path *new_dir,
b5e95b48
JJ
326 struct dentry *new_dentry)
327{
637f688d 328 struct aa_label *label;
b5e95b48
JJ
329 int error = 0;
330
efeee83a 331 if (!path_mediated_fs(old_dentry))
b5e95b48
JJ
332 return 0;
333
637f688d
JJ
334 label = begin_current_label_crit_section();
335 if (!unconfined(label))
8014370f 336 error = aa_path_link(label, old_dentry, new_dir, new_dentry);
637f688d 337 end_current_label_crit_section(label);
cf797c0e 338
b5e95b48
JJ
339 return error;
340}
341
3ccee46a
AV
342static int apparmor_path_rename(const struct path *old_dir, struct dentry *old_dentry,
343 const struct path *new_dir, struct dentry *new_dentry)
b5e95b48 344{
637f688d 345 struct aa_label *label;
b5e95b48
JJ
346 int error = 0;
347
efeee83a 348 if (!path_mediated_fs(old_dentry))
b5e95b48
JJ
349 return 0;
350
637f688d
JJ
351 label = begin_current_label_crit_section();
352 if (!unconfined(label)) {
8486adf0
KC
353 struct path old_path = { .mnt = old_dir->mnt,
354 .dentry = old_dentry };
355 struct path new_path = { .mnt = new_dir->mnt,
356 .dentry = new_dentry };
c6f493d6
DH
357 struct path_cond cond = { d_backing_inode(old_dentry)->i_uid,
358 d_backing_inode(old_dentry)->i_mode
b5e95b48
JJ
359 };
360
aebd873e 361 error = aa_path_perm(OP_RENAME_SRC, label, &old_path, 0,
e53cfe6c
JJ
362 MAY_READ | AA_MAY_GETATTR | MAY_WRITE |
363 AA_MAY_SETATTR | AA_MAY_DELETE,
b5e95b48
JJ
364 &cond);
365 if (!error)
aebd873e 366 error = aa_path_perm(OP_RENAME_DEST, label, &new_path,
e53cfe6c 367 0, MAY_WRITE | AA_MAY_SETATTR |
b5e95b48
JJ
368 AA_MAY_CREATE, &cond);
369
370 }
637f688d 371 end_current_label_crit_section(label);
cf797c0e 372
b5e95b48
JJ
373 return error;
374}
375
be01f9f2 376static int apparmor_path_chmod(const struct path *path, umode_t mode)
b5e95b48 377{
31f75bfe 378 return common_perm_cond(OP_CHMOD, path, AA_MAY_CHMOD);
b5e95b48
JJ
379}
380
7fd25dac 381static int apparmor_path_chown(const struct path *path, kuid_t uid, kgid_t gid)
b5e95b48 382{
31f75bfe 383 return common_perm_cond(OP_CHOWN, path, AA_MAY_CHOWN);
b5e95b48
JJ
384}
385
3f7036a0 386static int apparmor_inode_getattr(const struct path *path)
b5e95b48 387{
e53cfe6c 388 return common_perm_cond(OP_GETATTR, path, AA_MAY_GETATTR);
b5e95b48
JJ
389}
390
83d49856 391static int apparmor_file_open(struct file *file, const struct cred *cred)
b5e95b48 392{
637f688d
JJ
393 struct aa_file_ctx *fctx = file_ctx(file);
394 struct aa_label *label;
b5e95b48
JJ
395 int error = 0;
396
efeee83a 397 if (!path_mediated_fs(file->f_path.dentry))
b5e95b48
JJ
398 return 0;
399
400 /* If in exec, permission is handled by bprm hooks.
401 * Cache permissions granted by the previous exec check, with
402 * implicit read and executable mmap which are required to
403 * actually execute the image.
404 */
405 if (current->in_execve) {
55a26ebf 406 fctx->allow = MAY_EXEC | MAY_READ | AA_EXEC_MMAP;
b5e95b48
JJ
407 return 0;
408 }
409
637f688d
JJ
410 label = aa_get_newest_cred_label(cred);
411 if (!unconfined(label)) {
496ad9aa 412 struct inode *inode = file_inode(file);
b5e95b48
JJ
413 struct path_cond cond = { inode->i_uid, inode->i_mode };
414
aebd873e 415 error = aa_path_perm(OP_OPEN, label, &file->f_path, 0,
b5e95b48
JJ
416 aa_map_file_to_perms(file), &cond);
417 /* todo cache full allowed permissions set and state */
55a26ebf 418 fctx->allow = aa_map_file_to_perms(file);
b5e95b48 419 }
637f688d 420 aa_put_label(label);
b5e95b48
JJ
421
422 return error;
423}
424
425static int apparmor_file_alloc_security(struct file *file)
426{
cf797c0e
JJ
427 int error = 0;
428
b5e95b48 429 /* freed by apparmor_file_free_security */
637f688d 430 struct aa_label *label = begin_current_label_crit_section();
190a9518 431 file->f_security = aa_alloc_file_ctx(label, GFP_KERNEL);
2835a13b
JJ
432 if (!file_ctx(file))
433 error = -ENOMEM;
637f688d 434 end_current_label_crit_section(label);
b5e95b48 435
cf797c0e 436 return error;
b5e95b48
JJ
437}
438
439static void apparmor_file_free_security(struct file *file)
440{
2835a13b 441 aa_free_file_ctx(file_ctx(file));
b5e95b48
JJ
442}
443
47f6e5cc 444static int common_file_perm(const char *op, struct file *file, u32 mask)
b5e95b48 445{
190a9518 446 struct aa_label *label;
b5e95b48
JJ
447 int error = 0;
448
192ca6b5
JJ
449 /* don't reaudit files closed during inheritance */
450 if (file->f_path.dentry == aa_null.dentry)
451 return -EACCES;
452
637f688d 453 label = __begin_current_label_crit_section();
190a9518 454 error = aa_file_perm(op, label, file, mask);
637f688d 455 __end_current_label_crit_section(label);
b5e95b48
JJ
456
457 return error;
458}
459
064dc947
JJ
460static int apparmor_file_receive(struct file *file)
461{
462 return common_file_perm(OP_FRECEIVE, file, aa_map_file_to_perms(file));
463}
464
b5e95b48
JJ
465static int apparmor_file_permission(struct file *file, int mask)
466{
467 return common_file_perm(OP_FPERM, file, mask);
468}
469
470static int apparmor_file_lock(struct file *file, unsigned int cmd)
471{
472 u32 mask = AA_MAY_LOCK;
473
474 if (cmd == F_WRLCK)
475 mask |= MAY_WRITE;
476
477 return common_file_perm(OP_FLOCK, file, mask);
478}
479
47f6e5cc 480static int common_mmap(const char *op, struct file *file, unsigned long prot,
b5e95b48
JJ
481 unsigned long flags)
482{
b5e95b48
JJ
483 int mask = 0;
484
637f688d 485 if (!file || !file_ctx(file))
b5e95b48
JJ
486 return 0;
487
488 if (prot & PROT_READ)
489 mask |= MAY_READ;
490 /*
491 * Private mappings don't require write perms since they don't
492 * write back to the files
493 */
494 if ((prot & PROT_WRITE) && !(flags & MAP_PRIVATE))
495 mask |= MAY_WRITE;
496 if (prot & PROT_EXEC)
497 mask |= AA_EXEC_MMAP;
498
b5e95b48
JJ
499 return common_file_perm(op, file, mask);
500}
501
e5467859
AV
502static int apparmor_mmap_file(struct file *file, unsigned long reqprot,
503 unsigned long prot, unsigned long flags)
b5e95b48 504{
b5e95b48
JJ
505 return common_mmap(OP_FMMAP, file, prot, flags);
506}
507
508static int apparmor_file_mprotect(struct vm_area_struct *vma,
509 unsigned long reqprot, unsigned long prot)
510{
511 return common_mmap(OP_FMPROT, vma->vm_file, prot,
512 !(vma->vm_flags & VM_SHARED) ? MAP_PRIVATE : 0);
513}
514
21fad8c3
JJ
515static int apparmor_sb_mount(const char *dev_name, const struct path *path,
516 const char *type, unsigned long flags, void *data)
517{
518 struct aa_label *label;
519 int error = 0;
520
521 /* Discard magic */
522 if ((flags & MS_MGC_MSK) == MS_MGC_VAL)
523 flags &= ~MS_MGC_MSK;
524
525 flags &= ~AA_MS_IGNORE_MASK;
526
527 label = __begin_current_label_crit_section();
528 if (!unconfined(label)) {
529 if (flags & MS_REMOUNT)
530 error = aa_remount(label, path, flags, data);
531 else if (flags & MS_BIND)
532 error = aa_bind_mount(label, path, dev_name, flags);
533 else if (flags & (MS_SHARED | MS_PRIVATE | MS_SLAVE |
534 MS_UNBINDABLE))
535 error = aa_mount_change_type(label, path, flags);
536 else if (flags & MS_MOVE)
537 error = aa_move_mount(label, path, dev_name);
538 else
539 error = aa_new_mount(label, dev_name, path, type,
540 flags, data);
541 }
542 __end_current_label_crit_section(label);
543
544 return error;
545}
546
547static int apparmor_sb_umount(struct vfsmount *mnt, int flags)
548{
549 struct aa_label *label;
550 int error = 0;
551
552 label = __begin_current_label_crit_section();
553 if (!unconfined(label))
554 error = aa_umount(label, mnt, flags);
555 __end_current_label_crit_section(label);
556
557 return error;
558}
559
560static int apparmor_sb_pivotroot(const struct path *old_path,
561 const struct path *new_path)
562{
563 struct aa_label *label;
564 int error = 0;
565
566 label = aa_get_current_label();
567 if (!unconfined(label))
568 error = aa_pivotroot(label, old_path, new_path);
569 aa_put_label(label);
570
571 return error;
572}
573
b5e95b48
JJ
574static int apparmor_getprocattr(struct task_struct *task, char *name,
575 char **value)
576{
577 int error = -ENOENT;
b5e95b48
JJ
578 /* released below */
579 const struct cred *cred = get_task_cred(task);
55a26ebf 580 struct aa_task_ctx *ctx = cred_ctx(cred);
637f688d 581 struct aa_label *label = NULL;
b5e95b48
JJ
582
583 if (strcmp(name, "current") == 0)
637f688d 584 label = aa_get_newest_label(ctx->label);
55a26ebf 585 else if (strcmp(name, "prev") == 0 && ctx->previous)
637f688d 586 label = aa_get_newest_label(ctx->previous);
55a26ebf 587 else if (strcmp(name, "exec") == 0 && ctx->onexec)
637f688d 588 label = aa_get_newest_label(ctx->onexec);
b5e95b48
JJ
589 else
590 error = -EINVAL;
591
637f688d 592 if (label)
76a1d263 593 error = aa_getprocattr(label, value);
77b071b3 594
637f688d 595 aa_put_label(label);
b5e95b48
JJ
596 put_cred(cred);
597
598 return error;
599}
600
b21507e2
SS
601static int apparmor_setprocattr(const char *name, void *value,
602 size_t size)
b5e95b48 603{
e89b8081 604 char *command, *largs = NULL, *args = value;
b5e95b48
JJ
605 size_t arg_size;
606 int error;
ef88a7ac 607 DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_NONE, OP_SETPROCATTR);
b5e95b48
JJ
608
609 if (size == 0)
610 return -EINVAL;
b5e95b48 611
e89b8081
VN
612 /* AppArmor requires that the buffer must be null terminated atm */
613 if (args[size - 1] != '\0') {
614 /* null terminate */
615 largs = args = kmalloc(size + 1, GFP_KERNEL);
616 if (!args)
617 return -ENOMEM;
618 memcpy(args, value, size);
619 args[size] = '\0';
620 }
621
622 error = -EINVAL;
b5e95b48
JJ
623 args = strim(args);
624 command = strsep(&args, " ");
625 if (!args)
e89b8081 626 goto out;
b5e95b48
JJ
627 args = skip_spaces(args);
628 if (!*args)
e89b8081 629 goto out;
b5e95b48 630
d4d03f74 631 arg_size = size - (args - (largs ? largs : (char *) value));
b5e95b48
JJ
632 if (strcmp(name, "current") == 0) {
633 if (strcmp(command, "changehat") == 0) {
634 error = aa_setprocattr_changehat(args, arg_size,
df8073c6 635 AA_CHANGE_NOFLAGS);
b5e95b48
JJ
636 } else if (strcmp(command, "permhat") == 0) {
637 error = aa_setprocattr_changehat(args, arg_size,
df8073c6 638 AA_CHANGE_TEST);
b5e95b48 639 } else if (strcmp(command, "changeprofile") == 0) {
df8073c6 640 error = aa_change_profile(args, AA_CHANGE_NOFLAGS);
b5e95b48 641 } else if (strcmp(command, "permprofile") == 0) {
df8073c6 642 error = aa_change_profile(args, AA_CHANGE_TEST);
6c5fc8f1
JJ
643 } else if (strcmp(command, "stack") == 0) {
644 error = aa_change_profile(args, AA_CHANGE_STACK);
3eea57c2
JJ
645 } else
646 goto fail;
b5e95b48 647 } else if (strcmp(name, "exec") == 0) {
3eea57c2 648 if (strcmp(command, "exec") == 0)
df8073c6 649 error = aa_change_profile(args, AA_CHANGE_ONEXEC);
6c5fc8f1
JJ
650 else if (strcmp(command, "stack") == 0)
651 error = aa_change_profile(args, (AA_CHANGE_ONEXEC |
652 AA_CHANGE_STACK));
3eea57c2
JJ
653 else
654 goto fail;
655 } else
b5e95b48 656 /* only support the "current" and "exec" process attributes */
e89b8081 657 goto fail;
3eea57c2 658
b5e95b48
JJ
659 if (!error)
660 error = size;
e89b8081
VN
661out:
662 kfree(largs);
b5e95b48 663 return error;
3eea57c2
JJ
664
665fail:
637f688d 666 aad(&sa)->label = begin_current_label_crit_section();
ef88a7ac
JJ
667 aad(&sa)->info = name;
668 aad(&sa)->error = error = -EINVAL;
3eea57c2 669 aa_audit_msg(AUDIT_APPARMOR_DENIED, &sa, NULL);
637f688d 670 end_current_label_crit_section(aad(&sa)->label);
e89b8081 671 goto out;
b5e95b48
JJ
672}
673
fe864821
JJ
674/**
675 * apparmor_bprm_committing_creds - do task cleanup on committing new creds
676 * @bprm: binprm for the exec (NOT NULL)
677 */
678static void apparmor_bprm_committing_creds(struct linux_binprm *bprm)
679{
637f688d 680 struct aa_label *label = aa_current_raw_label();
fe864821
JJ
681 struct aa_task_ctx *new_ctx = cred_ctx(bprm->cred);
682
683 /* bail out if unconfined or not changing profile */
637f688d
JJ
684 if ((new_ctx->label->proxy == label->proxy) ||
685 (unconfined(new_ctx->label)))
fe864821
JJ
686 return;
687
192ca6b5
JJ
688 aa_inherit_files(bprm->cred, current->files);
689
fe864821
JJ
690 current->pdeath_signal = 0;
691
637f688d 692 /* reset soft limits and set hard limits for the new label */
86b92cb7 693 __aa_transition_rlimits(label, new_ctx->label);
fe864821
JJ
694}
695
696/**
697 * apparmor_bprm_committed_cred - do cleanup after new creds committed
698 * @bprm: binprm for the exec (NOT NULL)
699 */
700static void apparmor_bprm_committed_creds(struct linux_binprm *bprm)
701{
702 /* TODO: cleanup signals - ipc mediation */
703 return;
704}
705
7cb4dc9f
JS
706static int apparmor_task_setrlimit(struct task_struct *task,
707 unsigned int resource, struct rlimit *new_rlim)
b5e95b48 708{
637f688d 709 struct aa_label *label = __begin_current_label_crit_section();
b5e95b48
JJ
710 int error = 0;
711
637f688d 712 if (!unconfined(label))
86b92cb7 713 error = aa_task_setrlimit(label, task, resource, new_rlim);
637f688d 714 __end_current_label_crit_section(label);
b5e95b48
JJ
715
716 return error;
717}
718
84632f19
JJ
719static int apparmor_task_kill(struct task_struct *target, struct siginfo *info,
720 int sig, u32 secid)
721{
722 struct aa_label *cl, *tl;
723 int error;
724
725 if (secid)
726 /* TODO: after secid to label mapping is done.
727 * Dealing with USB IO specific behavior
728 */
729 return 0;
730 cl = __begin_current_label_crit_section();
731 tl = aa_get_task_label(target);
732 error = aa_may_signal(cl, tl, sig);
733 aa_put_label(tl);
734 __end_current_label_crit_section(cl);
735
736 return error;
737}
738
ca97d939 739static struct security_hook_list apparmor_hooks[] __lsm_ro_after_init = {
e20b043a
CS
740 LSM_HOOK_INIT(ptrace_access_check, apparmor_ptrace_access_check),
741 LSM_HOOK_INIT(ptrace_traceme, apparmor_ptrace_traceme),
742 LSM_HOOK_INIT(capget, apparmor_capget),
743 LSM_HOOK_INIT(capable, apparmor_capable),
744
21fad8c3
JJ
745 LSM_HOOK_INIT(sb_mount, apparmor_sb_mount),
746 LSM_HOOK_INIT(sb_umount, apparmor_sb_umount),
747 LSM_HOOK_INIT(sb_pivotroot, apparmor_sb_pivotroot),
748
e20b043a
CS
749 LSM_HOOK_INIT(path_link, apparmor_path_link),
750 LSM_HOOK_INIT(path_unlink, apparmor_path_unlink),
751 LSM_HOOK_INIT(path_symlink, apparmor_path_symlink),
752 LSM_HOOK_INIT(path_mkdir, apparmor_path_mkdir),
753 LSM_HOOK_INIT(path_rmdir, apparmor_path_rmdir),
754 LSM_HOOK_INIT(path_mknod, apparmor_path_mknod),
755 LSM_HOOK_INIT(path_rename, apparmor_path_rename),
756 LSM_HOOK_INIT(path_chmod, apparmor_path_chmod),
757 LSM_HOOK_INIT(path_chown, apparmor_path_chown),
758 LSM_HOOK_INIT(path_truncate, apparmor_path_truncate),
759 LSM_HOOK_INIT(inode_getattr, apparmor_inode_getattr),
760
761 LSM_HOOK_INIT(file_open, apparmor_file_open),
064dc947 762 LSM_HOOK_INIT(file_receive, apparmor_file_receive),
e20b043a
CS
763 LSM_HOOK_INIT(file_permission, apparmor_file_permission),
764 LSM_HOOK_INIT(file_alloc_security, apparmor_file_alloc_security),
765 LSM_HOOK_INIT(file_free_security, apparmor_file_free_security),
766 LSM_HOOK_INIT(mmap_file, apparmor_mmap_file),
e20b043a
CS
767 LSM_HOOK_INIT(file_mprotect, apparmor_file_mprotect),
768 LSM_HOOK_INIT(file_lock, apparmor_file_lock),
769
770 LSM_HOOK_INIT(getprocattr, apparmor_getprocattr),
771 LSM_HOOK_INIT(setprocattr, apparmor_setprocattr),
772
773 LSM_HOOK_INIT(cred_alloc_blank, apparmor_cred_alloc_blank),
774 LSM_HOOK_INIT(cred_free, apparmor_cred_free),
775 LSM_HOOK_INIT(cred_prepare, apparmor_cred_prepare),
776 LSM_HOOK_INIT(cred_transfer, apparmor_cred_transfer),
777
778 LSM_HOOK_INIT(bprm_set_creds, apparmor_bprm_set_creds),
779 LSM_HOOK_INIT(bprm_committing_creds, apparmor_bprm_committing_creds),
780 LSM_HOOK_INIT(bprm_committed_creds, apparmor_bprm_committed_creds),
781 LSM_HOOK_INIT(bprm_secureexec, apparmor_bprm_secureexec),
782
783 LSM_HOOK_INIT(task_setrlimit, apparmor_task_setrlimit),
84632f19 784 LSM_HOOK_INIT(task_kill, apparmor_task_kill),
b5e95b48
JJ
785};
786
787/*
788 * AppArmor sysfs module parameters
789 */
790
101d6c82
SR
791static int param_set_aabool(const char *val, const struct kernel_param *kp);
792static int param_get_aabool(char *buffer, const struct kernel_param *kp);
b8aa09fd 793#define param_check_aabool param_check_bool
9c27847d 794static const struct kernel_param_ops param_ops_aabool = {
6a4c2643 795 .flags = KERNEL_PARAM_OPS_FL_NOARG,
101d6c82
SR
796 .set = param_set_aabool,
797 .get = param_get_aabool
798};
b5e95b48 799
101d6c82
SR
800static int param_set_aauint(const char *val, const struct kernel_param *kp);
801static int param_get_aauint(char *buffer, const struct kernel_param *kp);
b8aa09fd 802#define param_check_aauint param_check_uint
9c27847d 803static const struct kernel_param_ops param_ops_aauint = {
101d6c82
SR
804 .set = param_set_aauint,
805 .get = param_get_aauint
806};
b5e95b48 807
101d6c82
SR
808static int param_set_aalockpolicy(const char *val, const struct kernel_param *kp);
809static int param_get_aalockpolicy(char *buffer, const struct kernel_param *kp);
b8aa09fd 810#define param_check_aalockpolicy param_check_bool
9c27847d 811static const struct kernel_param_ops param_ops_aalockpolicy = {
6a4c2643 812 .flags = KERNEL_PARAM_OPS_FL_NOARG,
101d6c82
SR
813 .set = param_set_aalockpolicy,
814 .get = param_get_aalockpolicy
815};
b5e95b48
JJ
816
817static int param_set_audit(const char *val, struct kernel_param *kp);
818static int param_get_audit(char *buffer, struct kernel_param *kp);
b5e95b48
JJ
819
820static int param_set_mode(const char *val, struct kernel_param *kp);
821static int param_get_mode(char *buffer, struct kernel_param *kp);
b5e95b48
JJ
822
823/* Flag values, also controllable via /sys/module/apparmor/parameters
824 * We define special types as we want to do additional mediation.
825 */
826
827/* AppArmor global enforcement switch - complain, enforce, kill */
828enum profile_mode aa_g_profile_mode = APPARMOR_ENFORCE;
829module_param_call(mode, param_set_mode, param_get_mode,
830 &aa_g_profile_mode, S_IRUSR | S_IWUSR);
831
6059f71f 832/* whether policy verification hashing is enabled */
7616ac70 833bool aa_g_hash_policy = IS_ENABLED(CONFIG_SECURITY_APPARMOR_HASH_DEFAULT);
3ccb76c5 834#ifdef CONFIG_SECURITY_APPARMOR_HASH
6059f71f 835module_param_named(hash_policy, aa_g_hash_policy, aabool, S_IRUSR | S_IWUSR);
7616ac70 836#endif
6059f71f 837
b5e95b48 838/* Debug mode */
eea7a05f 839bool aa_g_debug = IS_ENABLED(CONFIG_SECURITY_APPARMOR_DEBUG_MESSAGES);
b5e95b48
JJ
840module_param_named(debug, aa_g_debug, aabool, S_IRUSR | S_IWUSR);
841
842/* Audit mode */
843enum audit_mode aa_g_audit;
844module_param_call(audit, param_set_audit, param_get_audit,
845 &aa_g_audit, S_IRUSR | S_IWUSR);
846
847/* Determines if audit header is included in audited messages. This
848 * provides more context if the audit daemon is not running
849 */
90ab5ee9 850bool aa_g_audit_header = 1;
b5e95b48
JJ
851module_param_named(audit_header, aa_g_audit_header, aabool,
852 S_IRUSR | S_IWUSR);
853
854/* lock out loading/removal of policy
855 * TODO: add in at boot loading of policy, which is the only way to
856 * load policy, if lock_policy is set
857 */
90ab5ee9 858bool aa_g_lock_policy;
b5e95b48
JJ
859module_param_named(lock_policy, aa_g_lock_policy, aalockpolicy,
860 S_IRUSR | S_IWUSR);
861
862/* Syscall logging mode */
90ab5ee9 863bool aa_g_logsyscall;
b5e95b48
JJ
864module_param_named(logsyscall, aa_g_logsyscall, aabool, S_IRUSR | S_IWUSR);
865
866/* Maximum pathname length before accesses will start getting rejected */
867unsigned int aa_g_path_max = 2 * PATH_MAX;
622f6e32 868module_param_named(path_max, aa_g_path_max, aauint, S_IRUSR);
b5e95b48
JJ
869
870/* Determines how paranoid loading of policy is and how much verification
871 * on the loaded policy is done.
abbf8734
JJ
872 * DEPRECATED: read only as strict checking of load is always done now
873 * that none root users (user namespaces) can load policy.
b5e95b48 874 */
90ab5ee9 875bool aa_g_paranoid_load = 1;
abbf8734 876module_param_named(paranoid_load, aa_g_paranoid_load, aabool, S_IRUGO);
b5e95b48
JJ
877
878/* Boot time disable flag */
90ab5ee9 879static bool apparmor_enabled = CONFIG_SECURITY_APPARMOR_BOOTPARAM_VALUE;
c611616c 880module_param_named(enabled, apparmor_enabled, bool, S_IRUGO);
b5e95b48
JJ
881
882static int __init apparmor_enabled_setup(char *str)
883{
884 unsigned long enabled;
29707b20 885 int error = kstrtoul(str, 0, &enabled);
b5e95b48
JJ
886 if (!error)
887 apparmor_enabled = enabled ? 1 : 0;
888 return 1;
889}
890
891__setup("apparmor=", apparmor_enabled_setup);
892
893/* set global flag turning off the ability to load policy */
101d6c82 894static int param_set_aalockpolicy(const char *val, const struct kernel_param *kp)
b5e95b48 895{
545de8fe
JJ
896 if (!apparmor_enabled)
897 return -EINVAL;
898 if (apparmor_initialized && !policy_admin_capable(NULL))
b5e95b48 899 return -EPERM;
b5e95b48
JJ
900 return param_set_bool(val, kp);
901}
902
101d6c82 903static int param_get_aalockpolicy(char *buffer, const struct kernel_param *kp)
b5e95b48 904{
ca4bd5ae
JJ
905 if (!apparmor_enabled)
906 return -EINVAL;
545de8fe
JJ
907 if (apparmor_initialized && !policy_view_capable(NULL))
908 return -EPERM;
b5e95b48
JJ
909 return param_get_bool(buffer, kp);
910}
911
101d6c82 912static int param_set_aabool(const char *val, const struct kernel_param *kp)
b5e95b48 913{
ca4bd5ae
JJ
914 if (!apparmor_enabled)
915 return -EINVAL;
545de8fe
JJ
916 if (apparmor_initialized && !policy_admin_capable(NULL))
917 return -EPERM;
b5e95b48
JJ
918 return param_set_bool(val, kp);
919}
920
101d6c82 921static int param_get_aabool(char *buffer, const struct kernel_param *kp)
b5e95b48 922{
ca4bd5ae
JJ
923 if (!apparmor_enabled)
924 return -EINVAL;
545de8fe
JJ
925 if (apparmor_initialized && !policy_view_capable(NULL))
926 return -EPERM;
b5e95b48
JJ
927 return param_get_bool(buffer, kp);
928}
929
101d6c82 930static int param_set_aauint(const char *val, const struct kernel_param *kp)
b5e95b48 931{
39d84824
JJ
932 int error;
933
ca4bd5ae
JJ
934 if (!apparmor_enabled)
935 return -EINVAL;
39d84824
JJ
936 /* file is ro but enforce 2nd line check */
937 if (apparmor_initialized)
545de8fe 938 return -EPERM;
39d84824
JJ
939
940 error = param_set_uint(val, kp);
941 pr_info("AppArmor: buffer size set to %d bytes\n", aa_g_path_max);
942
943 return error;
b5e95b48
JJ
944}
945
101d6c82 946static int param_get_aauint(char *buffer, const struct kernel_param *kp)
b5e95b48 947{
ca4bd5ae
JJ
948 if (!apparmor_enabled)
949 return -EINVAL;
545de8fe
JJ
950 if (apparmor_initialized && !policy_view_capable(NULL))
951 return -EPERM;
b5e95b48
JJ
952 return param_get_uint(buffer, kp);
953}
954
955static int param_get_audit(char *buffer, struct kernel_param *kp)
956{
b5e95b48
JJ
957 if (!apparmor_enabled)
958 return -EINVAL;
545de8fe
JJ
959 if (apparmor_initialized && !policy_view_capable(NULL))
960 return -EPERM;
b5e95b48
JJ
961 return sprintf(buffer, "%s", audit_mode_names[aa_g_audit]);
962}
963
964static int param_set_audit(const char *val, struct kernel_param *kp)
965{
966 int i;
b5e95b48
JJ
967
968 if (!apparmor_enabled)
969 return -EINVAL;
b5e95b48
JJ
970 if (!val)
971 return -EINVAL;
545de8fe
JJ
972 if (apparmor_initialized && !policy_admin_capable(NULL))
973 return -EPERM;
b5e95b48
JJ
974
975 for (i = 0; i < AUDIT_MAX_INDEX; i++) {
976 if (strcmp(val, audit_mode_names[i]) == 0) {
977 aa_g_audit = i;
978 return 0;
979 }
980 }
981
982 return -EINVAL;
983}
984
985static int param_get_mode(char *buffer, struct kernel_param *kp)
986{
b5e95b48
JJ
987 if (!apparmor_enabled)
988 return -EINVAL;
545de8fe
JJ
989 if (apparmor_initialized && !policy_view_capable(NULL))
990 return -EPERM;
b5e95b48 991
0d259f04 992 return sprintf(buffer, "%s", aa_profile_mode_names[aa_g_profile_mode]);
b5e95b48
JJ
993}
994
995static int param_set_mode(const char *val, struct kernel_param *kp)
996{
997 int i;
b5e95b48
JJ
998
999 if (!apparmor_enabled)
1000 return -EINVAL;
b5e95b48
JJ
1001 if (!val)
1002 return -EINVAL;
545de8fe
JJ
1003 if (apparmor_initialized && !policy_admin_capable(NULL))
1004 return -EPERM;
b5e95b48 1005
0d259f04
JJ
1006 for (i = 0; i < APPARMOR_MODE_NAMES_MAX_INDEX; i++) {
1007 if (strcmp(val, aa_profile_mode_names[i]) == 0) {
b5e95b48
JJ
1008 aa_g_profile_mode = i;
1009 return 0;
1010 }
1011 }
1012
1013 return -EINVAL;
1014}
1015
1016/*
1017 * AppArmor init functions
1018 */
1019
1020/**
55a26ebf 1021 * set_init_ctx - set a task context and profile on the first task.
b5e95b48
JJ
1022 *
1023 * TODO: allow setting an alternate profile than unconfined
1024 */
55a26ebf 1025static int __init set_init_ctx(void)
b5e95b48
JJ
1026{
1027 struct cred *cred = (struct cred *)current->real_cred;
55a26ebf 1028 struct aa_task_ctx *ctx;
b5e95b48 1029
55a26ebf
JJ
1030 ctx = aa_alloc_task_context(GFP_KERNEL);
1031 if (!ctx)
b5e95b48
JJ
1032 return -ENOMEM;
1033
637f688d 1034 ctx->label = aa_get_label(ns_unconfined(root_ns));
55a26ebf 1035 cred_ctx(cred) = ctx;
b5e95b48
JJ
1036
1037 return 0;
1038}
1039
d4669f0b
JJ
1040static void destroy_buffers(void)
1041{
1042 u32 i, j;
1043
1044 for_each_possible_cpu(i) {
1045 for_each_cpu_buffer(j) {
1046 kfree(per_cpu(aa_buffers, i).buf[j]);
1047 per_cpu(aa_buffers, i).buf[j] = NULL;
1048 }
1049 }
1050}
1051
1052static int __init alloc_buffers(void)
1053{
1054 u32 i, j;
1055
1056 for_each_possible_cpu(i) {
1057 for_each_cpu_buffer(j) {
1058 char *buffer;
1059
1060 if (cpu_to_node(i) > num_online_nodes())
1061 /* fallback to kmalloc for offline nodes */
1062 buffer = kmalloc(aa_g_path_max, GFP_KERNEL);
1063 else
1064 buffer = kmalloc_node(aa_g_path_max, GFP_KERNEL,
1065 cpu_to_node(i));
1066 if (!buffer) {
1067 destroy_buffers();
1068 return -ENOMEM;
1069 }
1070 per_cpu(aa_buffers, i).buf[j] = buffer;
1071 }
1072 }
1073
1074 return 0;
1075}
1076
e3ea1ca5
TH
1077#ifdef CONFIG_SYSCTL
1078static int apparmor_dointvec(struct ctl_table *table, int write,
1079 void __user *buffer, size_t *lenp, loff_t *ppos)
1080{
1081 if (!policy_admin_capable(NULL))
1082 return -EPERM;
1083 if (!apparmor_enabled)
1084 return -EINVAL;
1085
1086 return proc_dointvec(table, write, buffer, lenp, ppos);
1087}
1088
1089static struct ctl_path apparmor_sysctl_path[] = {
1090 { .procname = "kernel", },
1091 { }
1092};
1093
1094static struct ctl_table apparmor_sysctl_table[] = {
1095 {
1096 .procname = "unprivileged_userns_apparmor_policy",
1097 .data = &unprivileged_userns_apparmor_policy,
1098 .maxlen = sizeof(int),
1099 .mode = 0600,
1100 .proc_handler = apparmor_dointvec,
1101 },
1102 { }
1103};
1104
1105static int __init apparmor_init_sysctl(void)
1106{
1107 return register_sysctl_paths(apparmor_sysctl_path,
1108 apparmor_sysctl_table) ? 0 : -ENOMEM;
1109}
1110#else
1111static inline int apparmor_init_sysctl(void)
1112{
1113 return 0;
1114}
1115#endif /* CONFIG_SYSCTL */
1116
b5e95b48
JJ
1117static int __init apparmor_init(void)
1118{
1119 int error;
1120
b1d9e6b0 1121 if (!apparmor_enabled || !security_module_enable("apparmor")) {
b5e95b48
JJ
1122 aa_info_message("AppArmor disabled by boot time parameter");
1123 apparmor_enabled = 0;
1124 return 0;
1125 }
1126
11c236b8
JJ
1127 error = aa_setup_dfa_engine();
1128 if (error) {
1129 AA_ERROR("Unable to setup dfa engine\n");
1130 goto alloc_out;
1131 }
1132
b5e95b48
JJ
1133 error = aa_alloc_root_ns();
1134 if (error) {
1135 AA_ERROR("Unable to allocate default profile namespace\n");
1136 goto alloc_out;
1137 }
1138
e3ea1ca5
TH
1139 error = apparmor_init_sysctl();
1140 if (error) {
1141 AA_ERROR("Unable to register sysctls\n");
1142 goto alloc_out;
1143
1144 }
1145
d4669f0b
JJ
1146 error = alloc_buffers();
1147 if (error) {
1148 AA_ERROR("Unable to allocate work buffers\n");
1149 goto buffers_out;
1150 }
1151
55a26ebf 1152 error = set_init_ctx();
b5e95b48
JJ
1153 if (error) {
1154 AA_ERROR("Failed to set context on init task\n");
b1d9e6b0 1155 aa_free_root_ns();
d4669f0b 1156 goto buffers_out;
b5e95b48 1157 }
d69dece5
CS
1158 security_add_hooks(apparmor_hooks, ARRAY_SIZE(apparmor_hooks),
1159 "apparmor");
b5e95b48
JJ
1160
1161 /* Report that AppArmor successfully initialized */
1162 apparmor_initialized = 1;
1163 if (aa_g_profile_mode == APPARMOR_COMPLAIN)
1164 aa_info_message("AppArmor initialized: complain mode enabled");
1165 else if (aa_g_profile_mode == APPARMOR_KILL)
1166 aa_info_message("AppArmor initialized: kill mode enabled");
1167 else
1168 aa_info_message("AppArmor initialized");
1169
1170 return error;
1171
d4669f0b
JJ
1172buffers_out:
1173 destroy_buffers();
1174
b5e95b48
JJ
1175alloc_out:
1176 aa_destroy_aafs();
11c236b8 1177 aa_teardown_dfa_engine();
b5e95b48
JJ
1178
1179 apparmor_enabled = 0;
1180 return error;
b5e95b48
JJ
1181}
1182
1183security_initcall(apparmor_init);