~ubuntu-branches/ubuntu/natty/apparmor/natty-updates

« back to all changes in this revision

Viewing changes to deprecated/kernel-patches/2.6.28/apparmor-main.diff

  • Committer: Bazaar Package Importer
  • Author(s): Steve Beattie, Steve Beattie, Jamie Strandboge
  • Date: 2011-02-24 01:41:58 UTC
  • mfrom: (1.1.17 upstream)
  • Revision ID: james.westby@ubuntu.com-20110224014158-jgxhztjm8ljtquxt
Tags: 2.6.0-0ubuntu1
[ Steve Beattie ]
* New upstream 2.6.0 release (LP: #724193)
  - Patches taken upstream and dropped:
    + 0001-ubuntu-buildd.patch
    + 0003-add-libvirt-support-to-dnsmasq.patch
    + 0004-lp698194.patch
    + 0005-aa-disable.patch
  - debian/rules: remove library path settings for mod_apparmor and
    pam_apprmor builds; upstream handles this properly now.
  - debian/apparmor-utils.install: handle upstream SubDomain.pm =>
    AppArmor.pm renaming
* debian/lib/apparmor/functions: handle profile names with embedded
  spaces (LP: #655523)
* debian/rules, debian/control, debian/python-libapparmor: build
  a python-libapparmor package.

[ Jamie Strandboge ]
* debian/copyright: update and reformat according to DEP-5
* debian/lib/apparmor/functions: don't unload dynamically generated libvirt
  profiles on reload, restart, and force-reload (LP: #702774)
* debian/control: use Section: python for python-libapparmor

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
From: John Johansen <jjohansen@suse.de>
2
 
Subject: AppArmor: Main Part
3
 
 
4
 
The underlying functions by which the AppArmor LSM hooks are implemented.
5
 
 
6
 
Signed-off-by: John Johansen <jjohansen@suse.de>
7
 
Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
8
 
 
9
 
---
10
 
 security/apparmor/main.c | 1479 +++++++++++++++++++++++++++++++++++++++++++++++
11
 
 1 file changed, 1479 insertions(+)
12
 
 
13
 
--- /dev/null
14
 
+++ b/security/apparmor/main.c
15
 
@@ -0,0 +1,1479 @@
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
 
+               if (!PROFILE_COMPLAIN(profile))
306
 
+                       sa->denied_mask &= (~mask) | ALL_AA_EXEC_TYPE;
307
 
+       }
308
 
+
309
 
+       return aa_audit(profile, sa);
310
 
+}
311
 
+
312
 
+static int aa_audit_caps(struct aa_profile *profile, struct aa_audit *sa,
313
 
+                        int cap)
314
 
+{
315
 
+       if (likely(!sa->error_code)) {
316
 
+               if (likely(!PROFILE_AUDIT(profile) &&
317
 
+                          !cap_raised(profile->audit_caps, cap)))
318
 
+                       return 0;
319
 
+       }
320
 
+
321
 
+       /* quieting of capabilities is handled the caps_logged cache */
322
 
+       return aa_audit(profile, sa);
323
 
+}
324
 
+
325
 
+/**
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
331
 
+ *
332
 
+ * Return %0 on success, or else the permissions in @mask that the
333
 
+ * profile denies.
334
 
+ */
335
 
+static int aa_file_denied(struct aa_profile *profile, const char *name,
336
 
+                         int mask, int *audit_mask)
337
 
+{
338
 
+       return (mask & ~aa_match(profile->file_rules, name, audit_mask));
339
 
+}
340
 
+
341
 
+/**
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.
350
 
+ */
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)
354
 
+{
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;
358
 
+
359
 
+       *request_mask = link_mask;
360
 
+
361
 
+       l_mode = aa_match_state(profile->file_rules, DFA_START, link, &state);
362
 
+
363
 
+       if (l_mode & link_mask) {
364
 
+               int mode;
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,
368
 
+                                     &state);
369
 
+
370
 
+               if (!(mode & link_mask))
371
 
+                       denied_mask |= link_mask;
372
 
+
373
 
+               *audit_mask = dfa_audit_mask(profile->file_rules, state);
374
 
+
375
 
+               /* return if link subset test is not required */
376
 
+               if (!(mode & (AA_LINK_SUBSET_TEST << target_mode)))
377
 
+                       return denied_mask;
378
 
+       }
379
 
+
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.
385
 
+        *
386
 
+        * If the link has 'x', an exact match of all the execute flags
387
 
+        * must match.
388
 
+        */
389
 
+       denied_mask |= ~l_mode & link_mask;
390
 
+
391
 
+       t_mode = aa_match(profile->file_rules, target, NULL);
392
 
+
393
 
+       l_x = l_mode & (ALL_AA_EXEC_TYPE | AA_EXEC_BITS);
394
 
+       t_x = t_mode & (ALL_AA_EXEC_TYPE | AA_EXEC_BITS);
395
 
+
396
 
+       /* For actual subset test ignore valid-profile-transition flags,
397
 
+        * and link bits
398
 
+        */
399
 
+       l_mode &= AA_FILE_PERMS & ~AA_LINK_BITS;
400
 
+       t_mode &= AA_FILE_PERMS & ~AA_LINK_BITS;
401
 
+
402
 
+       *request_mask = l_mode | link_mask;
403
 
+
404
 
+       if (l_mode) {
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 */
408
 
+
409
 
+               /* handle exec subset
410
 
+                * - link safe exec issubset of unsafe exec
411
 
+                * - no link x perm is subset of target having x perm
412
 
+                */
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);
419
 
+       }
420
 
+
421
 
+       return denied_mask;
422
 
+}
423
 
+
424
 
+/**
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
430
 
+ *
431
 
+ * Returns a pointer to the beginning of the pathname (which usually differs
432
 
+ * from the beginning of the buffer), or an error code.
433
 
+ *
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.
436
 
+ */
437
 
+static char *aa_get_name(struct dentry *dentry, struct vfsmount *mnt,
438
 
+                        char **buffer, int check)
439
 
+{
440
 
+       char *name;
441
 
+       int is_dir, size = 256;
442
 
+
443
 
+       is_dir = (check & AA_CHECK_DIR) ? 1 : 0;
444
 
+
445
 
+       for (;;) {
446
 
+               char *buf = kmalloc(size, GFP_KERNEL);
447
 
+               if (!buf)
448
 
+                       return ERR_PTR(-ENOMEM);
449
 
+
450
 
+               name = d_namespace_path(dentry, mnt, buf, size - is_dir);
451
 
+               if (!IS_ERR(name)) {
452
 
+                       if (name[0] != '/') {
453
 
+                               /*
454
 
+                                * This dentry is not connected to the
455
 
+                                * namespace root -- reject access.
456
 
+                                */
457
 
+                               kfree(buf);
458
 
+                               return ERR_PTR(-ENOENT);
459
 
+                       }
460
 
+                       if (is_dir && name[1] != '\0') {
461
 
+                               /*
462
 
+                                * Append "/" to the pathname. The root
463
 
+                                * directory is a special case; it already
464
 
+                                * ends in slash.
465
 
+                                */
466
 
+                               buf[size - 2] = '/';
467
 
+                               buf[size - 1] = '\0';
468
 
+                       }
469
 
+
470
 
+                       *buffer = buf;
471
 
+                       return name;
472
 
+               }
473
 
+               if (PTR_ERR(name) != -ENAMETOOLONG)
474
 
+                       return name;
475
 
+
476
 
+               kfree(buf);
477
 
+               size <<= 1;
478
 
+               if (size > apparmor_path_max)
479
 
+                       return ERR_PTR(-ENAMETOOLONG);
480
 
+       }
481
 
+}
482
 
+
483
 
+static char *new_compound_name(const char *n1, const char *n2)
484
 
+{
485
 
+       char *name = kmalloc(strlen(n1) + strlen(n2) + 3, GFP_KERNEL);
486
 
+       if (name)
487
 
+               sprintf(name, "%s//%s", n1, n2);
488
 
+       return name;
489
 
+}
490
 
+static inline void aa_put_name_buffer(char *buffer)
491
 
+{
492
 
+       kfree(buffer);
493
 
+}
494
 
+
495
 
+/**
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
503
 
+ *
504
 
+ * Returns 0 upon success, or else an error code.
505
 
+ *
506
 
+ * @check indicates the file type, and whether the file was accessed through
507
 
+ * an open file descriptor (AA_CHECK_FD) or not.
508
 
+ */
509
 
+static int aa_perm_dentry(struct aa_profile *profile, struct dentry *dentry,
510
 
+                         struct vfsmount *mnt, struct aa_audit *sa, int check)
511
 
+{
512
 
+       int error;
513
 
+       char *buffer = NULL;
514
 
+
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)) {
518
 
+               /*
519
 
+                * deleted files are given a pass on permission checks when
520
 
+                * accessed through a file descriptor.
521
 
+                */
522
 
+               if (PTR_ERR(sa->name) == -ENOENT && (check & AA_CHECK_FD))
523
 
+                       sa->denied_mask = 0;
524
 
+               else {
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";
531
 
+                       else
532
 
+                               sa->info = "Failed name resolution";
533
 
+               }
534
 
+               sa->name = NULL;
535
 
+       } else
536
 
+               sa->denied_mask = aa_file_denied(profile, sa->name,
537
 
+                                                sa->request_mask,
538
 
+                                                &sa->audit_mask);
539
 
+
540
 
+       if (!sa->denied_mask)
541
 
+               sa->error_code = 0;
542
 
+
543
 
+       error = aa_audit_file(profile, sa);
544
 
+       aa_put_name_buffer(buffer);
545
 
+
546
 
+       return error;
547
 
+}
548
 
+
549
 
+/**
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
555
 
+ */
556
 
+int aa_attr(struct aa_profile *profile, struct dentry *dentry,
557
 
+           struct vfsmount *mnt, struct iattr *iattr)
558
 
+{
559
 
+       struct inode *inode = dentry->d_inode;
560
 
+       int error, check;
561
 
+       struct aa_audit sa;
562
 
+
563
 
+       memset(&sa, 0, sizeof(sa));
564
 
+       sa.operation = "setattr";
565
 
+       sa.gfp_mask = GFP_KERNEL;
566
 
+       sa.iattr = iattr;
567
 
+       sa.request_mask = MAY_WRITE;
568
 
+       sa.error_code = -EACCES;
569
 
+
570
 
+       check = 0;
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;
575
 
+
576
 
+       error = aa_perm_dentry(profile, dentry, mnt, &sa, check);
577
 
+
578
 
+       return error;
579
 
+}
580
 
+
581
 
+/**
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
589
 
+ */
590
 
+int aa_perm_xattr(struct aa_profile *profile, const char *operation,
591
 
+                 struct dentry *dentry, struct vfsmount *mnt, int mask,
592
 
+                 int check)
593
 
+{
594
 
+       struct inode *inode = dentry->d_inode;
595
 
+       int error;
596
 
+       struct aa_audit sa;
597
 
+
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;
603
 
+
604
 
+       if (inode && S_ISDIR(inode->i_mode))
605
 
+               check |= AA_CHECK_DIR;
606
 
+
607
 
+       error = aa_perm_dentry(profile, dentry, mnt, &sa, check);
608
 
+
609
 
+       return error;
610
 
+}
611
 
+
612
 
+/**
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
619
 
+ *
620
 
+ * Determine if access @mask for the file is authorized by @profile.
621
 
+ * Returns 0 on success, or else an error code.
622
 
+ */
623
 
+int aa_perm(struct aa_profile *profile, const char *operation,
624
 
+           struct dentry *dentry, struct vfsmount *mnt, int mask, int check)
625
 
+{
626
 
+       struct aa_audit sa;
627
 
+       int error = 0;
628
 
+
629
 
+       if (mask == 0)
630
 
+               goto out;
631
 
+
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;
637
 
+
638
 
+       error = aa_perm_dentry(profile, dentry, mnt, &sa, check);
639
 
+
640
 
+out:
641
 
+       return error;
642
 
+}
643
 
+
644
 
+/**
645
 
+ * aa_perm_dir
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
651
 
+ *
652
 
+ * Determine if directory operation (make/remove) for dentry is authorized
653
 
+ * by @profile.
654
 
+ * Returns 0 on success, or else an error code.
655
 
+ */
656
 
+int aa_perm_dir(struct aa_profile *profile, const char *operation,
657
 
+               struct dentry *dentry, struct vfsmount *mnt, int mask)
658
 
+{
659
 
+       struct aa_audit sa;
660
 
+
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;
666
 
+
667
 
+       return aa_perm_dentry(profile, dentry, mnt, &sa, AA_CHECK_DIR);
668
 
+}
669
 
+
670
 
+int aa_perm_path(struct aa_profile *profile, const char *operation,
671
 
+                const char *name, int mask, uid_t uid)
672
 
+{
673
 
+       struct aa_audit sa;
674
 
+
675
 
+       memset(&sa, 0, sizeof(sa));
676
 
+       sa.operation = operation;
677
 
+       sa.gfp_mask = GFP_KERNEL;
678
 
+       sa.request_mask = mask;
679
 
+       sa.name = name;
680
 
+       if (current->fsuid == uid)
681
 
+               sa.request_mask = mask << AA_USER_SHIFT;
682
 
+       else
683
 
+               sa.request_mask = mask << AA_OTHER_SHIFT;
684
 
+
685
 
+       sa.denied_mask = aa_file_denied(profile, name, sa.request_mask,
686
 
+                                       &sa.audit_mask) ;
687
 
+       sa.error_code = sa.denied_mask ? -EACCES : 0;
688
 
+
689
 
+       return aa_audit_file(profile, &sa);
690
 
+}
691
 
+
692
 
+/**
693
 
+ * aa_capability - test permission to use capability
694
 
+ * @cxt: aa_task_context with profile to check against
695
 
+ * @cap: capability to be tested
696
 
+ *
697
 
+ * Look up capability in profile capability set.
698
 
+ * Returns 0 on success, or else an error code.
699
 
+ */
700
 
+int aa_capability(struct aa_task_context *cxt, int cap)
701
 
+{
702
 
+       int error = cap_raised(cxt->profile->capabilities, cap) ? 0 : -EPERM;
703
 
+       struct aa_audit sa;
704
 
+
705
 
+       /* test if cap has alread been logged */
706
 
+       if (cap_raised(cxt->caps_logged, cap)) {
707
 
+               if (PROFILE_COMPLAIN(cxt->profile))
708
 
+                       error = 0;
709
 
+               return error;
710
 
+       } else
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
715
 
+                * the audit log
716
 
+                */
717
 
+               cap_raise(cxt->caps_logged, cap);
718
 
+
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;
724
 
+
725
 
+       error = aa_audit_caps(cxt->profile, &sa, cap);
726
 
+
727
 
+       return error;
728
 
+}
729
 
+
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)
732
 
+{
733
 
+       if (!cxt || cxt->profile == tracee)
734
 
+               return 0;
735
 
+       return aa_capability(cxt, CAP_SYS_PTRACE);
736
 
+}
737
 
+
738
 
+/**
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
745
 
+ *
746
 
+ * Returns 0 on success, or else an error code.
747
 
+ */
748
 
+int aa_link(struct aa_profile *profile,
749
 
+           struct dentry *link, struct vfsmount *link_mnt,
750
 
+           struct dentry *target, struct vfsmount *target_mnt)
751
 
+{
752
 
+       int error;
753
 
+       struct aa_audit sa;
754
 
+       char *buffer = NULL, *buffer2 = NULL;
755
 
+
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);
761
 
+
762
 
+       if (IS_ERR(sa.name)) {
763
 
+               sa.error_code = PTR_ERR(sa.name);
764
 
+               sa.name = NULL;
765
 
+       }
766
 
+       if (IS_ERR(sa.name2)) {
767
 
+               sa.error_code = PTR_ERR(sa.name2);
768
 
+               sa.name2 = NULL;
769
 
+       }
770
 
+
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),
774
 
+                                               &sa.request_mask,
775
 
+                                               &sa.audit_mask);
776
 
+               sa.error_code = sa.denied_mask ? -EACCES : 0;
777
 
+       }
778
 
+
779
 
+       error = aa_audit_file(profile, &sa);
780
 
+
781
 
+       aa_put_name_buffer(buffer);
782
 
+       aa_put_name_buffer(buffer2);
783
 
+
784
 
+       return error;
785
 
+}
786
 
+
787
 
+/*******************************
788
 
+ * Global task related functions
789
 
+ *******************************/
790
 
+
791
 
+/**
792
 
+ * aa_clone - initialize the task context for a new task
793
 
+ * @child: task that is being created
794
 
+ *
795
 
+ * Returns 0 on success, or else an error code.
796
 
+ */
797
 
+int aa_clone(struct task_struct *child)
798
 
+{
799
 
+       struct aa_task_context *cxt, *child_cxt;
800
 
+       struct aa_profile *profile;
801
 
+
802
 
+       if (!aa_task_context(current))
803
 
+               return 0;
804
 
+       child_cxt = aa_alloc_task_context(GFP_KERNEL);
805
 
+       if (!child_cxt)
806
 
+               return -ENOMEM;
807
 
+
808
 
+repeat:
809
 
+       profile = aa_get_profile(current);
810
 
+       if (profile) {
811
 
+               lock_profile(profile);
812
 
+               cxt = aa_task_context(current);
813
 
+               if (unlikely(profile->isstale || !cxt ||
814
 
+                            cxt->profile != profile)) {
815
 
+                       /**
816
 
+                        * Race with profile replacement or removal, or with
817
 
+                        * task context removal.
818
 
+                        */
819
 
+                       unlock_profile(profile);
820
 
+                       aa_put_profile(profile);
821
 
+                       goto repeat;
822
 
+               }
823
 
+
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);
828
 
+
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);
837
 
+               }
838
 
+               aa_put_profile(profile);
839
 
+       } else
840
 
+               aa_free_task_context(child_cxt);
841
 
+
842
 
+       return 0;
843
 
+}
844
 
+
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)
849
 
+{
850
 
+       struct aa_namespace *ns;
851
 
+       struct aa_profile *new_profile;
852
 
+       int ns_ref = 0;
853
 
+
854
 
+       if (profile)
855
 
+               ns = profile->ns;
856
 
+       else
857
 
+               ns = default_namespace;
858
 
+
859
 
+       if (ns_name) {
860
 
+               /* locate the profile namespace */
861
 
+               ns = aa_find_namespace(ns_name);
862
 
+               if (!ns) {
863
 
+                       if (mandatory) {
864
 
+                               sa->info = "profile namespace not found";
865
 
+                               sa->denied_mask = sa->request_mask;
866
 
+                               sa->error_code = -ENOENT;
867
 
+                               return ERR_PTR(-ENOENT);
868
 
+                       } else {
869
 
+                               return NULL;
870
 
+                       }
871
 
+               }
872
 
+               ns_ref++;
873
 
+       }
874
 
+
875
 
+       /* Locate new profile */
876
 
+       new_profile = aa_find_profile(ns, name);
877
 
+
878
 
+       if (new_profile) {
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 */
884
 
+               if (complain) {
885
 
+                       aa_audit_hint(profile, sa);
886
 
+                       new_profile =
887
 
+                           aa_dup_profile(profile->ns->null_complain_profile);
888
 
+               } else {
889
 
+                       sa->error_code = -EACCES;
890
 
+                       if (ns_ref)
891
 
+                               aa_put_namespace(ns);
892
 
+                       return ERR_PTR(-EACCES);
893
 
+               }
894
 
+       } else {
895
 
+               /* Only way we can get into this code is if task
896
 
+                * is unconfined, pix, nix.
897
 
+                */
898
 
+               AA_DEBUG("%s: No profile found for exec image '%s'\n",
899
 
+                        __FUNCTION__,
900
 
+                        name);
901
 
+       }
902
 
+       if (ns_ref)
903
 
+               aa_put_namespace(ns);
904
 
+       return new_profile;
905
 
+}
906
 
+
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)
910
 
+{
911
 
+       struct aa_profile *new_profile = NULL;
912
 
+       int ix = xmode & AA_EXEC_INHERIT;
913
 
+       int complain = PROFILE_COMPLAIN(profile);
914
 
+       int index;
915
 
+
916
 
+       *child = NULL;
917
 
+       switch (xmode & AA_EXEC_MODIFIERS) {
918
 
+       case 0:
919
 
+               /* only valid with ix flag */
920
 
+               ix = 1;
921
 
+               break;
922
 
+       case AA_EXEC_UNCONFINED:
923
 
+               /* only valid without ix flag */
924
 
+               ix = 0;
925
 
+               break;
926
 
+       case AA_EXEC_PROFILE:
927
 
+               new_profile = aa_register_find(profile, NULL, filename, !ix,
928
 
+                                              complain, sa);
929
 
+               break;
930
 
+       case AA_EXEC_CHILD:
931
 
+               *child = new_compound_name(profile->name, filename);
932
 
+               sa->name2 = *child;
933
 
+               if (!*child) {
934
 
+                       sa->info = "Failed name resolution - exec failed";
935
 
+                       sa->error_code = -ENOMEM;
936
 
+                       new_profile = ERR_PTR(-ENOMEM);
937
 
+               } else {
938
 
+                       new_profile = aa_register_find(profile, NULL, *child,
939
 
+                                                      !ix, complain, sa);
940
 
+               }
941
 
+               break;
942
 
+       default:
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);
949
 
+               } else {
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;
955
 
+                       }
956
 
+                       sa->name2 = name;
957
 
+                       sa->name3 = ns_name;
958
 
+                       new_profile =
959
 
+                               aa_register_find(profile, ns_name, name,
960
 
+                                                !ix, complain, sa);
961
 
+               }
962
 
+       }
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;
967
 
+}
968
 
+
969
 
+/**
970
 
+ * aa_register - register a new program
971
 
+ * @bprm: binprm of program being registered
972
 
+ *
973
 
+ * Try to register a new program during execve().  This should give the
974
 
+ * new program a valid aa_task_context if confined.
975
 
+ */
976
 
+int aa_register(struct linux_binprm *bprm)
977
 
+{
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;
984
 
+
985
 
+       AA_DEBUG("%s\n", __FUNCTION__);
986
 
+
987
 
+       profile = aa_get_profile(current);
988
 
+
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;
994
 
+
995
 
+       filename = aa_get_name(filp->f_dentry, filp->f_vfsmnt, &buffer, 0);
996
 
+       if (IS_ERR(filename)) {
997
 
+               if (profile) {
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;
1002
 
+               } else
1003
 
+                       return 0;
1004
 
+       }
1005
 
+       sa.name = filename;
1006
 
+
1007
 
+       exec_mode = AA_EXEC_UNSAFE << shift;
1008
 
+
1009
 
+repeat:
1010
 
+       if (profile) {
1011
 
+               complain = PROFILE_COMPLAIN(profile);
1012
 
+
1013
 
+               /* Confined task, determine what mode inherit, unconfined or
1014
 
+                * mandatory to load new profile
1015
 
+                */
1016
 
+               exec_mode = aa_match(profile->file_rules, filename,
1017
 
+                                    &sa.audit_mask);
1018
 
+
1019
 
+
1020
 
+               if (exec_mode & sa.request_mask) {
1021
 
+                       int xm = exec_mode >> shift;
1022
 
+                       new_profile = aa_x_to_profile(profile, filename,
1023
 
+                                                     xm, &sa, &child);
1024
 
+
1025
 
+                       if (!new_profile && (xm & AA_EXEC_INHERIT))
1026
 
+                               /* (p|c|n|)ix - don't change profile */
1027
 
+                               goto cleanup;
1028
 
+                       /* error case caught below */
1029
 
+
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).
1037
 
+                        */
1038
 
+                       new_profile =
1039
 
+                           aa_dup_profile(profile->ns->null_complain_profile);
1040
 
+                       exec_mode |= AA_EXEC_UNSAFE << shift;
1041
 
+               } else {
1042
 
+                       sa.denied_mask = sa.request_mask;
1043
 
+                       sa.error_code = -EACCES;
1044
 
+                       new_profile = ERR_PTR(aa_audit_file(profile, &sa));
1045
 
+               }
1046
 
+       } else {
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)
1050
 
+                       goto cleanup;
1051
 
+       }
1052
 
+
1053
 
+       if (IS_ERR(new_profile))
1054
 
+               goto cleanup;
1055
 
+
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);
1062
 
+                       goto repeat;
1063
 
+               }
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);
1069
 
+               }
1070
 
+               new_profile = old_profile;
1071
 
+               goto cleanup;
1072
 
+       }
1073
 
+       aa_put_profile(old_profile);
1074
 
+       aa_put_profile(profile);
1075
 
+
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
1081
 
+        *
1082
 
+        * Cases 2 and 3 are marked as requiring secure exec
1083
 
+        * (unless policy specified "unsafe exec")
1084
 
+        */
1085
 
+       if (!(exec_mode & (AA_EXEC_UNSAFE << shift))) {
1086
 
+               unsigned long bprm_flags;
1087
 
+
1088
 
+               bprm_flags = AA_SECURE_EXEC_NEEDED;
1089
 
+               bprm->security = (void*)
1090
 
+                       ((unsigned long)bprm->security | bprm_flags);
1091
 
+       }
1092
 
+
1093
 
+       if (complain && new_profile &&
1094
 
+           new_profile == new_profile->ns->null_complain_profile) {
1095
 
+               sa.request_mask = 0;
1096
 
+               sa.name = NULL;
1097
 
+               sa.info = "set profile";
1098
 
+               aa_audit_hint(new_profile, &sa);
1099
 
+       }
1100
 
+
1101
 
+cleanup:
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);
1107
 
+       return 0;
1108
 
+}
1109
 
+
1110
 
+/**
1111
 
+ * aa_release - release a task context
1112
 
+ * @task: task being released
1113
 
+ *
1114
 
+ * This is called after a task has exited and the parent has reaped it.
1115
 
+ */
1116
 
+void aa_release(struct task_struct *task)
1117
 
+{
1118
 
+       struct aa_task_context *cxt;
1119
 
+       struct aa_profile *profile;
1120
 
+       /*
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
1127
 
+        * the task.
1128
 
+        *
1129
 
+        * Use lock subtyping to avoid lockdep reporting a false irq
1130
 
+        * possible inversion between the task_lock and profile_lock
1131
 
+        *
1132
 
+        * We also avoid taking the task_lock here because lock_dep
1133
 
+        * would report another false {softirq-on-W} potential irq_lock
1134
 
+        * inversion.
1135
 
+        *
1136
 
+        * If the task does not have a profile attached we are safe;
1137
 
+        * nothing can race with us at this point.
1138
 
+        */
1139
 
+
1140
 
+repeat:
1141
 
+       profile = aa_get_profile(task);
1142
 
+       if (profile) {
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);
1148
 
+                       goto repeat;
1149
 
+               }
1150
 
+               aa_change_task_context(task, NULL, NULL, 0, NULL);
1151
 
+               unlock_profile(profile);
1152
 
+               aa_put_profile(profile);
1153
 
+       }
1154
 
+}
1155
 
+
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)
1160
 
+{
1161
 
+       struct aa_profile *new_profile = NULL, *old_profile = NULL,
1162
 
+               *previous_profile = NULL;
1163
 
+       struct aa_task_context *new_cxt, *cxt;
1164
 
+       int error = 0;
1165
 
+
1166
 
+       sa->name = name;
1167
 
+
1168
 
+       new_cxt = aa_alloc_task_context(GFP_KERNEL);
1169
 
+       if (!new_cxt)
1170
 
+               return -ENOMEM;
1171
 
+
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);
1176
 
+                       return -ENOENT;
1177
 
+               }
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);
1182
 
+               return error;
1183
 
+       }
1184
 
+
1185
 
+       cxt = lock_task_and_profiles(current, new_profile);
1186
 
+       if (!cxt) {
1187
 
+               error = -EPERM;
1188
 
+               goto out;
1189
 
+       }
1190
 
+       old_profile = cxt->profile;
1191
 
+
1192
 
+       if (cxt->profile != expected || (new_profile && new_profile->isstale)) {
1193
 
+               error = -ESTALE;
1194
 
+               goto out;
1195
 
+       }
1196
 
+
1197
 
+       if (cxt->previous_profile) {
1198
 
+               if (cxt->cookie != cookie) {
1199
 
+                       error = -EACCES;
1200
 
+                       sa->info = "killing process";
1201
 
+                       aa_audit_reject(cxt->profile, sa);
1202
 
+                       /* terminate process */
1203
 
+                       (void)send_sig_info(SIGKILL, NULL, current);
1204
 
+                       goto out;
1205
 
+               }
1206
 
+
1207
 
+               if (!restore)
1208
 
+                       previous_profile = cxt->previous_profile;
1209
 
+       } else
1210
 
+               previous_profile = cxt->profile;
1211
 
+
1212
 
+       if ((current->ptrace & PT_PTRACED) && aa_may_ptrace(cxt, new_profile)) {
1213
 
+               error = -EACCES;
1214
 
+               goto out;
1215
 
+       }
1216
 
+
1217
 
+       if (new_profile == ns->null_complain_profile)
1218
 
+               aa_audit_hint(cxt->profile, sa);
1219
 
+
1220
 
+       if (APPARMOR_AUDIT(cxt))
1221
 
+               aa_audit_message(cxt->profile, sa, AUDIT_APPARMOR_AUDIT);
1222
 
+
1223
 
+       if (!restore && cookie)
1224
 
+               aa_change_task_context(current, new_cxt, new_profile, cookie,
1225
 
+                                      previous_profile);
1226
 
+       else
1227
 
+               /* either return to previous_profile, or a permanent change */
1228
 
+               aa_change_task_context(current, new_cxt, new_profile, 0, NULL);
1229
 
+
1230
 
+out:
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);
1236
 
+       return error;
1237
 
+}
1238
 
+
1239
 
+/**
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
1244
 
+ * to change back.
1245
 
+ *
1246
 
+ * Returns %0 on success, error otherwise.
1247
 
+ */
1248
 
+int aa_change_profile(const char *ns_name, const char *name)
1249
 
+{
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;
1256
 
+
1257
 
+       if (!name)
1258
 
+               return -EINVAL;
1259
 
+
1260
 
+       memset(&sa, 0, sizeof(sa));
1261
 
+       sa.gfp_mask = GFP_ATOMIC;
1262
 
+       sa.operation = "change_profile";
1263
 
+
1264
 
+repeat:
1265
 
+       task_lock(current);
1266
 
+       cxt = aa_task_context(current);
1267
 
+       if (cxt)
1268
 
+               profile = aa_dup_profile(cxt->profile);
1269
 
+       task_unlock(current);
1270
 
+
1271
 
+       if (ns_name)
1272
 
+               ns = aa_find_namespace(ns_name);
1273
 
+       else if (profile)
1274
 
+               ns = aa_get_namespace(profile->ns);
1275
 
+       else
1276
 
+               ns = aa_get_namespace(default_namespace);
1277
 
+
1278
 
+       if (!ns) {
1279
 
+               aa_put_profile(profile);
1280
 
+               return -ENOENT;
1281
 
+       }
1282
 
+
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);
1287
 
+       else {
1288
 
+               /* check for a rule with a namespace prepended */
1289
 
+               aa_match_state(profile->file_rules, DFA_START, ns->name,
1290
 
+                              &state);
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,
1295
 
+                                                 &sa);
1296
 
+               else
1297
 
+                       /* no permission to transition to profile @name */
1298
 
+                       error = -EACCES;
1299
 
+       }
1300
 
+
1301
 
+       aa_put_namespace(ns);
1302
 
+       aa_put_profile(profile);
1303
 
+       if (error == -ESTALE)
1304
 
+               goto repeat;
1305
 
+
1306
 
+       return error;
1307
 
+}
1308
 
+
1309
 
+/**
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
1313
 
+ *
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
1317
 
+ * profile.
1318
 
+ * Returns %0 on success, error otherwise.
1319
 
+ */
1320
 
+int aa_change_hat(const char *hat_name, u64 cookie)
1321
 
+{
1322
 
+       struct aa_task_context *cxt;
1323
 
+       struct aa_profile *profile, *previous_profile;
1324
 
+       struct aa_audit sa;
1325
 
+       int error = 0;
1326
 
+
1327
 
+       memset(&sa, 0, sizeof(sa));
1328
 
+       sa.gfp_mask = GFP_ATOMIC;
1329
 
+       sa.operation = "change_hat";
1330
 
+
1331
 
+repeat:
1332
 
+       task_lock(current);
1333
 
+       cxt = aa_task_context(current);
1334
 
+       if (!cxt) {
1335
 
+               task_unlock(current);
1336
 
+               return -EPERM;
1337
 
+       }
1338
 
+       profile = aa_dup_profile(cxt->profile);
1339
 
+       previous_profile = aa_dup_profile(cxt->previous_profile);
1340
 
+       task_unlock(current);
1341
 
+
1342
 
+       if (hat_name) {
1343
 
+               char *name, *profile_name;
1344
 
+
1345
 
+               if (previous_profile)
1346
 
+                       profile_name = previous_profile->name;
1347
 
+               else
1348
 
+                       profile_name = profile->name;
1349
 
+
1350
 
+               name = new_compound_name(profile_name, hat_name);
1351
 
+               if (!name) {
1352
 
+                       error = -ENOMEM;
1353
 
+                       goto out;
1354
 
+               }
1355
 
+               error = do_change_profile(profile, profile->ns, name, cookie,
1356
 
+                                         0, 1, &sa);
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,
1361
 
+                                         &sa);
1362
 
+       /* else ignore restores when there is no saved profile */
1363
 
+
1364
 
+out:
1365
 
+       aa_put_profile(previous_profile);
1366
 
+       aa_put_profile(profile);
1367
 
+       if (error == -ESTALE)
1368
 
+               goto repeat;
1369
 
+
1370
 
+       return error;
1371
 
+}
1372
 
+
1373
 
+/**
1374
 
+ * __aa_replace_profile - replace a task's profile
1375
 
+ * @task: task to switch the profile of
1376
 
+ * @profile: profile to switch to
1377
 
+ *
1378
 
+ * Returns a handle to the previous profile upon success, or else an
1379
 
+ * error code.
1380
 
+ */
1381
 
+struct aa_profile *__aa_replace_profile(struct task_struct *task,
1382
 
+                                       struct aa_profile *profile)
1383
 
+{
1384
 
+       struct aa_task_context *cxt, *new_cxt = NULL;
1385
 
+       struct aa_profile *old_profile = NULL;
1386
 
+
1387
 
+       if (profile) {
1388
 
+               new_cxt = aa_alloc_task_context(GFP_KERNEL);
1389
 
+               if (!new_cxt)
1390
 
+                       return ERR_PTR(-ENOMEM);
1391
 
+       }
1392
 
+
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);
1399
 
+       }
1400
 
+
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);
1406
 
+       }
1407
 
+
1408
 
+       if (cxt)
1409
 
+               old_profile = aa_dup_profile(cxt->profile);
1410
 
+       aa_change_task_context(task, new_cxt, profile, 0, NULL);
1411
 
+
1412
 
+       task_unlock(task);
1413
 
+       unlock_both_profiles(profile, old_profile);
1414
 
+       return old_profile;
1415
 
+}
1416
 
+
1417
 
+/**
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
1421
 
+ *
1422
 
+ * Handle the spinning on locking to make sure the task context and
1423
 
+ * profile are consistent once all locks are aquired.
1424
 
+ *
1425
 
+ * return the aa_task_context currently confining the task.  The task lock
1426
 
+ * will be held whether or not the task is confined.
1427
 
+ */
1428
 
+struct aa_task_context *
1429
 
+lock_task_and_profiles(struct task_struct *task, struct aa_profile *profile)
1430
 
+{
1431
 
+       struct aa_task_context *cxt;
1432
 
+       struct aa_profile *old_profile = NULL;
1433
 
+
1434
 
+       rcu_read_lock();
1435
 
+repeat:
1436
 
+       cxt = aa_task_context(task);
1437
 
+       if (cxt)
1438
 
+               old_profile = cxt->profile;
1439
 
+
1440
 
+       lock_both_profiles(profile, old_profile);
1441
 
+       task_lock(task);
1442
 
+
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;
1448
 
+               goto repeat;
1449
 
+       }
1450
 
+       rcu_read_unlock();
1451
 
+       return cxt;
1452
 
+}
1453
 
+
1454
 
+static void free_aa_task_context_rcu_callback(struct rcu_head *head)
1455
 
+{
1456
 
+       struct aa_task_context *cxt;
1457
 
+
1458
 
+       cxt = container_of(head, struct aa_task_context, rcu);
1459
 
+       aa_free_task_context(cxt);
1460
 
+}
1461
 
+
1462
 
+/**
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
1469
 
+ */
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)
1474
 
+{
1475
 
+       struct aa_task_context *old_cxt = aa_task_context(task);
1476
 
+
1477
 
+       if (old_cxt) {
1478
 
+               list_del_init(&old_cxt->list);
1479
 
+               call_rcu(&old_cxt->rcu, free_aa_task_context_rcu_callback);
1480
 
+       }
1481
 
+       if (new_cxt) {
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
1485
 
+                */
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);
1492
 
+       }
1493
 
+       rcu_assign_pointer(task->security, new_cxt);
1494
 
+}