1
From: John Johansen <jjohansen@suse.de>
2
Subject: AppArmor: Main Part
4
The underlying functions by which the AppArmor LSM hooks are implemented.
6
Signed-off-by: John Johansen <jjohansen@suse.de>
7
Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
10
security/apparmor/main.c | 1479 +++++++++++++++++++++++++++++++++++++++++++++++
11
1 file changed, 1479 insertions(+)
14
+++ b/security/apparmor/main.c
17
+ * Copyright (C) 2002-2007 Novell/SUSE
19
+ * This program is free software; you can redistribute it and/or
20
+ * modify it under the terms of the GNU General Public License as
21
+ * published by the Free Software Foundation, version 2 of the
27
+#include <linux/security.h>
28
+#include <linux/namei.h>
29
+#include <linux/audit.h>
30
+#include <linux/mount.h>
31
+#include <linux/ptrace.h>
33
+#include "apparmor.h"
38
+ * Table of capability names: we generate it from capabilities.h.
40
+static const char *capability_names[] = {
41
+#include "capability_names.h"
44
+struct aa_namespace *default_namespace;
46
+static int aa_inode_mode(struct inode *inode)
48
+ /* if the inode doesn't exist the user is creating it */
49
+ if (!inode || current->fsuid == inode->i_uid)
50
+ return AA_USER_SHIFT;
51
+ return AA_OTHER_SHIFT;
54
+int alloc_default_namespace(void)
56
+ struct aa_namespace *ns;
57
+ char *name = kstrdup("default", GFP_KERNEL);
60
+ ns = alloc_aa_namespace(name);
66
+ write_lock(&profile_ns_list_lock);
67
+ default_namespace = ns;
68
+ aa_get_namespace(ns);
69
+ list_add(&ns->list, &profile_ns_list);
70
+ write_unlock(&profile_ns_list_lock);
75
+void free_default_namespace(void)
77
+ write_lock(&profile_ns_list_lock);
78
+ list_del_init(&default_namespace->list);
79
+ write_unlock(&profile_ns_list_lock);
80
+ aa_put_namespace(default_namespace);
81
+ default_namespace = NULL;
84
+static void aa_audit_file_sub_mask(struct audit_buffer *ab, char *buffer,
87
+ const char unsafex[] = "upcn";
88
+ const char safex[] = "UPCN";
91
+ if (mask & AA_EXEC_MMAP)
93
+ if (mask & MAY_READ)
95
+ if (mask & MAY_WRITE)
97
+ else if (mask & MAY_APPEND)
99
+ if (mask & MAY_EXEC) {
100
+ int index = AA_EXEC_INDEX(mask);
101
+ /* all indexes > 4 are also named transitions */
105
+ if (mask & AA_EXEC_UNSAFE)
106
+ *m++ = unsafex[index - 1];
108
+ *m++ = safex[index - 1];
110
+ if (mask & AA_EXEC_INHERIT)
114
+ if (mask & AA_MAY_LINK)
116
+ if (mask & AA_MAY_LOCK)
121
+static void aa_audit_file_mask(struct audit_buffer *ab, const char *name,
124
+ char user[10], other[10];
126
+ aa_audit_file_sub_mask(ab, user,
127
+ (mask & AA_USER_PERMS) >> AA_USER_SHIFT);
128
+ aa_audit_file_sub_mask(ab, other,
129
+ (mask & AA_OTHER_PERMS) >> AA_OTHER_SHIFT);
131
+ audit_log_format(ab, " %s=\"%s::%s\"", name, user, other);
135
+ * aa_audit - Log an audit event to the audit subsystem
136
+ * @profile: profile to check against
138
+ * @audit_cxt: audit context to log message to
139
+ * @type: audit event number
141
+static int aa_audit_base(struct aa_profile *profile, struct aa_audit *sa,
142
+ struct audit_context *audit_cxt, int type)
144
+ struct audit_buffer *ab = NULL;
146
+ ab = audit_log_start(audit_cxt, sa->gfp_mask, type);
149
+ AA_ERROR("Unable to log event (%d) to audit subsys\n",
151
+ /* don't fail operations in complain mode even if logging
153
+ return type == AUDIT_APPARMOR_ALLOWED ? 0 : -ENOMEM;
157
+ audit_log_format(ab, "operation=\"%s\"", sa->operation);
160
+ audit_log_format(ab, " info=\"%s\"", sa->info);
161
+ if (sa->error_code)
162
+ audit_log_format(ab, " error=%d", sa->error_code);
165
+ if (sa->request_mask)
166
+ aa_audit_file_mask(ab, "requested_mask", sa->request_mask);
168
+ if (sa->denied_mask)
169
+ aa_audit_file_mask(ab, "denied_mask", sa->denied_mask);
171
+ if (sa->request_mask)
172
+ audit_log_format(ab, " fsuid=%d", current->fsuid);
175
+ struct iattr *iattr = sa->iattr;
177
+ audit_log_format(ab, " attribute=\"%s%s%s%s%s%s%s\"",
178
+ iattr->ia_valid & ATTR_MODE ? "mode," : "",
179
+ iattr->ia_valid & ATTR_UID ? "uid," : "",
180
+ iattr->ia_valid & ATTR_GID ? "gid," : "",
181
+ iattr->ia_valid & ATTR_SIZE ? "size," : "",
182
+ iattr->ia_valid & (ATTR_ATIME | ATTR_ATIME_SET) ?
184
+ iattr->ia_valid & (ATTR_MTIME | ATTR_MTIME_SET) ?
186
+ iattr->ia_valid & ATTR_CTIME ? "ctime," : "");
190
+ audit_log_format(ab, " task=%d", sa->task);
193
+ audit_log_format(ab, " parent=%d", sa->parent);
196
+ audit_log_format(ab, " name=");
197
+ audit_log_untrustedstring(ab, sa->name);
201
+ audit_log_format(ab, " name2=");
202
+ audit_log_untrustedstring(ab, sa->name2);
205
+ audit_log_format(ab, " pid=%d", current->pid);
208
+ audit_log_format(ab, " profile=");
209
+ audit_log_untrustedstring(ab, profile->name);
211
+ if (profile->ns != default_namespace) {
212
+ audit_log_format(ab, " namespace=");
213
+ audit_log_untrustedstring(ab, profile->ns->name);
219
+ return type == AUDIT_APPARMOR_ALLOWED ? 0 : sa->error_code;
223
+ * aa_audit_syscallreject - Log a syscall rejection to the audit subsystem
224
+ * @profile: profile to check against
225
+ * @gfp: memory allocation flags
226
+ * @msg: string describing syscall being rejected
228
+int aa_audit_syscallreject(struct aa_profile *profile, gfp_t gfp,
231
+ struct aa_audit sa;
232
+ memset(&sa, 0, sizeof(sa));
233
+ sa.operation = "syscall";
236
+ sa.error_code = -EPERM;
238
+ return aa_audit_base(profile, &sa, current->audit_context,
239
+ AUDIT_APPARMOR_DENIED);
242
+int aa_audit_message(struct aa_profile *profile, struct aa_audit *sa,
245
+ struct audit_context *audit_cxt;
247
+ audit_cxt = apparmor_logsyscall ? current->audit_context : NULL;
248
+ return aa_audit_base(profile, sa, audit_cxt, type);
251
+void aa_audit_hint(struct aa_profile *profile, struct aa_audit *sa)
253
+ aa_audit_message(profile, sa, AUDIT_APPARMOR_HINT);
256
+void aa_audit_status(struct aa_profile *profile, struct aa_audit *sa)
258
+ aa_audit_message(profile, sa, AUDIT_APPARMOR_STATUS);
261
+int aa_audit_reject(struct aa_profile *profile, struct aa_audit *sa)
263
+ return aa_audit_message(profile, sa, AUDIT_APPARMOR_DENIED);
267
+ * aa_audit - Log an audit event to the audit subsystem
268
+ * @profile: profile to check against
271
+int aa_audit(struct aa_profile *profile, struct aa_audit *sa)
273
+ int type = AUDIT_APPARMOR_DENIED;
274
+ struct audit_context *audit_cxt;
276
+ if (likely(!sa->error_code))
277
+ type = AUDIT_APPARMOR_AUDIT;
278
+ else if (PROFILE_COMPLAIN(profile))
279
+ type = AUDIT_APPARMOR_ALLOWED;
281
+ audit_cxt = apparmor_logsyscall ? current->audit_context : NULL;
282
+ return aa_audit_base(profile, sa, audit_cxt, type);
285
+static int aa_audit_file(struct aa_profile *profile, struct aa_audit *sa)
287
+ if (likely(!sa->error_code)) {
288
+ int mask = sa->audit_mask & AUDIT_FILE_MASK;
290
+ if (unlikely(PROFILE_AUDIT(profile)))
291
+ mask |= AUDIT_FILE_MASK;
293
+ if (likely(!(sa->request_mask & mask)))
296
+ /* mask off perms that are not being force audited */
297
+ sa->request_mask &= mask | ALL_AA_EXEC_TYPE;
299
+ int mask = AUDIT_QUIET_MASK(sa->audit_mask);
301
+ if (!(sa->denied_mask & ~mask))
302
+ return sa->error_code;
304
+ /* mask off perms whose denial is being silenced */
305
+ if (!PROFILE_COMPLAIN(profile))
306
+ sa->denied_mask &= (~mask) | ALL_AA_EXEC_TYPE;
309
+ return aa_audit(profile, sa);
312
+static int aa_audit_caps(struct aa_profile *profile, struct aa_audit *sa,
315
+ if (likely(!sa->error_code)) {
316
+ if (likely(!PROFILE_AUDIT(profile) &&
317
+ !cap_raised(profile->audit_caps, cap)))
321
+ /* quieting of capabilities is handled the caps_logged cache */
322
+ return aa_audit(profile, sa);
326
+ * aa_file_denied - check for @mask access on a file
327
+ * @profile: profile to check against
328
+ * @name: pathname of file
329
+ * @mask: permission mask requested for file
330
+ * @audit_mask: return audit mask for the match
332
+ * Return %0 on success, or else the permissions in @mask that the
335
+static int aa_file_denied(struct aa_profile *profile, const char *name,
336
+ int mask, int *audit_mask)
338
+ return (mask & ~aa_match(profile->file_rules, name, audit_mask));
342
+ * aa_link_denied - check for permission to link a file
343
+ * @profile: profile to check against
344
+ * @link: pathname of link being created
345
+ * @target: pathname of target to be linked to
346
+ * @target_mode: UGO shift for target inode
347
+ * @request_mask: the permissions subset valid only if link succeeds
348
+ * @audit_mask: return the audit_mask for the link permission
349
+ * Return %0 on success, or else the permissions that the profile denies.
351
+static int aa_link_denied(struct aa_profile *profile, const char *link,
352
+ const char *target, int target_mode,
353
+ int *request_mask, int *audit_mask)
355
+ unsigned int state;
356
+ int l_mode, t_mode, l_x, t_x, denied_mask = 0;
357
+ int link_mask = AA_MAY_LINK << target_mode;
359
+ *request_mask = link_mask;
361
+ l_mode = aa_match_state(profile->file_rules, DFA_START, link, &state);
363
+ if (l_mode & link_mask) {
365
+ /* test to see if target can be paired with link */
366
+ state = aa_dfa_null_transition(profile->file_rules, state);
367
+ mode = aa_match_state(profile->file_rules, state, target,
370
+ if (!(mode & link_mask))
371
+ denied_mask |= link_mask;
373
+ *audit_mask = dfa_audit_mask(profile->file_rules, state);
375
+ /* return if link subset test is not required */
376
+ if (!(mode & (AA_LINK_SUBSET_TEST << target_mode)))
377
+ return denied_mask;
380
+ /* Do link perm subset test requiring permission on link are a
381
+ * subset of the permissions on target.
382
+ * If a subset test is required a permission subset test of the
383
+ * perms for the link are done against the user::other of the
384
+ * target's 'r', 'w', 'x', 'a', 'k', and 'm' permissions.
386
+ * If the link has 'x', an exact match of all the execute flags
389
+ denied_mask |= ~l_mode & link_mask;
391
+ t_mode = aa_match(profile->file_rules, target, NULL);
393
+ l_x = l_mode & (ALL_AA_EXEC_TYPE | AA_EXEC_BITS);
394
+ t_x = t_mode & (ALL_AA_EXEC_TYPE | AA_EXEC_BITS);
396
+ /* For actual subset test ignore valid-profile-transition flags,
399
+ l_mode &= AA_FILE_PERMS & ~AA_LINK_BITS;
400
+ t_mode &= AA_FILE_PERMS & ~AA_LINK_BITS;
402
+ *request_mask = l_mode | link_mask;
405
+ int x = l_x | (t_x & ALL_AA_EXEC_UNSAFE);
406
+ denied_mask |= l_mode & ~t_mode;
407
+ /* mask off x modes not used by link */
409
+ /* handle exec subset
410
+ * - link safe exec issubset of unsafe exec
411
+ * - no link x perm is subset of target having x perm
413
+ if ((l_mode & AA_USER_EXEC) &&
414
+ (x & AA_USER_EXEC_TYPE) != (t_x & AA_USER_EXEC_TYPE))
415
+ denied_mask = AA_USER_EXEC | (l_x & AA_USER_EXEC_TYPE);
416
+ if ((l_mode & AA_OTHER_EXEC) &&
417
+ (x & AA_OTHER_EXEC_TYPE) != (t_x & AA_OTHER_EXEC_TYPE))
418
+ denied_mask = AA_OTHER_EXEC | (l_x & AA_OTHER_EXEC_TYPE);
421
+ return denied_mask;
425
+ * aa_get_name - compute the pathname of a file
426
+ * @dentry: dentry of the file
427
+ * @mnt: vfsmount of the file
428
+ * @buffer: buffer that aa_get_name() allocated
429
+ * @check: AA_CHECK_DIR is set if the file is a directory
431
+ * Returns a pointer to the beginning of the pathname (which usually differs
432
+ * from the beginning of the buffer), or an error code.
434
+ * We need @check to indicate whether the file is a directory or not because
435
+ * the file may not yet exist, and so we cannot check the inode's file type.
437
+static char *aa_get_name(struct dentry *dentry, struct vfsmount *mnt,
438
+ char **buffer, int check)
441
+ int is_dir, size = 256;
443
+ is_dir = (check & AA_CHECK_DIR) ? 1 : 0;
446
+ char *buf = kmalloc(size, GFP_KERNEL);
448
+ return ERR_PTR(-ENOMEM);
450
+ name = d_namespace_path(dentry, mnt, buf, size - is_dir);
451
+ if (!IS_ERR(name)) {
452
+ if (name[0] != '/') {
454
+ * This dentry is not connected to the
455
+ * namespace root -- reject access.
458
+ return ERR_PTR(-ENOENT);
460
+ if (is_dir && name[1] != '\0') {
462
+ * Append "/" to the pathname. The root
463
+ * directory is a special case; it already
466
+ buf[size - 2] = '/';
467
+ buf[size - 1] = '\0';
473
+ if (PTR_ERR(name) != -ENAMETOOLONG)
478
+ if (size > apparmor_path_max)
479
+ return ERR_PTR(-ENAMETOOLONG);
483
+static char *new_compound_name(const char *n1, const char *n2)
485
+ char *name = kmalloc(strlen(n1) + strlen(n2) + 3, GFP_KERNEL);
487
+ sprintf(name, "%s//%s", n1, n2);
490
+static inline void aa_put_name_buffer(char *buffer)
496
+ * aa_perm_dentry - check if @profile allows @mask for a file
497
+ * @profile: profile to check against
498
+ * @dentry: dentry of the file
499
+ * @mnt: vfsmount o the file
500
+ * @sa: audit context
501
+ * @mask: requested profile permissions
502
+ * @check: kind of check to perform
504
+ * Returns 0 upon success, or else an error code.
506
+ * @check indicates the file type, and whether the file was accessed through
507
+ * an open file descriptor (AA_CHECK_FD) or not.
509
+static int aa_perm_dentry(struct aa_profile *profile, struct dentry *dentry,
510
+ struct vfsmount *mnt, struct aa_audit *sa, int check)
513
+ char *buffer = NULL;
515
+ sa->name = aa_get_name(dentry, mnt, &buffer, check);
516
+ sa->request_mask <<= aa_inode_mode(dentry->d_inode);
517
+ if (IS_ERR(sa->name)) {
519
+ * deleted files are given a pass on permission checks when
520
+ * accessed through a file descriptor.
522
+ if (PTR_ERR(sa->name) == -ENOENT && (check & AA_CHECK_FD))
523
+ sa->denied_mask = 0;
525
+ sa->denied_mask = sa->request_mask;
526
+ sa->error_code = PTR_ERR(sa->name);
527
+ if (sa->error_code == -ENOENT)
528
+ sa->info = "Failed name resolution - object not a valid entry";
529
+ else if (sa->error_code == -ENAMETOOLONG)
530
+ sa->info = "Failed name resolution - name too long";
532
+ sa->info = "Failed name resolution";
536
+ sa->denied_mask = aa_file_denied(profile, sa->name,
540
+ if (!sa->denied_mask)
541
+ sa->error_code = 0;
543
+ error = aa_audit_file(profile, sa);
544
+ aa_put_name_buffer(buffer);
550
+ * aa_attr - check if attribute change is allowed
551
+ * @profile: profile to check against
552
+ * @dentry: dentry of the file to check
553
+ * @mnt: vfsmount of the file to check
554
+ * @iattr: attribute changes requested
556
+int aa_attr(struct aa_profile *profile, struct dentry *dentry,
557
+ struct vfsmount *mnt, struct iattr *iattr)
559
+ struct inode *inode = dentry->d_inode;
561
+ struct aa_audit sa;
563
+ memset(&sa, 0, sizeof(sa));
564
+ sa.operation = "setattr";
565
+ sa.gfp_mask = GFP_KERNEL;
567
+ sa.request_mask = MAY_WRITE;
568
+ sa.error_code = -EACCES;
571
+ if (inode && S_ISDIR(inode->i_mode))
572
+ check |= AA_CHECK_DIR;
573
+ if (iattr->ia_valid & ATTR_FILE)
574
+ check |= AA_CHECK_FD;
576
+ error = aa_perm_dentry(profile, dentry, mnt, &sa, check);
582
+ * aa_perm_xattr - check if xattr attribute change is allowed
583
+ * @profile: profile to check against
584
+ * @dentry: dentry of the file to check
585
+ * @mnt: vfsmount of the file to check
586
+ * @operation: xattr operation being done
587
+ * @mask: access mode requested
588
+ * @check: kind of check to perform
590
+int aa_perm_xattr(struct aa_profile *profile, const char *operation,
591
+ struct dentry *dentry, struct vfsmount *mnt, int mask,
594
+ struct inode *inode = dentry->d_inode;
596
+ struct aa_audit sa;
598
+ memset(&sa, 0, sizeof(sa));
599
+ sa.operation = operation;
600
+ sa.gfp_mask = GFP_KERNEL;
601
+ sa.request_mask = mask;
602
+ sa.error_code = -EACCES;
604
+ if (inode && S_ISDIR(inode->i_mode))
605
+ check |= AA_CHECK_DIR;
607
+ error = aa_perm_dentry(profile, dentry, mnt, &sa, check);
613
+ * aa_perm - basic apparmor permissions check
614
+ * @profile: profile to check against
615
+ * @dentry: dentry of the file to check
616
+ * @mnt: vfsmount of the file to check
617
+ * @mask: access mode requested
618
+ * @check: kind of check to perform
620
+ * Determine if access @mask for the file is authorized by @profile.
621
+ * Returns 0 on success, or else an error code.
623
+int aa_perm(struct aa_profile *profile, const char *operation,
624
+ struct dentry *dentry, struct vfsmount *mnt, int mask, int check)
626
+ struct aa_audit sa;
632
+ memset(&sa, 0, sizeof(sa));
633
+ sa.operation = operation;
634
+ sa.gfp_mask = GFP_KERNEL;
635
+ sa.request_mask = mask;
636
+ sa.error_code = -EACCES;
638
+ error = aa_perm_dentry(profile, dentry, mnt, &sa, check);
646
+ * @profile: profile to check against
647
+ * @dentry: dentry of directory to check
648
+ * @mnt: vfsmount of directory to check
649
+ * @operation: directory operation being performed
650
+ * @mask: access mode requested
652
+ * Determine if directory operation (make/remove) for dentry is authorized
654
+ * Returns 0 on success, or else an error code.
656
+int aa_perm_dir(struct aa_profile *profile, const char *operation,
657
+ struct dentry *dentry, struct vfsmount *mnt, int mask)
659
+ struct aa_audit sa;
661
+ memset(&sa, 0, sizeof(sa));
662
+ sa.operation = operation;
663
+ sa.gfp_mask = GFP_KERNEL;
664
+ sa.request_mask = mask;
665
+ sa.error_code = -EACCES;
667
+ return aa_perm_dentry(profile, dentry, mnt, &sa, AA_CHECK_DIR);
670
+int aa_perm_path(struct aa_profile *profile, const char *operation,
671
+ const char *name, int mask, uid_t uid)
673
+ struct aa_audit sa;
675
+ memset(&sa, 0, sizeof(sa));
676
+ sa.operation = operation;
677
+ sa.gfp_mask = GFP_KERNEL;
678
+ sa.request_mask = mask;
680
+ if (current->fsuid == uid)
681
+ sa.request_mask = mask << AA_USER_SHIFT;
683
+ sa.request_mask = mask << AA_OTHER_SHIFT;
685
+ sa.denied_mask = aa_file_denied(profile, name, sa.request_mask,
687
+ sa.error_code = sa.denied_mask ? -EACCES : 0;
689
+ return aa_audit_file(profile, &sa);
693
+ * aa_capability - test permission to use capability
694
+ * @cxt: aa_task_context with profile to check against
695
+ * @cap: capability to be tested
697
+ * Look up capability in profile capability set.
698
+ * Returns 0 on success, or else an error code.
700
+int aa_capability(struct aa_task_context *cxt, int cap)
702
+ int error = cap_raised(cxt->profile->capabilities, cap) ? 0 : -EPERM;
703
+ struct aa_audit sa;
705
+ /* test if cap has alread been logged */
706
+ if (cap_raised(cxt->caps_logged, cap)) {
707
+ if (PROFILE_COMPLAIN(cxt->profile))
711
+ /* don't worry about rcu replacement of the cxt here.
712
+ * caps_logged is a cache to reduce the occurence of
713
+ * duplicate messages in the log. The worst that can
714
+ * happen is duplicate capability messages shows up in
717
+ cap_raise(cxt->caps_logged, cap);
719
+ memset(&sa, 0, sizeof(sa));
720
+ sa.operation = "capable";
721
+ sa.gfp_mask = GFP_ATOMIC;
722
+ sa.name = capability_names[cap];
723
+ sa.error_code = error;
725
+ error = aa_audit_caps(cxt->profile, &sa, cap);
730
+/* must be used inside rcu_read_lock or task_lock */
731
+int aa_may_ptrace(struct aa_task_context *cxt, struct aa_profile *tracee)
733
+ if (!cxt || cxt->profile == tracee)
735
+ return aa_capability(cxt, CAP_SYS_PTRACE);
739
+ * aa_link - hard link check
740
+ * @profile: profile to check against
741
+ * @link: dentry of link being created
742
+ * @link_mnt: vfsmount of link being created
743
+ * @target: dentry of link target
744
+ * @target_mnt: vfsmunt of link target
746
+ * Returns 0 on success, or else an error code.
748
+int aa_link(struct aa_profile *profile,
749
+ struct dentry *link, struct vfsmount *link_mnt,
750
+ struct dentry *target, struct vfsmount *target_mnt)
753
+ struct aa_audit sa;
754
+ char *buffer = NULL, *buffer2 = NULL;
756
+ memset(&sa, 0, sizeof(sa));
757
+ sa.operation = "inode_link";
758
+ sa.gfp_mask = GFP_KERNEL;
759
+ sa.name = aa_get_name(link, link_mnt, &buffer, 0);
760
+ sa.name2 = aa_get_name(target, target_mnt, &buffer2, 0);
762
+ if (IS_ERR(sa.name)) {
763
+ sa.error_code = PTR_ERR(sa.name);
766
+ if (IS_ERR(sa.name2)) {
767
+ sa.error_code = PTR_ERR(sa.name2);
771
+ if (sa.name && sa.name2) {
772
+ sa.denied_mask = aa_link_denied(profile, sa.name, sa.name2,
773
+ aa_inode_mode(target->d_inode),
776
+ sa.error_code = sa.denied_mask ? -EACCES : 0;
779
+ error = aa_audit_file(profile, &sa);
781
+ aa_put_name_buffer(buffer);
782
+ aa_put_name_buffer(buffer2);
787
+/*******************************
788
+ * Global task related functions
789
+ *******************************/
792
+ * aa_clone - initialize the task context for a new task
793
+ * @child: task that is being created
795
+ * Returns 0 on success, or else an error code.
797
+int aa_clone(struct task_struct *child)
799
+ struct aa_task_context *cxt, *child_cxt;
800
+ struct aa_profile *profile;
802
+ if (!aa_task_context(current))
804
+ child_cxt = aa_alloc_task_context(GFP_KERNEL);
809
+ profile = aa_get_profile(current);
811
+ lock_profile(profile);
812
+ cxt = aa_task_context(current);
813
+ if (unlikely(profile->isstale || !cxt ||
814
+ cxt->profile != profile)) {
816
+ * Race with profile replacement or removal, or with
817
+ * task context removal.
819
+ unlock_profile(profile);
820
+ aa_put_profile(profile);
824
+ /* No need to grab the child's task lock here. */
825
+ aa_change_task_context(child, child_cxt, profile,
826
+ cxt->cookie, cxt->previous_profile);
827
+ unlock_profile(profile);
829
+ if (APPARMOR_COMPLAIN(child_cxt) &&
830
+ profile == profile->ns->null_complain_profile) {
831
+ struct aa_audit sa;
832
+ memset(&sa, 0, sizeof(sa));
833
+ sa.operation = "clone";
834
+ sa.gfp_mask = GFP_KERNEL;
835
+ sa.task = child->pid;
836
+ aa_audit_hint(profile, &sa);
838
+ aa_put_profile(profile);
840
+ aa_free_task_context(child_cxt);
845
+static struct aa_profile *
846
+aa_register_find(struct aa_profile *profile, const char* ns_name,
847
+ const char *name, int mandatory, int complain,
848
+ struct aa_audit *sa)
850
+ struct aa_namespace *ns;
851
+ struct aa_profile *new_profile;
857
+ ns = default_namespace;
860
+ /* locate the profile namespace */
861
+ ns = aa_find_namespace(ns_name);
864
+ sa->info = "profile namespace not found";
865
+ sa->denied_mask = sa->request_mask;
866
+ sa->error_code = -ENOENT;
867
+ return ERR_PTR(-ENOENT);
875
+ /* Locate new profile */
876
+ new_profile = aa_find_profile(ns, name);
879
+ AA_DEBUG("%s: setting profile %s\n",
880
+ __FUNCTION__, new_profile->name);
881
+ } else if (mandatory && profile) {
882
+ sa->info = "mandatory profile missing";
883
+ sa->denied_mask = sa->request_mask; /* shifted MAY_EXEC */
885
+ aa_audit_hint(profile, sa);
887
+ aa_dup_profile(profile->ns->null_complain_profile);
889
+ sa->error_code = -EACCES;
891
+ aa_put_namespace(ns);
892
+ return ERR_PTR(-EACCES);
895
+ /* Only way we can get into this code is if task
896
+ * is unconfined, pix, nix.
898
+ AA_DEBUG("%s: No profile found for exec image '%s'\n",
903
+ aa_put_namespace(ns);
904
+ return new_profile;
907
+static struct aa_profile *
908
+aa_x_to_profile(struct aa_profile *profile, const char *filename, int xmode,
909
+ struct aa_audit *sa, char **child)
911
+ struct aa_profile *new_profile = NULL;
912
+ int ix = xmode & AA_EXEC_INHERIT;
913
+ int complain = PROFILE_COMPLAIN(profile);
917
+ switch (xmode & AA_EXEC_MODIFIERS) {
919
+ /* only valid with ix flag */
922
+ case AA_EXEC_UNCONFINED:
923
+ /* only valid without ix flag */
926
+ case AA_EXEC_PROFILE:
927
+ new_profile = aa_register_find(profile, NULL, filename, !ix,
930
+ case AA_EXEC_CHILD:
931
+ *child = new_compound_name(profile->name, filename);
932
+ sa->name2 = *child;
934
+ sa->info = "Failed name resolution - exec failed";
935
+ sa->error_code = -ENOMEM;
936
+ new_profile = ERR_PTR(-ENOMEM);
938
+ new_profile = aa_register_find(profile, NULL, *child,
939
+ !ix, complain, sa);
943
+ /* all other indexes are named transitions */
944
+ index = AA_EXEC_INDEX(xmode);
945
+ if (index - 4 > profile->exec_table_size) {
946
+ sa->info = "invalid named transition - exec failed";
947
+ sa->error_code = -EACCES;
948
+ new_profile = ERR_PTR(-EACCES);
950
+ char *ns_name = NULL;
951
+ char *name = profile->exec_table[index - 4];
952
+ if (*name == ':') {
953
+ ns_name = name + 1;
954
+ name = ns_name + strlen(ns_name) + 1;
957
+ sa->name3 = ns_name;
959
+ aa_register_find(profile, ns_name, name,
960
+ !ix, complain, sa);
963
+ if (IS_ERR(new_profile))
964
+ /* all these failures must be audited - no quieting */
965
+ return ERR_PTR(aa_audit_reject(profile, sa));
966
+ return new_profile;
970
+ * aa_register - register a new program
971
+ * @bprm: binprm of program being registered
973
+ * Try to register a new program during execve(). This should give the
974
+ * new program a valid aa_task_context if confined.
976
+int aa_register(struct linux_binprm *bprm)
978
+ const char *filename;
979
+ char *buffer = NULL, *child = NULL;
980
+ struct file *filp = bprm->file;
981
+ struct aa_profile *profile, *old_profile, *new_profile = NULL;
982
+ int exec_mode, complain = 0, shift;
983
+ struct aa_audit sa;
985
+ AA_DEBUG("%s\n", __FUNCTION__);
987
+ profile = aa_get_profile(current);
989
+ shift = aa_inode_mode(filp->f_dentry->d_inode);
990
+ memset(&sa, 0, sizeof(sa));
991
+ sa.operation = "exec";
992
+ sa.gfp_mask = GFP_KERNEL;
993
+ sa.request_mask = MAY_EXEC << shift;
995
+ filename = aa_get_name(filp->f_dentry, filp->f_vfsmnt, &buffer, 0);
996
+ if (IS_ERR(filename)) {
998
+ sa.info = "Failed name resolution - exec failed";
999
+ sa.error_code = PTR_ERR(filename);
1000
+ aa_audit_file(profile, &sa);
1001
+ return sa.error_code;
1005
+ sa.name = filename;
1007
+ exec_mode = AA_EXEC_UNSAFE << shift;
1011
+ complain = PROFILE_COMPLAIN(profile);
1013
+ /* Confined task, determine what mode inherit, unconfined or
1014
+ * mandatory to load new profile
1016
+ exec_mode = aa_match(profile->file_rules, filename,
1020
+ if (exec_mode & sa.request_mask) {
1021
+ int xm = exec_mode >> shift;
1022
+ new_profile = aa_x_to_profile(profile, filename,
1025
+ if (!new_profile && (xm & AA_EXEC_INHERIT))
1026
+ /* (p|c|n|)ix - don't change profile */
1028
+ /* error case caught below */
1030
+ } else if (sa.request_mask & AUDIT_QUIET_MASK(sa.audit_mask)) {
1031
+ /* quiet failed exit */
1032
+ new_profile = ERR_PTR(-EACCES);
1033
+ } else if (complain) {
1034
+ /* There was no entry in calling profile
1035
+ * describing mode to execute image in.
1036
+ * Drop into null-profile (disabling secure exec).
1039
+ aa_dup_profile(profile->ns->null_complain_profile);
1040
+ exec_mode |= AA_EXEC_UNSAFE << shift;
1042
+ sa.denied_mask = sa.request_mask;
1043
+ sa.error_code = -EACCES;
1044
+ new_profile = ERR_PTR(aa_audit_file(profile, &sa));
1047
+ /* Unconfined task, load profile if it exists */
1048
+ new_profile = aa_register_find(NULL, NULL, filename, 0, 0, &sa);
1049
+ if (new_profile == NULL)
1053
+ if (IS_ERR(new_profile))
1056
+ old_profile = __aa_replace_profile(current, new_profile);
1057
+ if (IS_ERR(old_profile)) {
1058
+ aa_put_profile(new_profile);
1059
+ aa_put_profile(profile);
1060
+ if (PTR_ERR(old_profile) == -ESTALE) {
1061
+ profile = aa_get_profile(current);
1064
+ if (PTR_ERR(old_profile) == -EPERM) {
1065
+ sa.denied_mask = sa.request_mask;
1066
+ sa.info = "unable to set profile due to ptrace";
1067
+ sa.task = current->parent->pid;
1068
+ aa_audit_reject(profile, &sa);
1070
+ new_profile = old_profile;
1073
+ aa_put_profile(old_profile);
1074
+ aa_put_profile(profile);
1076
+ /* Handle confined exec.
1077
+ * Can be at this point for the following reasons:
1078
+ * 1. unconfined switching to confined
1079
+ * 2. confined switching to different confinement
1080
+ * 3. confined switching to unconfined
1082
+ * Cases 2 and 3 are marked as requiring secure exec
1083
+ * (unless policy specified "unsafe exec")
1085
+ if (!(exec_mode & (AA_EXEC_UNSAFE << shift))) {
1086
+ unsigned long bprm_flags;
1088
+ bprm_flags = AA_SECURE_EXEC_NEEDED;
1089
+ bprm->security = (void*)
1090
+ ((unsigned long)bprm->security | bprm_flags);
1093
+ if (complain && new_profile &&
1094
+ new_profile == new_profile->ns->null_complain_profile) {
1095
+ sa.request_mask = 0;
1097
+ sa.info = "set profile";
1098
+ aa_audit_hint(new_profile, &sa);
1102
+ aa_put_name_buffer(child);
1103
+ aa_put_name_buffer(buffer);
1104
+ if (IS_ERR(new_profile))
1105
+ return PTR_ERR(new_profile);
1106
+ aa_put_profile(new_profile);
1111
+ * aa_release - release a task context
1112
+ * @task: task being released
1114
+ * This is called after a task has exited and the parent has reaped it.
1116
+void aa_release(struct task_struct *task)
1118
+ struct aa_task_context *cxt;
1119
+ struct aa_profile *profile;
1121
+ * While the task context is still on a profile's task context
1122
+ * list, another process could replace the profile under us,
1123
+ * leaving us with a locked profile that is no longer attached
1124
+ * to this task. So after locking the profile, we check that
1125
+ * the profile is still attached. The profile lock is
1126
+ * sufficient to prevent the replacement race so we do not lock
1129
+ * Use lock subtyping to avoid lockdep reporting a false irq
1130
+ * possible inversion between the task_lock and profile_lock
1132
+ * We also avoid taking the task_lock here because lock_dep
1133
+ * would report another false {softirq-on-W} potential irq_lock
1136
+ * If the task does not have a profile attached we are safe;
1137
+ * nothing can race with us at this point.
1141
+ profile = aa_get_profile(task);
1143
+ lock_profile_nested(profile, aa_lock_task_release);
1144
+ cxt = aa_task_context(task);
1145
+ if (unlikely(!cxt || cxt->profile != profile)) {
1146
+ unlock_profile(profile);
1147
+ aa_put_profile(profile);
1150
+ aa_change_task_context(task, NULL, NULL, 0, NULL);
1151
+ unlock_profile(profile);
1152
+ aa_put_profile(profile);
1156
+static int do_change_profile(struct aa_profile *expected,
1157
+ struct aa_namespace *ns, const char *name,
1158
+ u64 cookie, int restore, int hat,
1159
+ struct aa_audit *sa)
1161
+ struct aa_profile *new_profile = NULL, *old_profile = NULL,
1162
+ *previous_profile = NULL;
1163
+ struct aa_task_context *new_cxt, *cxt;
1168
+ new_cxt = aa_alloc_task_context(GFP_KERNEL);
1172
+ new_profile = aa_find_profile(ns, name);
1173
+ if (!new_profile && !restore) {
1174
+ if (!PROFILE_COMPLAIN(expected)) {
1175
+ aa_free_task_context(new_cxt);
1178
+ new_profile = aa_dup_profile(ns->null_complain_profile);
1179
+ } else if (new_profile && hat && !PROFILE_IS_HAT(new_profile)) {
1180
+ aa_free_task_context(new_cxt);
1181
+ aa_put_profile(new_profile);
1185
+ cxt = lock_task_and_profiles(current, new_profile);
1190
+ old_profile = cxt->profile;
1192
+ if (cxt->profile != expected || (new_profile && new_profile->isstale)) {
1197
+ if (cxt->previous_profile) {
1198
+ if (cxt->cookie != cookie) {
1200
+ sa->info = "killing process";
1201
+ aa_audit_reject(cxt->profile, sa);
1202
+ /* terminate process */
1203
+ (void)send_sig_info(SIGKILL, NULL, current);
1208
+ previous_profile = cxt->previous_profile;
1210
+ previous_profile = cxt->profile;
1212
+ if ((current->ptrace & PT_PTRACED) && aa_may_ptrace(cxt, new_profile)) {
1217
+ if (new_profile == ns->null_complain_profile)
1218
+ aa_audit_hint(cxt->profile, sa);
1220
+ if (APPARMOR_AUDIT(cxt))
1221
+ aa_audit_message(cxt->profile, sa, AUDIT_APPARMOR_AUDIT);
1223
+ if (!restore && cookie)
1224
+ aa_change_task_context(current, new_cxt, new_profile, cookie,
1225
+ previous_profile);
1227
+ /* either return to previous_profile, or a permanent change */
1228
+ aa_change_task_context(current, new_cxt, new_profile, 0, NULL);
1231
+ if (aa_task_context(current) != new_cxt)
1232
+ aa_free_task_context(new_cxt);
1233
+ task_unlock(current);
1234
+ unlock_both_profiles(old_profile, new_profile);
1235
+ aa_put_profile(new_profile);
1240
+ * aa_change_profile - perform a one-way profile transition
1241
+ * @ns_name: name of the profile namespace to change to
1242
+ * @name: name of profile to change to
1243
+ * Change to new profile @name. Unlike with hats, there is no way
1246
+ * Returns %0 on success, error otherwise.
1248
+int aa_change_profile(const char *ns_name, const char *name)
1250
+ struct aa_task_context *cxt;
1251
+ struct aa_profile *profile = NULL;
1252
+ struct aa_namespace *ns = NULL;
1253
+ struct aa_audit sa;
1254
+ unsigned int state;
1255
+ int error = -EINVAL;
1260
+ memset(&sa, 0, sizeof(sa));
1261
+ sa.gfp_mask = GFP_ATOMIC;
1262
+ sa.operation = "change_profile";
1265
+ task_lock(current);
1266
+ cxt = aa_task_context(current);
1268
+ profile = aa_dup_profile(cxt->profile);
1269
+ task_unlock(current);
1272
+ ns = aa_find_namespace(ns_name);
1274
+ ns = aa_get_namespace(profile->ns);
1276
+ ns = aa_get_namespace(default_namespace);
1279
+ aa_put_profile(profile);
1283
+ if (!profile || PROFILE_COMPLAIN(profile) ||
1284
+ (ns == profile->ns &&
1285
+ (aa_match(profile->file_rules, name, NULL) & AA_CHANGE_PROFILE)))
1286
+ error = do_change_profile(profile, ns, name, 0, 0, 0, &sa);
1288
+ /* check for a rule with a namespace prepended */
1289
+ aa_match_state(profile->file_rules, DFA_START, ns->name,
1291
+ state = aa_dfa_null_transition(profile->file_rules, state);
1292
+ if ((aa_match_state(profile->file_rules, state, name, NULL) &
1293
+ AA_CHANGE_PROFILE))
1294
+ error = do_change_profile(profile, ns, name, 0, 0, 0,
1297
+ /* no permission to transition to profile @name */
1301
+ aa_put_namespace(ns);
1302
+ aa_put_profile(profile);
1303
+ if (error == -ESTALE)
1310
+ * aa_change_hat - change hat to/from subprofile
1311
+ * @hat_name: hat to change to
1312
+ * @cookie: magic value to validate the hat change
1314
+ * Change to new @hat_name, and store the @hat_magic in the current task
1315
+ * context. If the new @hat_name is %NULL and the @cookie matches that
1316
+ * stored in the current task context and is not 0, return to the top level
1318
+ * Returns %0 on success, error otherwise.
1320
+int aa_change_hat(const char *hat_name, u64 cookie)
1322
+ struct aa_task_context *cxt;
1323
+ struct aa_profile *profile, *previous_profile;
1324
+ struct aa_audit sa;
1327
+ memset(&sa, 0, sizeof(sa));
1328
+ sa.gfp_mask = GFP_ATOMIC;
1329
+ sa.operation = "change_hat";
1332
+ task_lock(current);
1333
+ cxt = aa_task_context(current);
1335
+ task_unlock(current);
1338
+ profile = aa_dup_profile(cxt->profile);
1339
+ previous_profile = aa_dup_profile(cxt->previous_profile);
1340
+ task_unlock(current);
1343
+ char *name, *profile_name;
1345
+ if (previous_profile)
1346
+ profile_name = previous_profile->name;
1348
+ profile_name = profile->name;
1350
+ name = new_compound_name(profile_name, hat_name);
1355
+ error = do_change_profile(profile, profile->ns, name, cookie,
1357
+ aa_put_name_buffer(name);
1358
+ } else if (previous_profile)
1359
+ error = do_change_profile(profile, profile->ns,
1360
+ previous_profile->name, cookie, 1, 0,
1362
+ /* else ignore restores when there is no saved profile */
1365
+ aa_put_profile(previous_profile);
1366
+ aa_put_profile(profile);
1367
+ if (error == -ESTALE)
1374
+ * __aa_replace_profile - replace a task's profile
1375
+ * @task: task to switch the profile of
1376
+ * @profile: profile to switch to
1378
+ * Returns a handle to the previous profile upon success, or else an
1381
+struct aa_profile *__aa_replace_profile(struct task_struct *task,
1382
+ struct aa_profile *profile)
1384
+ struct aa_task_context *cxt, *new_cxt = NULL;
1385
+ struct aa_profile *old_profile = NULL;
1388
+ new_cxt = aa_alloc_task_context(GFP_KERNEL);
1390
+ return ERR_PTR(-ENOMEM);
1393
+ cxt = lock_task_and_profiles(task, profile);
1394
+ if (unlikely(profile && profile->isstale)) {
1395
+ task_unlock(task);
1396
+ unlock_both_profiles(profile, cxt ? cxt->profile : NULL);
1397
+ aa_free_task_context(new_cxt);
1398
+ return ERR_PTR(-ESTALE);
1401
+ if ((current->ptrace & PT_PTRACED) && aa_may_ptrace(cxt, profile)) {
1402
+ task_unlock(task);
1403
+ unlock_both_profiles(profile, cxt ? cxt->profile : NULL);
1404
+ aa_free_task_context(new_cxt);
1405
+ return ERR_PTR(-EPERM);
1409
+ old_profile = aa_dup_profile(cxt->profile);
1410
+ aa_change_task_context(task, new_cxt, profile, 0, NULL);
1412
+ task_unlock(task);
1413
+ unlock_both_profiles(profile, old_profile);
1414
+ return old_profile;
1418
+ * lock_task_and_profiles - lock the task and confining profiles and @profile
1419
+ * @task: task to lock
1420
+ * @profile: extra profile to lock in addition to the current profile
1422
+ * Handle the spinning on locking to make sure the task context and
1423
+ * profile are consistent once all locks are aquired.
1425
+ * return the aa_task_context currently confining the task. The task lock
1426
+ * will be held whether or not the task is confined.
1428
+struct aa_task_context *
1429
+lock_task_and_profiles(struct task_struct *task, struct aa_profile *profile)
1431
+ struct aa_task_context *cxt;
1432
+ struct aa_profile *old_profile = NULL;
1436
+ cxt = aa_task_context(task);
1438
+ old_profile = cxt->profile;
1440
+ lock_both_profiles(profile, old_profile);
1443
+ /* check for race with profile transition, replacement or removal */
1444
+ if (unlikely(cxt != aa_task_context(task))) {
1445
+ task_unlock(task);
1446
+ unlock_both_profiles(profile, old_profile);
1447
+ old_profile = NULL;
1450
+ rcu_read_unlock();
1454
+static void free_aa_task_context_rcu_callback(struct rcu_head *head)
1456
+ struct aa_task_context *cxt;
1458
+ cxt = container_of(head, struct aa_task_context, rcu);
1459
+ aa_free_task_context(cxt);
1463
+ * aa_change_task_context - switch a task to use a new context and profile
1464
+ * @task: task that is having its task context changed
1465
+ * @new_cxt: new task context to use after the switch
1466
+ * @profile: new profile to use after the switch
1467
+ * @cookie: magic value to switch to
1468
+ * @previous_profile: profile the task can return to
1470
+void aa_change_task_context(struct task_struct *task,
1471
+ struct aa_task_context *new_cxt,
1472
+ struct aa_profile *profile, u64 cookie,
1473
+ struct aa_profile *previous_profile)
1475
+ struct aa_task_context *old_cxt = aa_task_context(task);
1478
+ list_del_init(&old_cxt->list);
1479
+ call_rcu(&old_cxt->rcu, free_aa_task_context_rcu_callback);
1482
+ /* set the caps_logged cache to the quiet_caps mask
1483
+ * this has the effect of quieting caps that are not
1484
+ * supposed to be logged
1486
+ new_cxt->caps_logged = profile->quiet_caps;
1487
+ new_cxt->cookie = cookie;
1488
+ new_cxt->task = task;
1489
+ new_cxt->profile = aa_dup_profile(profile);
1490
+ new_cxt->previous_profile = aa_dup_profile(previous_profile);
1491
+ list_move(&new_cxt->list, &profile->task_contexts);
1493
+ rcu_assign_pointer(task->security, new_cxt);