]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blame - src/patches/suse-2.6.27.31/patches.apparmor/apparmor-main.diff
Add a patch to fix Intel E100 wake-on-lan problems.
[people/pmueller/ipfire-2.x.git] / src / patches / suse-2.6.27.31 / patches.apparmor / apparmor-main.diff
CommitLineData
6a930a95
BS
1From: John Johansen <jjohansen@suse.de>
2Subject: AppArmor: Main Part
3
4The underlying functions by which the AppArmor LSM hooks are implemented.
5
6Signed-off-by: John Johansen <jjohansen@suse.de>
7Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
8
9---
10 security/apparmor/main.c | 1478 +++++++++++++++++++++++++++++++++++++++++++++++
11 1 file changed, 1478 insertions(+)
12
13--- /dev/null
14+++ b/security/apparmor/main.c
15@@ -0,0 +1,1478 @@
16+/*
17+ * Copyright (C) 2002-2007 Novell/SUSE
18+ *
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
22+ * License.
23+ *
24+ * AppArmor Core
25+ */
26+
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>
32+
33+#include "apparmor.h"
34+
35+#include "inline.h"
36+
37+/*
38+ * Table of capability names: we generate it from capabilities.h.
39+ */
40+static const char *capability_names[] = {
41+#include "capability_names.h"
42+};
43+
44+struct aa_namespace *default_namespace;
45+
46+static int aa_inode_mode(struct inode *inode)
47+{
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;
52+}
53+
54+int alloc_default_namespace(void)
55+{
56+ struct aa_namespace *ns;
57+ char *name = kstrdup("default", GFP_KERNEL);
58+ if (!name)
59+ return -ENOMEM;
60+ ns = alloc_aa_namespace(name);
61+ if (!ns) {
62+ kfree(name);
63+ return -ENOMEM;
64+ }
65+
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);
71+
72+ return 0;
73+}
74+
75+void free_default_namespace(void)
76+{
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;
82+}
83+
84+static void aa_audit_file_sub_mask(struct audit_buffer *ab, char *buffer,
85+ int mask)
86+{
87+ const char unsafex[] = "upcn";
88+ const char safex[] = "UPCN";
89+ char *m = buffer;
90+
91+ if (mask & AA_EXEC_MMAP)
92+ *m++ = 'm';
93+ if (mask & MAY_READ)
94+ *m++ = 'r';
95+ if (mask & MAY_WRITE)
96+ *m++ = 'w';
97+ else if (mask & MAY_APPEND)
98+ *m++ = 'a';
99+ if (mask & MAY_EXEC) {
100+ int index = AA_EXEC_INDEX(mask);
101+ /* all indexes > 4 are also named transitions */
102+ if (index > 4)
103+ index = 4;
104+ if (index > 0) {
105+ if (mask & AA_EXEC_UNSAFE)
106+ *m++ = unsafex[index - 1];
107+ else
108+ *m++ = safex[index - 1];
109+ }
110+ if (mask & AA_EXEC_INHERIT)
111+ *m++ = 'i';
112+ *m++ = 'x';
113+ }
114+ if (mask & AA_MAY_LINK)
115+ *m++ = 'l';
116+ if (mask & AA_MAY_LOCK)
117+ *m++ = 'k';
118+ *m++ = '\0';
119+}
120+
121+static void aa_audit_file_mask(struct audit_buffer *ab, const char *name,
122+ int mask)
123+{
124+ char user[10], other[10];
125+
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);
130+
131+ audit_log_format(ab, " %s=\"%s::%s\"", name, user, other);
132+}
133+
134+/**
135+ * aa_audit - Log an audit event to the audit subsystem
136+ * @profile: profile to check against
137+ * @sa: audit event
138+ * @audit_cxt: audit context to log message to
139+ * @type: audit event number
140+ */
141+static int aa_audit_base(struct aa_profile *profile, struct aa_audit *sa,
142+ struct audit_context *audit_cxt, int type)
143+{
144+ struct audit_buffer *ab = NULL;
145+
146+ ab = audit_log_start(audit_cxt, sa->gfp_mask, type);
147+
148+ if (!ab) {
149+ AA_ERROR("Unable to log event (%d) to audit subsys\n",
150+ type);
151+ /* don't fail operations in complain mode even if logging
152+ * fails */
153+ return type == AUDIT_APPARMOR_ALLOWED ? 0 : -ENOMEM;
154+ }
155+
156+ if (sa->operation)
157+ audit_log_format(ab, "operation=\"%s\"", sa->operation);
158+
159+ if (sa->info) {
160+ audit_log_format(ab, " info=\"%s\"", sa->info);
161+ if (sa->error_code)
162+ audit_log_format(ab, " error=%d", sa->error_code);
163+ }
164+
165+ if (sa->request_mask)
166+ aa_audit_file_mask(ab, "requested_mask", sa->request_mask);
167+
168+ if (sa->denied_mask)
169+ aa_audit_file_mask(ab, "denied_mask", sa->denied_mask);
170+
171+ if (sa->request_mask)
172+ audit_log_format(ab, " fsuid=%d", current->fsuid);
173+
174+ if (sa->iattr) {
175+ struct iattr *iattr = sa->iattr;
176+
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) ?
183+ "atime," : "",
184+ iattr->ia_valid & (ATTR_MTIME | ATTR_MTIME_SET) ?
185+ "mtime," : "",
186+ iattr->ia_valid & ATTR_CTIME ? "ctime," : "");
187+ }
188+
189+ if (sa->task)
190+ audit_log_format(ab, " task=%d", sa->task);
191+
192+ if (sa->parent)
193+ audit_log_format(ab, " parent=%d", sa->parent);
194+
195+ if (sa->name) {
196+ audit_log_format(ab, " name=");
197+ audit_log_untrustedstring(ab, sa->name);
198+ }
199+
200+ if (sa->name2) {
201+ audit_log_format(ab, " name2=");
202+ audit_log_untrustedstring(ab, sa->name2);
203+ }
204+
205+ audit_log_format(ab, " pid=%d", current->pid);
206+
207+ if (profile) {
208+ audit_log_format(ab, " profile=");
209+ audit_log_untrustedstring(ab, profile->name);
210+
211+ if (profile->ns != default_namespace) {
212+ audit_log_format(ab, " namespace=");
213+ audit_log_untrustedstring(ab, profile->ns->name);
214+ }
215+ }
216+
217+ audit_log_end(ab);
218+
219+ return type == AUDIT_APPARMOR_ALLOWED ? 0 : sa->error_code;
220+}
221+
222+/**
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
227+ */
228+int aa_audit_syscallreject(struct aa_profile *profile, gfp_t gfp,
229+ const char *msg)
230+{
231+ struct aa_audit sa;
232+ memset(&sa, 0, sizeof(sa));
233+ sa.operation = "syscall";
234+ sa.name = msg;
235+ sa.gfp_mask = gfp;
236+ sa.error_code = -EPERM;
237+
238+ return aa_audit_base(profile, &sa, current->audit_context,
239+ AUDIT_APPARMOR_DENIED);
240+}
241+
242+int aa_audit_message(struct aa_profile *profile, struct aa_audit *sa,
243+ int type)
244+{
245+ struct audit_context *audit_cxt;
246+
247+ audit_cxt = apparmor_logsyscall ? current->audit_context : NULL;
248+ return aa_audit_base(profile, sa, audit_cxt, type);
249+}
250+
251+void aa_audit_hint(struct aa_profile *profile, struct aa_audit *sa)
252+{
253+ aa_audit_message(profile, sa, AUDIT_APPARMOR_HINT);
254+}
255+
256+void aa_audit_status(struct aa_profile *profile, struct aa_audit *sa)
257+{
258+ aa_audit_message(profile, sa, AUDIT_APPARMOR_STATUS);
259+}
260+
261+int aa_audit_reject(struct aa_profile *profile, struct aa_audit *sa)
262+{
263+ return aa_audit_message(profile, sa, AUDIT_APPARMOR_DENIED);
264+}
265+
266+/**
267+ * aa_audit - Log an audit event to the audit subsystem
268+ * @profile: profile to check against
269+ * @sa: audit event
270+ */
271+int aa_audit(struct aa_profile *profile, struct aa_audit *sa)
272+{
273+ int type = AUDIT_APPARMOR_DENIED;
274+ struct audit_context *audit_cxt;
275+
276+ if (likely(!sa->error_code))
277+ type = AUDIT_APPARMOR_AUDIT;
278+ else if (PROFILE_COMPLAIN(profile))
279+ type = AUDIT_APPARMOR_ALLOWED;
280+
281+ audit_cxt = apparmor_logsyscall ? current->audit_context : NULL;
282+ return aa_audit_base(profile, sa, audit_cxt, type);
283+}
284+
285+static int aa_audit_file(struct aa_profile *profile, struct aa_audit *sa)
286+{
287+ if (likely(!sa->error_code)) {
288+ int mask = sa->audit_mask & AUDIT_FILE_MASK;
289+
290+ if (unlikely(PROFILE_AUDIT(profile)))
291+ mask |= AUDIT_FILE_MASK;
292+
293+ if (likely(!(sa->request_mask & mask)))
294+ return 0;
295+
296+ /* mask off perms that are not being force audited */
297+ sa->request_mask &= mask | ALL_AA_EXEC_TYPE;
298+ } else {
299+ int mask = AUDIT_QUIET_MASK(sa->audit_mask);
300+
301+ if (!(sa->denied_mask & ~mask))
302+ return sa->error_code;
303+
304+ /* mask off perms whose denial is being silenced */
305+ sa->denied_mask &= (~mask) | ALL_AA_EXEC_TYPE;
306+ }
307+
308+ return aa_audit(profile, sa);
309+}
310+
311+static int aa_audit_caps(struct aa_profile *profile, struct aa_audit *sa,
312+ int cap)
313+{
314+ if (likely(!sa->error_code)) {
315+ if (likely(!PROFILE_AUDIT(profile) &&
316+ !cap_raised(profile->audit_caps, cap)))
317+ return 0;
318+ }
319+
320+ /* quieting of capabilities is handled the caps_logged cache */
321+ return aa_audit(profile, sa);
322+}
323+
324+/**
325+ * aa_file_denied - check for @mask access on a file
326+ * @profile: profile to check against
327+ * @name: pathname of file
328+ * @mask: permission mask requested for file
329+ * @audit_mask: return audit mask for the match
330+ *
331+ * Return %0 on success, or else the permissions in @mask that the
332+ * profile denies.
333+ */
334+static int aa_file_denied(struct aa_profile *profile, const char *name,
335+ int mask, int *audit_mask)
336+{
337+ return (mask & ~aa_match(profile->file_rules, name, audit_mask));
338+}
339+
340+/**
341+ * aa_link_denied - check for permission to link a file
342+ * @profile: profile to check against
343+ * @link: pathname of link being created
344+ * @target: pathname of target to be linked to
345+ * @target_mode: UGO shift for target inode
346+ * @request_mask: the permissions subset valid only if link succeeds
347+ * @audit_mask: return the audit_mask for the link permission
348+ * Return %0 on success, or else the permissions that the profile denies.
349+ */
350+static int aa_link_denied(struct aa_profile *profile, const char *link,
351+ const char *target, int target_mode,
352+ int *request_mask, int *audit_mask)
353+{
354+ unsigned int state;
355+ int l_mode, t_mode, l_x, t_x, denied_mask = 0;
356+ int link_mask = AA_MAY_LINK << target_mode;
357+
358+ *request_mask = link_mask;
359+
360+ l_mode = aa_match_state(profile->file_rules, DFA_START, link, &state);
361+
362+ if (l_mode & link_mask) {
363+ int mode;
364+ /* test to see if target can be paired with link */
365+ state = aa_dfa_null_transition(profile->file_rules, state);
366+ mode = aa_match_state(profile->file_rules, state, target,
367+ &state);
368+
369+ if (!(mode & link_mask))
370+ denied_mask |= link_mask;
371+
372+ *audit_mask = dfa_audit_mask(profile->file_rules, state);
373+
374+ /* return if link subset test is not required */
375+ if (!(mode & (AA_LINK_SUBSET_TEST << target_mode)))
376+ return denied_mask;
377+ }
378+
379+ /* Do link perm subset test requiring permission on link are a
380+ * subset of the permissions on target.
381+ * If a subset test is required a permission subset test of the
382+ * perms for the link are done against the user::other of the
383+ * target's 'r', 'w', 'x', 'a', 'k', and 'm' permissions.
384+ *
385+ * If the link has 'x', an exact match of all the execute flags
386+ * must match.
387+ */
388+ denied_mask |= ~l_mode & link_mask;
389+
390+ t_mode = aa_match(profile->file_rules, target, NULL);
391+
392+ l_x = l_mode & (ALL_AA_EXEC_TYPE | AA_EXEC_BITS);
393+ t_x = t_mode & (ALL_AA_EXEC_TYPE | AA_EXEC_BITS);
394+
395+ /* For actual subset test ignore valid-profile-transition flags,
396+ * and link bits
397+ */
398+ l_mode &= AA_FILE_PERMS & ~AA_LINK_BITS;
399+ t_mode &= AA_FILE_PERMS & ~AA_LINK_BITS;
400+
401+ *request_mask = l_mode | link_mask;
402+
403+ if (l_mode) {
404+ int x = l_x | (t_x & ALL_AA_EXEC_UNSAFE);
405+ denied_mask |= l_mode & ~t_mode;
406+ /* mask off x modes not used by link */
407+
408+ /* handle exec subset
409+ * - link safe exec issubset of unsafe exec
410+ * - no link x perm is subset of target having x perm
411+ */
412+ if ((l_mode & AA_USER_EXEC) &&
413+ (x & AA_USER_EXEC_TYPE) != (t_x & AA_USER_EXEC_TYPE))
414+ denied_mask = AA_USER_EXEC | (l_x & AA_USER_EXEC_TYPE);
415+ if ((l_mode & AA_OTHER_EXEC) &&
416+ (x & AA_OTHER_EXEC_TYPE) != (t_x & AA_OTHER_EXEC_TYPE))
417+ denied_mask = AA_OTHER_EXEC | (l_x & AA_OTHER_EXEC_TYPE);
418+ }
419+
420+ return denied_mask;
421+}
422+
423+/**
424+ * aa_get_name - compute the pathname of a file
425+ * @dentry: dentry of the file
426+ * @mnt: vfsmount of the file
427+ * @buffer: buffer that aa_get_name() allocated
428+ * @check: AA_CHECK_DIR is set if the file is a directory
429+ *
430+ * Returns a pointer to the beginning of the pathname (which usually differs
431+ * from the beginning of the buffer), or an error code.
432+ *
433+ * We need @check to indicate whether the file is a directory or not because
434+ * the file may not yet exist, and so we cannot check the inode's file type.
435+ */
436+static char *aa_get_name(struct dentry *dentry, struct vfsmount *mnt,
437+ char **buffer, int check)
438+{
439+ char *name;
440+ int is_dir, size = 256;
441+
442+ is_dir = (check & AA_CHECK_DIR) ? 1 : 0;
443+
444+ for (;;) {
445+ char *buf = kmalloc(size, GFP_KERNEL);
446+ if (!buf)
447+ return ERR_PTR(-ENOMEM);
448+
449+ name = d_namespace_path(dentry, mnt, buf, size - is_dir);
450+ if (!IS_ERR(name)) {
451+ if (name[0] != '/') {
452+ /*
453+ * This dentry is not connected to the
454+ * namespace root -- reject access.
455+ */
456+ kfree(buf);
457+ return ERR_PTR(-ENOENT);
458+ }
459+ if (is_dir && name[1] != '\0') {
460+ /*
461+ * Append "/" to the pathname. The root
462+ * directory is a special case; it already
463+ * ends in slash.
464+ */
465+ buf[size - 2] = '/';
466+ buf[size - 1] = '\0';
467+ }
468+
469+ *buffer = buf;
470+ return name;
471+ }
472+ if (PTR_ERR(name) != -ENAMETOOLONG)
473+ return name;
474+
475+ kfree(buf);
476+ size <<= 1;
477+ if (size > apparmor_path_max)
478+ return ERR_PTR(-ENAMETOOLONG);
479+ }
480+}
481+
482+static char *new_compound_name(const char *n1, const char *n2)
483+{
484+ char *name = kmalloc(strlen(n1) + strlen(n2) + 3, GFP_KERNEL);
485+ if (name)
486+ sprintf(name, "%s//%s", n1, n2);
487+ return name;
488+}
489+static inline void aa_put_name_buffer(char *buffer)
490+{
491+ kfree(buffer);
492+}
493+
494+/**
495+ * aa_perm_dentry - check if @profile allows @mask for a file
496+ * @profile: profile to check against
497+ * @dentry: dentry of the file
498+ * @mnt: vfsmount o the file
499+ * @sa: audit context
500+ * @mask: requested profile permissions
501+ * @check: kind of check to perform
502+ *
503+ * Returns 0 upon success, or else an error code.
504+ *
505+ * @check indicates the file type, and whether the file was accessed through
506+ * an open file descriptor (AA_CHECK_FD) or not.
507+ */
508+static int aa_perm_dentry(struct aa_profile *profile, struct dentry *dentry,
509+ struct vfsmount *mnt, struct aa_audit *sa, int check)
510+{
511+ int error;
512+ char *buffer = NULL;
513+
514+ sa->name = aa_get_name(dentry, mnt, &buffer, check);
515+ sa->request_mask <<= aa_inode_mode(dentry->d_inode);
516+ if (IS_ERR(sa->name)) {
517+ /*
518+ * deleted files are given a pass on permission checks when
519+ * accessed through a file descriptor.
520+ */
521+ if (PTR_ERR(sa->name) == -ENOENT && (check & AA_CHECK_FD))
522+ sa->denied_mask = 0;
523+ else {
524+ sa->denied_mask = sa->request_mask;
525+ sa->error_code = PTR_ERR(sa->name);
526+ if (sa->error_code == -ENOENT)
527+ sa->info = "Failed name resolution - object not a valid entry";
528+ else if (sa->error_code == -ENAMETOOLONG)
529+ sa->info = "Failed name resolution - name too long";
530+ else
531+ sa->info = "Failed name resolution";
532+ }
533+ sa->name = NULL;
534+ } else
535+ sa->denied_mask = aa_file_denied(profile, sa->name,
536+ sa->request_mask,
537+ &sa->audit_mask);
538+
539+ if (!sa->denied_mask)
540+ sa->error_code = 0;
541+
542+ error = aa_audit_file(profile, sa);
543+ aa_put_name_buffer(buffer);
544+
545+ return error;
546+}
547+
548+/**
549+ * aa_attr - check if attribute change is allowed
550+ * @profile: profile to check against
551+ * @dentry: dentry of the file to check
552+ * @mnt: vfsmount of the file to check
553+ * @iattr: attribute changes requested
554+ */
555+int aa_attr(struct aa_profile *profile, struct dentry *dentry,
556+ struct vfsmount *mnt, struct iattr *iattr)
557+{
558+ struct inode *inode = dentry->d_inode;
559+ int error, check;
560+ struct aa_audit sa;
561+
562+ memset(&sa, 0, sizeof(sa));
563+ sa.operation = "setattr";
564+ sa.gfp_mask = GFP_KERNEL;
565+ sa.iattr = iattr;
566+ sa.request_mask = MAY_WRITE;
567+ sa.error_code = -EACCES;
568+
569+ check = 0;
570+ if (inode && S_ISDIR(inode->i_mode))
571+ check |= AA_CHECK_DIR;
572+ if (iattr->ia_valid & ATTR_FILE)
573+ check |= AA_CHECK_FD;
574+
575+ error = aa_perm_dentry(profile, dentry, mnt, &sa, check);
576+
577+ return error;
578+}
579+
580+/**
581+ * aa_perm_xattr - check if xattr attribute change is allowed
582+ * @profile: profile to check against
583+ * @dentry: dentry of the file to check
584+ * @mnt: vfsmount of the file to check
585+ * @operation: xattr operation being done
586+ * @mask: access mode requested
587+ * @check: kind of check to perform
588+ */
589+int aa_perm_xattr(struct aa_profile *profile, const char *operation,
590+ struct dentry *dentry, struct vfsmount *mnt, int mask,
591+ int check)
592+{
593+ struct inode *inode = dentry->d_inode;
594+ int error;
595+ struct aa_audit sa;
596+
597+ memset(&sa, 0, sizeof(sa));
598+ sa.operation = operation;
599+ sa.gfp_mask = GFP_KERNEL;
600+ sa.request_mask = mask;
601+ sa.error_code = -EACCES;
602+
603+ if (inode && S_ISDIR(inode->i_mode))
604+ check |= AA_CHECK_DIR;
605+
606+ error = aa_perm_dentry(profile, dentry, mnt, &sa, check);
607+
608+ return error;
609+}
610+
611+/**
612+ * aa_perm - basic apparmor permissions check
613+ * @profile: profile to check against
614+ * @dentry: dentry of the file to check
615+ * @mnt: vfsmount of the file to check
616+ * @mask: access mode requested
617+ * @check: kind of check to perform
618+ *
619+ * Determine if access @mask for the file is authorized by @profile.
620+ * Returns 0 on success, or else an error code.
621+ */
622+int aa_perm(struct aa_profile *profile, const char *operation,
623+ struct dentry *dentry, struct vfsmount *mnt, int mask, int check)
624+{
625+ struct aa_audit sa;
626+ int error = 0;
627+
628+ if (mask == 0)
629+ goto out;
630+
631+ memset(&sa, 0, sizeof(sa));
632+ sa.operation = operation;
633+ sa.gfp_mask = GFP_KERNEL;
634+ sa.request_mask = mask;
635+ sa.error_code = -EACCES;
636+
637+ error = aa_perm_dentry(profile, dentry, mnt, &sa, check);
638+
639+out:
640+ return error;
641+}
642+
643+/**
644+ * aa_perm_dir
645+ * @profile: profile to check against
646+ * @dentry: dentry of directory to check
647+ * @mnt: vfsmount of directory to check
648+ * @operation: directory operation being performed
649+ * @mask: access mode requested
650+ *
651+ * Determine if directory operation (make/remove) for dentry is authorized
652+ * by @profile.
653+ * Returns 0 on success, or else an error code.
654+ */
655+int aa_perm_dir(struct aa_profile *profile, const char *operation,
656+ struct dentry *dentry, struct vfsmount *mnt, int mask)
657+{
658+ struct aa_audit sa;
659+
660+ memset(&sa, 0, sizeof(sa));
661+ sa.operation = operation;
662+ sa.gfp_mask = GFP_KERNEL;
663+ sa.request_mask = mask;
664+ sa.error_code = -EACCES;
665+
666+ return aa_perm_dentry(profile, dentry, mnt, &sa, AA_CHECK_DIR);
667+}
668+
669+int aa_perm_path(struct aa_profile *profile, const char *operation,
670+ const char *name, int mask, uid_t uid)
671+{
672+ struct aa_audit sa;
673+
674+ memset(&sa, 0, sizeof(sa));
675+ sa.operation = operation;
676+ sa.gfp_mask = GFP_KERNEL;
677+ sa.request_mask = mask;
678+ sa.name = name;
679+ if (current->fsuid == uid)
680+ sa.request_mask = mask << AA_USER_SHIFT;
681+ else
682+ sa.request_mask = mask << AA_OTHER_SHIFT;
683+
684+ sa.denied_mask = aa_file_denied(profile, name, sa.request_mask,
685+ &sa.audit_mask) ;
686+ sa.error_code = sa.denied_mask ? -EACCES : 0;
687+
688+ return aa_audit_file(profile, &sa);
689+}
690+
691+/**
692+ * aa_capability - test permission to use capability
693+ * @cxt: aa_task_context with profile to check against
694+ * @cap: capability to be tested
695+ *
696+ * Look up capability in profile capability set.
697+ * Returns 0 on success, or else an error code.
698+ */
699+int aa_capability(struct aa_task_context *cxt, int cap)
700+{
701+ int error = cap_raised(cxt->profile->capabilities, cap) ? 0 : -EPERM;
702+ struct aa_audit sa;
703+
704+ /* test if cap has alread been logged */
705+ if (cap_raised(cxt->caps_logged, cap)) {
706+ if (PROFILE_COMPLAIN(cxt->profile))
707+ error = 0;
708+ return error;
709+ } else
710+ /* don't worry about rcu replacement of the cxt here.
711+ * caps_logged is a cache to reduce the occurence of
712+ * duplicate messages in the log. The worst that can
713+ * happen is duplicate capability messages shows up in
714+ * the audit log
715+ */
716+ cap_raise(cxt->caps_logged, cap);
717+
718+ memset(&sa, 0, sizeof(sa));
719+ sa.operation = "capable";
720+ sa.gfp_mask = GFP_ATOMIC;
721+ sa.name = capability_names[cap];
722+ sa.error_code = error;
723+
724+ error = aa_audit_caps(cxt->profile, &sa, cap);
725+
726+ return error;
727+}
728+
729+/* must be used inside rcu_read_lock or task_lock */
730+int aa_may_ptrace(struct aa_task_context *cxt, struct aa_profile *tracee)
731+{
732+ if (!cxt || cxt->profile == tracee)
733+ return 0;
734+ return aa_capability(cxt, CAP_SYS_PTRACE);
735+}
736+
737+/**
738+ * aa_link - hard link check
739+ * @profile: profile to check against
740+ * @link: dentry of link being created
741+ * @link_mnt: vfsmount of link being created
742+ * @target: dentry of link target
743+ * @target_mnt: vfsmunt of link target
744+ *
745+ * Returns 0 on success, or else an error code.
746+ */
747+int aa_link(struct aa_profile *profile,
748+ struct dentry *link, struct vfsmount *link_mnt,
749+ struct dentry *target, struct vfsmount *target_mnt)
750+{
751+ int error;
752+ struct aa_audit sa;
753+ char *buffer = NULL, *buffer2 = NULL;
754+
755+ memset(&sa, 0, sizeof(sa));
756+ sa.operation = "inode_link";
757+ sa.gfp_mask = GFP_KERNEL;
758+ sa.name = aa_get_name(link, link_mnt, &buffer, 0);
759+ sa.name2 = aa_get_name(target, target_mnt, &buffer2, 0);
760+
761+ if (IS_ERR(sa.name)) {
762+ sa.error_code = PTR_ERR(sa.name);
763+ sa.name = NULL;
764+ }
765+ if (IS_ERR(sa.name2)) {
766+ sa.error_code = PTR_ERR(sa.name2);
767+ sa.name2 = NULL;
768+ }
769+
770+ if (sa.name && sa.name2) {
771+ sa.denied_mask = aa_link_denied(profile, sa.name, sa.name2,
772+ aa_inode_mode(target->d_inode),
773+ &sa.request_mask,
774+ &sa.audit_mask);
775+ sa.error_code = sa.denied_mask ? -EACCES : 0;
776+ }
777+
778+ error = aa_audit_file(profile, &sa);
779+
780+ aa_put_name_buffer(buffer);
781+ aa_put_name_buffer(buffer2);
782+
783+ return error;
784+}
785+
786+/*******************************
787+ * Global task related functions
788+ *******************************/
789+
790+/**
791+ * aa_clone - initialize the task context for a new task
792+ * @child: task that is being created
793+ *
794+ * Returns 0 on success, or else an error code.
795+ */
796+int aa_clone(struct task_struct *child)
797+{
798+ struct aa_task_context *cxt, *child_cxt;
799+ struct aa_profile *profile;
800+
801+ if (!aa_task_context(current))
802+ return 0;
803+ child_cxt = aa_alloc_task_context(GFP_KERNEL);
804+ if (!child_cxt)
805+ return -ENOMEM;
806+
807+repeat:
808+ profile = aa_get_profile(current);
809+ if (profile) {
810+ lock_profile(profile);
811+ cxt = aa_task_context(current);
812+ if (unlikely(profile->isstale || !cxt ||
813+ cxt->profile != profile)) {
814+ /**
815+ * Race with profile replacement or removal, or with
816+ * task context removal.
817+ */
818+ unlock_profile(profile);
819+ aa_put_profile(profile);
820+ goto repeat;
821+ }
822+
823+ /* No need to grab the child's task lock here. */
824+ aa_change_task_context(child, child_cxt, profile,
825+ cxt->cookie, cxt->previous_profile);
826+ unlock_profile(profile);
827+
828+ if (APPARMOR_COMPLAIN(child_cxt) &&
829+ profile == profile->ns->null_complain_profile) {
830+ struct aa_audit sa;
831+ memset(&sa, 0, sizeof(sa));
832+ sa.operation = "clone";
833+ sa.gfp_mask = GFP_KERNEL;
834+ sa.task = child->pid;
835+ aa_audit_hint(profile, &sa);
836+ }
837+ aa_put_profile(profile);
838+ } else
839+ aa_free_task_context(child_cxt);
840+
841+ return 0;
842+}
843+
844+static struct aa_profile *
845+aa_register_find(struct aa_profile *profile, const char* ns_name,
846+ const char *name, int mandatory, int complain,
847+ struct aa_audit *sa)
848+{
849+ struct aa_namespace *ns;
850+ struct aa_profile *new_profile;
851+ int ns_ref = 0;
852+
853+ if (profile)
854+ ns = profile->ns;
855+ else
856+ ns = default_namespace;
857+
858+ if (ns_name) {
859+ /* locate the profile namespace */
860+ ns = aa_find_namespace(ns_name);
861+ if (!ns) {
862+ if (mandatory) {
863+ sa->info = "profile namespace not found";
864+ sa->denied_mask = sa->request_mask;
865+ sa->error_code = -ENOENT;
866+ return ERR_PTR(-ENOENT);
867+ } else {
868+ return NULL;
869+ }
870+ }
871+ ns_ref++;
872+ }
873+
874+ /* Locate new profile */
875+ new_profile = aa_find_profile(ns, name);
876+
877+ if (new_profile) {
878+ AA_DEBUG("%s: setting profile %s\n",
879+ __FUNCTION__, new_profile->name);
880+ } else if (mandatory && profile) {
881+ sa->info = "mandatory profile missing";
882+ sa->denied_mask = sa->request_mask; /* shifted MAY_EXEC */
883+ if (complain) {
884+ aa_audit_hint(profile, sa);
885+ new_profile =
886+ aa_dup_profile(profile->ns->null_complain_profile);
887+ } else {
888+ sa->error_code = -EACCES;
889+ if (ns_ref)
890+ aa_put_namespace(ns);
891+ return ERR_PTR(-EACCES);
892+ }
893+ } else {
894+ /* Only way we can get into this code is if task
895+ * is unconfined, pix, nix.
896+ */
897+ AA_DEBUG("%s: No profile found for exec image '%s'\n",
898+ __FUNCTION__,
899+ name);
900+ }
901+ if (ns_ref)
902+ aa_put_namespace(ns);
903+ return new_profile;
904+}
905+
906+static struct aa_profile *
907+aa_x_to_profile(struct aa_profile *profile, const char *filename, int xmode,
908+ struct aa_audit *sa, char **child)
909+{
910+ struct aa_profile *new_profile = NULL;
911+ int ix = xmode & AA_EXEC_INHERIT;
912+ int complain = PROFILE_COMPLAIN(profile);
913+ int index;
914+
915+ *child = NULL;
916+ switch (xmode & AA_EXEC_MODIFIERS) {
917+ case 0:
918+ /* only valid with ix flag */
919+ ix = 1;
920+ break;
921+ case AA_EXEC_UNCONFINED:
922+ /* only valid without ix flag */
923+ ix = 0;
924+ break;
925+ case AA_EXEC_PROFILE:
926+ new_profile = aa_register_find(profile, NULL, filename, !ix,
927+ complain, sa);
928+ break;
929+ case AA_EXEC_CHILD:
930+ *child = new_compound_name(profile->name, filename);
931+ sa->name2 = *child;
932+ if (!*child) {
933+ sa->info = "Failed name resolution - exec failed";
934+ sa->error_code = -ENOMEM;
935+ new_profile = ERR_PTR(-ENOMEM);
936+ } else {
937+ new_profile = aa_register_find(profile, NULL, *child,
938+ !ix, complain, sa);
939+ }
940+ break;
941+ default:
942+ /* all other indexes are named transitions */
943+ index = AA_EXEC_INDEX(xmode);
944+ if (index - 4 > profile->exec_table_size) {
945+ sa->info = "invalid named transition - exec failed";
946+ sa->error_code = -EACCES;
947+ new_profile = ERR_PTR(-EACCES);
948+ } else {
949+ char *ns_name = NULL;
950+ char *name = profile->exec_table[index - 4];
951+ if (*name == ':') {
952+ ns_name = name + 1;
953+ name = ns_name + strlen(ns_name) + 1;
954+ }
955+ sa->name2 = name;
956+ sa->name3 = ns_name;
957+ new_profile =
958+ aa_register_find(profile, ns_name, name,
959+ !ix, complain, sa);
960+ }
961+ }
962+ if (IS_ERR(new_profile))
963+ /* all these failures must be audited - no quieting */
964+ return ERR_PTR(aa_audit_reject(profile, sa));
965+ return new_profile;
966+}
967+
968+/**
969+ * aa_register - register a new program
970+ * @bprm: binprm of program being registered
971+ *
972+ * Try to register a new program during execve(). This should give the
973+ * new program a valid aa_task_context if confined.
974+ */
975+int aa_register(struct linux_binprm *bprm)
976+{
977+ const char *filename;
978+ char *buffer = NULL, *child = NULL;
979+ struct file *filp = bprm->file;
980+ struct aa_profile *profile, *old_profile, *new_profile = NULL;
981+ int exec_mode, complain = 0, shift;
982+ struct aa_audit sa;
983+
984+ AA_DEBUG("%s\n", __FUNCTION__);
985+
986+ profile = aa_get_profile(current);
987+
988+ shift = aa_inode_mode(filp->f_dentry->d_inode);
989+ memset(&sa, 0, sizeof(sa));
990+ sa.operation = "exec";
991+ sa.gfp_mask = GFP_KERNEL;
992+ sa.request_mask = MAY_EXEC << shift;
993+
994+ filename = aa_get_name(filp->f_dentry, filp->f_vfsmnt, &buffer, 0);
995+ if (IS_ERR(filename)) {
996+ if (profile) {
997+ sa.info = "Failed name resolution - exec failed";
998+ sa.error_code = PTR_ERR(filename);
999+ aa_audit_file(profile, &sa);
1000+ return sa.error_code;
1001+ } else
1002+ return 0;
1003+ }
1004+ sa.name = filename;
1005+
1006+ exec_mode = AA_EXEC_UNSAFE << shift;
1007+
1008+repeat:
1009+ if (profile) {
1010+ complain = PROFILE_COMPLAIN(profile);
1011+
1012+ /* Confined task, determine what mode inherit, unconfined or
1013+ * mandatory to load new profile
1014+ */
1015+ exec_mode = aa_match(profile->file_rules, filename,
1016+ &sa.audit_mask);
1017+
1018+
1019+ if (exec_mode & sa.request_mask) {
1020+ int xm = exec_mode >> shift;
1021+ new_profile = aa_x_to_profile(profile, filename,
1022+ xm, &sa, &child);
1023+
1024+ if (!new_profile && (xm & AA_EXEC_INHERIT))
1025+ /* (p|c|n|)ix - don't change profile */
1026+ goto cleanup;
1027+ /* error case caught below */
1028+
1029+ } else if (sa.request_mask & AUDIT_QUIET_MASK(sa.audit_mask)) {
1030+ /* quiet failed exit */
1031+ new_profile = ERR_PTR(-EACCES);
1032+ } else if (complain) {
1033+ /* There was no entry in calling profile
1034+ * describing mode to execute image in.
1035+ * Drop into null-profile (disabling secure exec).
1036+ */
1037+ new_profile =
1038+ aa_dup_profile(profile->ns->null_complain_profile);
1039+ exec_mode |= AA_EXEC_UNSAFE << shift;
1040+ } else {
1041+ sa.denied_mask = sa.request_mask;
1042+ sa.error_code = -EACCES;
1043+ new_profile = ERR_PTR(aa_audit_file(profile, &sa));
1044+ }
1045+ } else {
1046+ /* Unconfined task, load profile if it exists */
1047+ new_profile = aa_register_find(NULL, NULL, filename, 0, 0, &sa);
1048+ if (new_profile == NULL)
1049+ goto cleanup;
1050+ }
1051+
1052+ if (IS_ERR(new_profile))
1053+ goto cleanup;
1054+
1055+ old_profile = __aa_replace_profile(current, new_profile);
1056+ if (IS_ERR(old_profile)) {
1057+ aa_put_profile(new_profile);
1058+ aa_put_profile(profile);
1059+ if (PTR_ERR(old_profile) == -ESTALE) {
1060+ profile = aa_get_profile(current);
1061+ goto repeat;
1062+ }
1063+ if (PTR_ERR(old_profile) == -EPERM) {
1064+ sa.denied_mask = sa.request_mask;
1065+ sa.info = "unable to set profile due to ptrace";
1066+ sa.task = current->parent->pid;
1067+ aa_audit_reject(profile, &sa);
1068+ }
1069+ new_profile = old_profile;
1070+ goto cleanup;
1071+ }
1072+ aa_put_profile(old_profile);
1073+ aa_put_profile(profile);
1074+
1075+ /* Handle confined exec.
1076+ * Can be at this point for the following reasons:
1077+ * 1. unconfined switching to confined
1078+ * 2. confined switching to different confinement
1079+ * 3. confined switching to unconfined
1080+ *
1081+ * Cases 2 and 3 are marked as requiring secure exec
1082+ * (unless policy specified "unsafe exec")
1083+ */
1084+ if (!(exec_mode & (AA_EXEC_UNSAFE << shift))) {
1085+ unsigned long bprm_flags;
1086+
1087+ bprm_flags = AA_SECURE_EXEC_NEEDED;
1088+ bprm->security = (void*)
1089+ ((unsigned long)bprm->security | bprm_flags);
1090+ }
1091+
1092+ if (complain && new_profile &&
1093+ new_profile == new_profile->ns->null_complain_profile) {
1094+ sa.request_mask = 0;
1095+ sa.name = NULL;
1096+ sa.info = "set profile";
1097+ aa_audit_hint(new_profile, &sa);
1098+ }
1099+
1100+cleanup:
1101+ aa_put_name_buffer(child);
1102+ aa_put_name_buffer(buffer);
1103+ if (IS_ERR(new_profile))
1104+ return PTR_ERR(new_profile);
1105+ aa_put_profile(new_profile);
1106+ return 0;
1107+}
1108+
1109+/**
1110+ * aa_release - release a task context
1111+ * @task: task being released
1112+ *
1113+ * This is called after a task has exited and the parent has reaped it.
1114+ */
1115+void aa_release(struct task_struct *task)
1116+{
1117+ struct aa_task_context *cxt;
1118+ struct aa_profile *profile;
1119+ /*
1120+ * While the task context is still on a profile's task context
1121+ * list, another process could replace the profile under us,
1122+ * leaving us with a locked profile that is no longer attached
1123+ * to this task. So after locking the profile, we check that
1124+ * the profile is still attached. The profile lock is
1125+ * sufficient to prevent the replacement race so we do not lock
1126+ * the task.
1127+ *
1128+ * Use lock subtyping to avoid lockdep reporting a false irq
1129+ * possible inversion between the task_lock and profile_lock
1130+ *
1131+ * We also avoid taking the task_lock here because lock_dep
1132+ * would report another false {softirq-on-W} potential irq_lock
1133+ * inversion.
1134+ *
1135+ * If the task does not have a profile attached we are safe;
1136+ * nothing can race with us at this point.
1137+ */
1138+
1139+repeat:
1140+ profile = aa_get_profile(task);
1141+ if (profile) {
1142+ lock_profile_nested(profile, aa_lock_task_release);
1143+ cxt = aa_task_context(task);
1144+ if (unlikely(!cxt || cxt->profile != profile)) {
1145+ unlock_profile(profile);
1146+ aa_put_profile(profile);
1147+ goto repeat;
1148+ }
1149+ aa_change_task_context(task, NULL, NULL, 0, NULL);
1150+ unlock_profile(profile);
1151+ aa_put_profile(profile);
1152+ }
1153+}
1154+
1155+static int do_change_profile(struct aa_profile *expected,
1156+ struct aa_namespace *ns, const char *name,
1157+ u64 cookie, int restore, int hat,
1158+ struct aa_audit *sa)
1159+{
1160+ struct aa_profile *new_profile = NULL, *old_profile = NULL,
1161+ *previous_profile = NULL;
1162+ struct aa_task_context *new_cxt, *cxt;
1163+ int error = 0;
1164+
1165+ sa->name = name;
1166+
1167+ new_cxt = aa_alloc_task_context(GFP_KERNEL);
1168+ if (!new_cxt)
1169+ return -ENOMEM;
1170+
1171+ new_profile = aa_find_profile(ns, name);
1172+ if (!new_profile && !restore) {
1173+ if (!PROFILE_COMPLAIN(expected)) {
1174+ aa_free_task_context(new_cxt);
1175+ return -ENOENT;
1176+ }
1177+ new_profile = aa_dup_profile(ns->null_complain_profile);
1178+ } else if (new_profile && hat && !PROFILE_IS_HAT(new_profile)) {
1179+ aa_free_task_context(new_cxt);
1180+ aa_put_profile(new_profile);
1181+ return error;
1182+ }
1183+
1184+ cxt = lock_task_and_profiles(current, new_profile);
1185+ if (!cxt) {
1186+ error = -EPERM;
1187+ goto out;
1188+ }
1189+ old_profile = cxt->profile;
1190+
1191+ if (cxt->profile != expected || (new_profile && new_profile->isstale)) {
1192+ error = -ESTALE;
1193+ goto out;
1194+ }
1195+
1196+ if (cxt->previous_profile) {
1197+ if (cxt->cookie != cookie) {
1198+ error = -EACCES;
1199+ sa->info = "killing process";
1200+ aa_audit_reject(cxt->profile, sa);
1201+ /* terminate process */
1202+ (void)send_sig_info(SIGKILL, NULL, current);
1203+ goto out;
1204+ }
1205+
1206+ if (!restore)
1207+ previous_profile = cxt->previous_profile;
1208+ } else
1209+ previous_profile = cxt->profile;
1210+
1211+ if ((current->ptrace & PT_PTRACED) && aa_may_ptrace(cxt, new_profile)) {
1212+ error = -EACCES;
1213+ goto out;
1214+ }
1215+
1216+ if (new_profile == ns->null_complain_profile)
1217+ aa_audit_hint(cxt->profile, sa);
1218+
1219+ if (APPARMOR_AUDIT(cxt))
1220+ aa_audit_message(cxt->profile, sa, AUDIT_APPARMOR_AUDIT);
1221+
1222+ if (!restore && cookie)
1223+ aa_change_task_context(current, new_cxt, new_profile, cookie,
1224+ previous_profile);
1225+ else
1226+ /* either return to previous_profile, or a permanent change */
1227+ aa_change_task_context(current, new_cxt, new_profile, 0, NULL);
1228+
1229+out:
1230+ if (aa_task_context(current) != new_cxt)
1231+ aa_free_task_context(new_cxt);
1232+ task_unlock(current);
1233+ unlock_both_profiles(old_profile, new_profile);
1234+ aa_put_profile(new_profile);
1235+ return error;
1236+}
1237+
1238+/**
1239+ * aa_change_profile - perform a one-way profile transition
1240+ * @ns_name: name of the profile namespace to change to
1241+ * @name: name of profile to change to
1242+ * Change to new profile @name. Unlike with hats, there is no way
1243+ * to change back.
1244+ *
1245+ * Returns %0 on success, error otherwise.
1246+ */
1247+int aa_change_profile(const char *ns_name, const char *name)
1248+{
1249+ struct aa_task_context *cxt;
1250+ struct aa_profile *profile = NULL;
1251+ struct aa_namespace *ns = NULL;
1252+ struct aa_audit sa;
1253+ unsigned int state;
1254+ int error = -EINVAL;
1255+
1256+ if (!name)
1257+ return -EINVAL;
1258+
1259+ memset(&sa, 0, sizeof(sa));
1260+ sa.gfp_mask = GFP_ATOMIC;
1261+ sa.operation = "change_profile";
1262+
1263+repeat:
1264+ task_lock(current);
1265+ cxt = aa_task_context(current);
1266+ if (cxt)
1267+ profile = aa_dup_profile(cxt->profile);
1268+ task_unlock(current);
1269+
1270+ if (ns_name)
1271+ ns = aa_find_namespace(ns_name);
1272+ else if (profile)
1273+ ns = aa_get_namespace(profile->ns);
1274+ else
1275+ ns = aa_get_namespace(default_namespace);
1276+
1277+ if (!ns) {
1278+ aa_put_profile(profile);
1279+ return -ENOENT;
1280+ }
1281+
1282+ if (!profile || PROFILE_COMPLAIN(profile) ||
1283+ (ns == profile->ns &&
1284+ (aa_match(profile->file_rules, name, NULL) & AA_CHANGE_PROFILE)))
1285+ error = do_change_profile(profile, ns, name, 0, 0, 0, &sa);
1286+ else {
1287+ /* check for a rule with a namespace prepended */
1288+ aa_match_state(profile->file_rules, DFA_START, ns->name,
1289+ &state);
1290+ state = aa_dfa_null_transition(profile->file_rules, state);
1291+ if ((aa_match_state(profile->file_rules, state, name, NULL) &
1292+ AA_CHANGE_PROFILE))
1293+ error = do_change_profile(profile, ns, name, 0, 0, 0,
1294+ &sa);
1295+ else
1296+ /* no permission to transition to profile @name */
1297+ error = -EACCES;
1298+ }
1299+
1300+ aa_put_namespace(ns);
1301+ aa_put_profile(profile);
1302+ if (error == -ESTALE)
1303+ goto repeat;
1304+
1305+ return error;
1306+}
1307+
1308+/**
1309+ * aa_change_hat - change hat to/from subprofile
1310+ * @hat_name: hat to change to
1311+ * @cookie: magic value to validate the hat change
1312+ *
1313+ * Change to new @hat_name, and store the @hat_magic in the current task
1314+ * context. If the new @hat_name is %NULL and the @cookie matches that
1315+ * stored in the current task context and is not 0, return to the top level
1316+ * profile.
1317+ * Returns %0 on success, error otherwise.
1318+ */
1319+int aa_change_hat(const char *hat_name, u64 cookie)
1320+{
1321+ struct aa_task_context *cxt;
1322+ struct aa_profile *profile, *previous_profile;
1323+ struct aa_audit sa;
1324+ int error = 0;
1325+
1326+ memset(&sa, 0, sizeof(sa));
1327+ sa.gfp_mask = GFP_ATOMIC;
1328+ sa.operation = "change_hat";
1329+
1330+repeat:
1331+ task_lock(current);
1332+ cxt = aa_task_context(current);
1333+ if (!cxt) {
1334+ task_unlock(current);
1335+ return -EPERM;
1336+ }
1337+ profile = aa_dup_profile(cxt->profile);
1338+ previous_profile = aa_dup_profile(cxt->previous_profile);
1339+ task_unlock(current);
1340+
1341+ if (hat_name) {
1342+ char *name, *profile_name;
1343+
1344+ if (previous_profile)
1345+ profile_name = previous_profile->name;
1346+ else
1347+ profile_name = profile->name;
1348+
1349+ name = new_compound_name(profile_name, hat_name);
1350+ if (!name) {
1351+ error = -ENOMEM;
1352+ goto out;
1353+ }
1354+ error = do_change_profile(profile, profile->ns, name, cookie,
1355+ 0, 1, &sa);
1356+ aa_put_name_buffer(name);
1357+ } else if (previous_profile)
1358+ error = do_change_profile(profile, profile->ns,
1359+ previous_profile->name, cookie, 1, 0,
1360+ &sa);
1361+ /* else ignore restores when there is no saved profile */
1362+
1363+out:
1364+ aa_put_profile(previous_profile);
1365+ aa_put_profile(profile);
1366+ if (error == -ESTALE)
1367+ goto repeat;
1368+
1369+ return error;
1370+}
1371+
1372+/**
1373+ * __aa_replace_profile - replace a task's profile
1374+ * @task: task to switch the profile of
1375+ * @profile: profile to switch to
1376+ *
1377+ * Returns a handle to the previous profile upon success, or else an
1378+ * error code.
1379+ */
1380+struct aa_profile *__aa_replace_profile(struct task_struct *task,
1381+ struct aa_profile *profile)
1382+{
1383+ struct aa_task_context *cxt, *new_cxt = NULL;
1384+ struct aa_profile *old_profile = NULL;
1385+
1386+ if (profile) {
1387+ new_cxt = aa_alloc_task_context(GFP_KERNEL);
1388+ if (!new_cxt)
1389+ return ERR_PTR(-ENOMEM);
1390+ }
1391+
1392+ cxt = lock_task_and_profiles(task, profile);
1393+ if (unlikely(profile && profile->isstale)) {
1394+ task_unlock(task);
1395+ unlock_both_profiles(profile, cxt ? cxt->profile : NULL);
1396+ aa_free_task_context(new_cxt);
1397+ return ERR_PTR(-ESTALE);
1398+ }
1399+
1400+ if ((current->ptrace & PT_PTRACED) && aa_may_ptrace(cxt, profile)) {
1401+ task_unlock(task);
1402+ unlock_both_profiles(profile, cxt ? cxt->profile : NULL);
1403+ aa_free_task_context(new_cxt);
1404+ return ERR_PTR(-EPERM);
1405+ }
1406+
1407+ if (cxt)
1408+ old_profile = aa_dup_profile(cxt->profile);
1409+ aa_change_task_context(task, new_cxt, profile, 0, NULL);
1410+
1411+ task_unlock(task);
1412+ unlock_both_profiles(profile, old_profile);
1413+ return old_profile;
1414+}
1415+
1416+/**
1417+ * lock_task_and_profiles - lock the task and confining profiles and @profile
1418+ * @task: task to lock
1419+ * @profile: extra profile to lock in addition to the current profile
1420+ *
1421+ * Handle the spinning on locking to make sure the task context and
1422+ * profile are consistent once all locks are aquired.
1423+ *
1424+ * return the aa_task_context currently confining the task. The task lock
1425+ * will be held whether or not the task is confined.
1426+ */
1427+struct aa_task_context *
1428+lock_task_and_profiles(struct task_struct *task, struct aa_profile *profile)
1429+{
1430+ struct aa_task_context *cxt;
1431+ struct aa_profile *old_profile = NULL;
1432+
1433+ rcu_read_lock();
1434+repeat:
1435+ cxt = aa_task_context(task);
1436+ if (cxt)
1437+ old_profile = cxt->profile;
1438+
1439+ lock_both_profiles(profile, old_profile);
1440+ task_lock(task);
1441+
1442+ /* check for race with profile transition, replacement or removal */
1443+ if (unlikely(cxt != aa_task_context(task))) {
1444+ task_unlock(task);
1445+ unlock_both_profiles(profile, old_profile);
1446+ old_profile = NULL;
1447+ goto repeat;
1448+ }
1449+ rcu_read_unlock();
1450+ return cxt;
1451+}
1452+
1453+static void free_aa_task_context_rcu_callback(struct rcu_head *head)
1454+{
1455+ struct aa_task_context *cxt;
1456+
1457+ cxt = container_of(head, struct aa_task_context, rcu);
1458+ aa_free_task_context(cxt);
1459+}
1460+
1461+/**
1462+ * aa_change_task_context - switch a task to use a new context and profile
1463+ * @task: task that is having its task context changed
1464+ * @new_cxt: new task context to use after the switch
1465+ * @profile: new profile to use after the switch
1466+ * @cookie: magic value to switch to
1467+ * @previous_profile: profile the task can return to
1468+ */
1469+void aa_change_task_context(struct task_struct *task,
1470+ struct aa_task_context *new_cxt,
1471+ struct aa_profile *profile, u64 cookie,
1472+ struct aa_profile *previous_profile)
1473+{
1474+ struct aa_task_context *old_cxt = aa_task_context(task);
1475+
1476+ if (old_cxt) {
1477+ list_del_init(&old_cxt->list);
1478+ call_rcu(&old_cxt->rcu, free_aa_task_context_rcu_callback);
1479+ }
1480+ if (new_cxt) {
1481+ /* set the caps_logged cache to the quiet_caps mask
1482+ * this has the effect of quieting caps that are not
1483+ * supposed to be logged
1484+ */
1485+ new_cxt->caps_logged = profile->quiet_caps;
1486+ new_cxt->cookie = cookie;
1487+ new_cxt->task = task;
1488+ new_cxt->profile = aa_dup_profile(profile);
1489+ new_cxt->previous_profile = aa_dup_profile(previous_profile);
1490+ list_move(&new_cxt->list, &profile->task_contexts);
1491+ }
1492+ rcu_assign_pointer(task->security, new_cxt);
1493+}