aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--security/apparmor/apparmorfs.c22
-rw-r--r--security/apparmor/domain.c68
-rw-r--r--security/apparmor/file.c8
-rw-r--r--security/apparmor/label.c2
-rw-r--r--security/apparmor/lib.c16
-rw-r--r--security/apparmor/lsm.c8
-rw-r--r--security/apparmor/mount.c13
-rw-r--r--security/apparmor/policy.c11
-rw-r--r--security/apparmor/policy_ns.c8
-rw-r--r--security/apparmor/policy_unpack.c2
-rw-r--r--security/apparmor/resource.c4
11 files changed, 91 insertions, 71 deletions
diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
index caaf51dda648..8542e9a55e1b 100644
--- a/security/apparmor/apparmorfs.c
+++ b/security/apparmor/apparmorfs.c
@@ -533,7 +533,7 @@ static ssize_t ns_revision_read(struct file *file, char __user *buf,
533 long last_read; 533 long last_read;
534 int avail; 534 int avail;
535 535
536 mutex_lock(&rev->ns->lock); 536 mutex_lock_nested(&rev->ns->lock, rev->ns->level);
537 last_read = rev->last_read; 537 last_read = rev->last_read;
538 if (last_read == rev->ns->revision) { 538 if (last_read == rev->ns->revision) {
539 mutex_unlock(&rev->ns->lock); 539 mutex_unlock(&rev->ns->lock);
@@ -543,7 +543,7 @@ static ssize_t ns_revision_read(struct file *file, char __user *buf,
543 last_read != 543 last_read !=
544 READ_ONCE(rev->ns->revision))) 544 READ_ONCE(rev->ns->revision)))
545 return -ERESTARTSYS; 545 return -ERESTARTSYS;
546 mutex_lock(&rev->ns->lock); 546 mutex_lock_nested(&rev->ns->lock, rev->ns->level);
547 } 547 }
548 548
549 avail = sprintf(buffer, "%ld\n", rev->ns->revision); 549 avail = sprintf(buffer, "%ld\n", rev->ns->revision);
@@ -577,7 +577,7 @@ static unsigned int ns_revision_poll(struct file *file, poll_table *pt)
577 unsigned int mask = 0; 577 unsigned int mask = 0;
578 578
579 if (rev) { 579 if (rev) {
580 mutex_lock(&rev->ns->lock); 580 mutex_lock_nested(&rev->ns->lock, rev->ns->level);
581 poll_wait(file, &rev->ns->wait, pt); 581 poll_wait(file, &rev->ns->wait, pt);
582 if (rev->last_read < rev->ns->revision) 582 if (rev->last_read < rev->ns->revision)
583 mask |= POLLIN | POLLRDNORM; 583 mask |= POLLIN | POLLRDNORM;
@@ -1643,7 +1643,7 @@ static int ns_mkdir_op(struct inode *dir, struct dentry *dentry, umode_t mode)
1643 */ 1643 */
1644 inode_unlock(dir); 1644 inode_unlock(dir);
1645 error = simple_pin_fs(&aafs_ops, &aafs_mnt, &aafs_count); 1645 error = simple_pin_fs(&aafs_ops, &aafs_mnt, &aafs_count);
1646 mutex_lock(&parent->lock); 1646 mutex_lock_nested(&parent->lock, parent->level);
1647 inode_lock_nested(dir, I_MUTEX_PARENT); 1647 inode_lock_nested(dir, I_MUTEX_PARENT);
1648 if (error) 1648 if (error)
1649 goto out; 1649 goto out;
@@ -1692,7 +1692,7 @@ static int ns_rmdir_op(struct inode *dir, struct dentry *dentry)
1692 inode_unlock(dir); 1692 inode_unlock(dir);
1693 inode_unlock(dentry->d_inode); 1693 inode_unlock(dentry->d_inode);
1694 1694
1695 mutex_lock(&parent->lock); 1695 mutex_lock_nested(&parent->lock, parent->level);
1696 ns = aa_get_ns(__aa_findn_ns(&parent->sub_ns, dentry->d_name.name, 1696 ns = aa_get_ns(__aa_findn_ns(&parent->sub_ns, dentry->d_name.name,
1697 dentry->d_name.len)); 1697 dentry->d_name.len));
1698 if (!ns) { 1698 if (!ns) {
@@ -1747,7 +1747,7 @@ void __aafs_ns_rmdir(struct aa_ns *ns)
1747 __aafs_profile_rmdir(child); 1747 __aafs_profile_rmdir(child);
1748 1748
1749 list_for_each_entry(sub, &ns->sub_ns, base.list) { 1749 list_for_each_entry(sub, &ns->sub_ns, base.list) {
1750 mutex_lock(&sub->lock); 1750 mutex_lock_nested(&sub->lock, sub->level);
1751 __aafs_ns_rmdir(sub); 1751 __aafs_ns_rmdir(sub);
1752 mutex_unlock(&sub->lock); 1752 mutex_unlock(&sub->lock);
1753 } 1753 }
@@ -1877,7 +1877,7 @@ int __aafs_ns_mkdir(struct aa_ns *ns, struct dentry *parent, const char *name,
1877 1877
1878 /* subnamespaces */ 1878 /* subnamespaces */
1879 list_for_each_entry(sub, &ns->sub_ns, base.list) { 1879 list_for_each_entry(sub, &ns->sub_ns, base.list) {
1880 mutex_lock(&sub->lock); 1880 mutex_lock_nested(&sub->lock, sub->level);
1881 error = __aafs_ns_mkdir(sub, ns_subns_dir(ns), NULL, NULL); 1881 error = __aafs_ns_mkdir(sub, ns_subns_dir(ns), NULL, NULL);
1882 mutex_unlock(&sub->lock); 1882 mutex_unlock(&sub->lock);
1883 if (error) 1883 if (error)
@@ -1921,7 +1921,7 @@ static struct aa_ns *__next_ns(struct aa_ns *root, struct aa_ns *ns)
1921 /* is next namespace a child */ 1921 /* is next namespace a child */
1922 if (!list_empty(&ns->sub_ns)) { 1922 if (!list_empty(&ns->sub_ns)) {
1923 next = list_first_entry(&ns->sub_ns, typeof(*ns), base.list); 1923 next = list_first_entry(&ns->sub_ns, typeof(*ns), base.list);
1924 mutex_lock(&next->lock); 1924 mutex_lock_nested(&next->lock, next->level);
1925 return next; 1925 return next;
1926 } 1926 }
1927 1927
@@ -1931,7 +1931,7 @@ static struct aa_ns *__next_ns(struct aa_ns *root, struct aa_ns *ns)
1931 mutex_unlock(&ns->lock); 1931 mutex_unlock(&ns->lock);
1932 next = list_next_entry(ns, base.list); 1932 next = list_next_entry(ns, base.list);
1933 if (!list_entry_is_head(next, &parent->sub_ns, base.list)) { 1933 if (!list_entry_is_head(next, &parent->sub_ns, base.list)) {
1934 mutex_lock(&next->lock); 1934 mutex_lock_nested(&next->lock, next->level);
1935 return next; 1935 return next;
1936 } 1936 }
1937 ns = parent; 1937 ns = parent;
@@ -2039,7 +2039,7 @@ static void *p_start(struct seq_file *f, loff_t *pos)
2039 f->private = root; 2039 f->private = root;
2040 2040
2041 /* find the first profile */ 2041 /* find the first profile */
2042 mutex_lock(&root->lock); 2042 mutex_lock_nested(&root->lock, root->level);
2043 profile = __first_profile(root, root); 2043 profile = __first_profile(root, root);
2044 2044
2045 /* skip to position */ 2045 /* skip to position */
@@ -2491,7 +2491,7 @@ static int __init aa_create_aafs(void)
2491 ns_subrevision(root_ns) = dent; 2491 ns_subrevision(root_ns) = dent;
2492 2492
2493 /* policy tree referenced by magic policy symlink */ 2493 /* policy tree referenced by magic policy symlink */
2494 mutex_lock(&root_ns->lock); 2494 mutex_lock_nested(&root_ns->lock, root_ns->level);
2495 error = __aafs_ns_mkdir(root_ns, aafs_mnt->mnt_root, ".policy", 2495 error = __aafs_ns_mkdir(root_ns, aafs_mnt->mnt_root, ".policy",
2496 aafs_mnt->mnt_root); 2496 aafs_mnt->mnt_root);
2497 mutex_unlock(&root_ns->lock); 2497 mutex_unlock(&root_ns->lock);
diff --git a/security/apparmor/domain.c b/security/apparmor/domain.c
index dd754b7850a8..04ba9d0718ea 100644
--- a/security/apparmor/domain.c
+++ b/security/apparmor/domain.c
@@ -305,6 +305,7 @@ static int change_profile_perms(struct aa_profile *profile,
305 * __attach_match_ - find an attachment match 305 * __attach_match_ - find an attachment match
306 * @name - to match against (NOT NULL) 306 * @name - to match against (NOT NULL)
307 * @head - profile list to walk (NOT NULL) 307 * @head - profile list to walk (NOT NULL)
308 * @info - info message if there was an error (NOT NULL)
308 * 309 *
309 * Do a linear search on the profiles in the list. There is a matching 310 * Do a linear search on the profiles in the list. There is a matching
310 * preference where an exact match is preferred over a name which uses 311 * preference where an exact match is preferred over a name which uses
@@ -316,28 +317,46 @@ static int change_profile_perms(struct aa_profile *profile,
316 * Returns: profile or NULL if no match found 317 * Returns: profile or NULL if no match found
317 */ 318 */
318static struct aa_profile *__attach_match(const char *name, 319static struct aa_profile *__attach_match(const char *name,
319 struct list_head *head) 320 struct list_head *head,
321 const char **info)
320{ 322{
321 int len = 0; 323 int len = 0;
324 bool conflict = false;
322 struct aa_profile *profile, *candidate = NULL; 325 struct aa_profile *profile, *candidate = NULL;
323 326
324 list_for_each_entry_rcu(profile, head, base.list) { 327 list_for_each_entry_rcu(profile, head, base.list) {
325 if (profile->label.flags & FLAG_NULL) 328 if (profile->label.flags & FLAG_NULL &&
329 &profile->label == ns_unconfined(profile->ns))
326 continue; 330 continue;
327 if (profile->xmatch && profile->xmatch_len > len) { 331
328 unsigned int state = aa_dfa_match(profile->xmatch, 332 if (profile->xmatch) {
329 DFA_START, name); 333 if (profile->xmatch_len == len) {
330 u32 perm = dfa_user_allow(profile->xmatch, state); 334 conflict = true;
331 /* any accepting state means a valid match. */ 335 continue;
332 if (perm & MAY_EXEC) { 336 } else if (profile->xmatch_len > len) {
333 candidate = profile; 337 unsigned int state;
334 len = profile->xmatch_len; 338 u32 perm;
339
340 state = aa_dfa_match(profile->xmatch,
341 DFA_START, name);
342 perm = dfa_user_allow(profile->xmatch, state);
343 /* any accepting state means a valid match. */
344 if (perm & MAY_EXEC) {
345 candidate = profile;
346 len = profile->xmatch_len;
347 conflict = false;
348 }
335 } 349 }
336 } else if (!strcmp(profile->base.name, name)) 350 } else if (!strcmp(profile->base.name, name))
337 /* exact non-re match, no more searching required */ 351 /* exact non-re match, no more searching required */
338 return profile; 352 return profile;
339 } 353 }
340 354
355 if (conflict) {
356 *info = "conflicting profile attachments";
357 return NULL;
358 }
359
341 return candidate; 360 return candidate;
342} 361}
343 362
@@ -346,16 +365,17 @@ static struct aa_profile *__attach_match(const char *name,
346 * @ns: the current namespace (NOT NULL) 365 * @ns: the current namespace (NOT NULL)
347 * @list: list to search (NOT NULL) 366 * @list: list to search (NOT NULL)
348 * @name: the executable name to match against (NOT NULL) 367 * @name: the executable name to match against (NOT NULL)
368 * @info: info message if there was an error
349 * 369 *
350 * Returns: label or NULL if no match found 370 * Returns: label or NULL if no match found
351 */ 371 */
352static struct aa_label *find_attach(struct aa_ns *ns, struct list_head *list, 372static struct aa_label *find_attach(struct aa_ns *ns, struct list_head *list,
353 const char *name) 373 const char *name, const char **info)
354{ 374{
355 struct aa_profile *profile; 375 struct aa_profile *profile;
356 376
357 rcu_read_lock(); 377 rcu_read_lock();
358 profile = aa_get_profile(__attach_match(name, list)); 378 profile = aa_get_profile(__attach_match(name, list, info));
359 rcu_read_unlock(); 379 rcu_read_unlock();
360 380
361 return profile ? &profile->label : NULL; 381 return profile ? &profile->label : NULL;
@@ -448,11 +468,11 @@ static struct aa_label *x_to_label(struct aa_profile *profile,
448 if (xindex & AA_X_CHILD) 468 if (xindex & AA_X_CHILD)
449 /* released by caller */ 469 /* released by caller */
450 new = find_attach(ns, &profile->base.profiles, 470 new = find_attach(ns, &profile->base.profiles,
451 name); 471 name, info);
452 else 472 else
453 /* released by caller */ 473 /* released by caller */
454 new = find_attach(ns, &ns->base.profiles, 474 new = find_attach(ns, &ns->base.profiles,
455 name); 475 name, info);
456 *lookupname = name; 476 *lookupname = name;
457 break; 477 break;
458 } 478 }
@@ -516,7 +536,7 @@ static struct aa_label *profile_transition(struct aa_profile *profile,
516 536
517 if (profile_unconfined(profile)) { 537 if (profile_unconfined(profile)) {
518 new = find_attach(profile->ns, &profile->ns->base.profiles, 538 new = find_attach(profile->ns, &profile->ns->base.profiles,
519 name); 539 name, &info);
520 if (new) { 540 if (new) {
521 AA_DEBUG("unconfined attached to new label"); 541 AA_DEBUG("unconfined attached to new label");
522 return new; 542 return new;
@@ -541,9 +561,21 @@ static struct aa_label *profile_transition(struct aa_profile *profile,
541 } 561 }
542 } else if (COMPLAIN_MODE(profile)) { 562 } else if (COMPLAIN_MODE(profile)) {
543 /* no exec permission - learning mode */ 563 /* no exec permission - learning mode */
544 struct aa_profile *new_profile = aa_new_null_profile(profile, 564 struct aa_profile *new_profile = NULL;
545 false, name, 565 char *n = kstrdup(name, GFP_ATOMIC);
546 GFP_ATOMIC); 566
567 if (n) {
568 /* name is ptr into buffer */
569 long pos = name - buffer;
570 /* break per cpu buffer hold */
571 put_buffers(buffer);
572 new_profile = aa_new_null_profile(profile, false, n,
573 GFP_KERNEL);
574 get_buffers(buffer);
575 name = buffer + pos;
576 strcpy((char *)name, n);
577 kfree(n);
578 }
547 if (!new_profile) { 579 if (!new_profile) {
548 error = -ENOMEM; 580 error = -ENOMEM;
549 info = "could not create null profile"; 581 info = "could not create null profile";
diff --git a/security/apparmor/file.c b/security/apparmor/file.c
index 3382518b87fa..e79bf44396a3 100644
--- a/security/apparmor/file.c
+++ b/security/apparmor/file.c
@@ -226,18 +226,12 @@ static u32 map_old_perms(u32 old)
226struct aa_perms aa_compute_fperms(struct aa_dfa *dfa, unsigned int state, 226struct aa_perms aa_compute_fperms(struct aa_dfa *dfa, unsigned int state,
227 struct path_cond *cond) 227 struct path_cond *cond)
228{ 228{
229 struct aa_perms perms;
230
231 /* FIXME: change over to new dfa format 229 /* FIXME: change over to new dfa format
232 * currently file perms are encoded in the dfa, new format 230 * currently file perms are encoded in the dfa, new format
233 * splits the permissions from the dfa. This mapping can be 231 * splits the permissions from the dfa. This mapping can be
234 * done at profile load 232 * done at profile load
235 */ 233 */
236 perms.deny = 0; 234 struct aa_perms perms = { };
237 perms.kill = perms.stop = 0;
238 perms.complain = perms.cond = 0;
239 perms.hide = 0;
240 perms.prompt = 0;
241 235
242 if (uid_eq(current_fsuid(), cond->uid)) { 236 if (uid_eq(current_fsuid(), cond->uid)) {
243 perms.allow = map_old_perms(dfa_user_allow(dfa, state)); 237 perms.allow = map_old_perms(dfa_user_allow(dfa, state));
diff --git a/security/apparmor/label.c b/security/apparmor/label.c
index ad28e03a6f30..324fe5c60f87 100644
--- a/security/apparmor/label.c
+++ b/security/apparmor/label.c
@@ -2115,7 +2115,7 @@ void __aa_labelset_update_subtree(struct aa_ns *ns)
2115 __labelset_update(ns); 2115 __labelset_update(ns);
2116 2116
2117 list_for_each_entry(child, &ns->sub_ns, base.list) { 2117 list_for_each_entry(child, &ns->sub_ns, base.list) {
2118 mutex_lock(&child->lock); 2118 mutex_lock_nested(&child->lock, child->level);
2119 __aa_labelset_update_subtree(child); 2119 __aa_labelset_update_subtree(child);
2120 mutex_unlock(&child->lock); 2120 mutex_unlock(&child->lock);
2121 } 2121 }
diff --git a/security/apparmor/lib.c b/security/apparmor/lib.c
index 08ca26bcca77..4d5e98e49d5e 100644
--- a/security/apparmor/lib.c
+++ b/security/apparmor/lib.c
@@ -317,14 +317,11 @@ static u32 map_other(u32 x)
317void aa_compute_perms(struct aa_dfa *dfa, unsigned int state, 317void aa_compute_perms(struct aa_dfa *dfa, unsigned int state,
318 struct aa_perms *perms) 318 struct aa_perms *perms)
319{ 319{
320 perms->deny = 0; 320 *perms = (struct aa_perms) {
321 perms->kill = perms->stop = 0; 321 .allow = dfa_user_allow(dfa, state),
322 perms->complain = perms->cond = 0; 322 .audit = dfa_user_audit(dfa, state),
323 perms->hide = 0; 323 .quiet = dfa_user_quiet(dfa, state),
324 perms->prompt = 0; 324 };
325 perms->allow = dfa_user_allow(dfa, state);
326 perms->audit = dfa_user_audit(dfa, state);
327 perms->quiet = dfa_user_quiet(dfa, state);
328 325
329 /* for v5 perm mapping in the policydb, the other set is used 326 /* for v5 perm mapping in the policydb, the other set is used
330 * to extend the general perm set 327 * to extend the general perm set
@@ -426,7 +423,6 @@ int aa_check_perms(struct aa_profile *profile, struct aa_perms *perms,
426 void (*cb)(struct audit_buffer *, void *)) 423 void (*cb)(struct audit_buffer *, void *))
427{ 424{
428 int type, error; 425 int type, error;
429 bool stop = false;
430 u32 denied = request & (~perms->allow | perms->deny); 426 u32 denied = request & (~perms->allow | perms->deny);
431 427
432 if (likely(!denied)) { 428 if (likely(!denied)) {
@@ -447,8 +443,6 @@ int aa_check_perms(struct aa_profile *profile, struct aa_perms *perms,
447 else 443 else
448 type = AUDIT_APPARMOR_DENIED; 444 type = AUDIT_APPARMOR_DENIED;
449 445
450 if (denied & perms->stop)
451 stop = true;
452 if (denied == (denied & perms->hide)) 446 if (denied == (denied & perms->hide))
453 error = -ENOENT; 447 error = -ENOENT;
454 448
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
index 17893fde4487..9a65eeaf7dfa 100644
--- a/security/apparmor/lsm.c
+++ b/security/apparmor/lsm.c
@@ -846,7 +846,7 @@ module_param_call(audit, param_set_audit, param_get_audit,
846/* Determines if audit header is included in audited messages. This 846/* Determines if audit header is included in audited messages. This
847 * provides more context if the audit daemon is not running 847 * provides more context if the audit daemon is not running
848 */ 848 */
849bool aa_g_audit_header = 1; 849bool aa_g_audit_header = true;
850module_param_named(audit_header, aa_g_audit_header, aabool, 850module_param_named(audit_header, aa_g_audit_header, aabool,
851 S_IRUSR | S_IWUSR); 851 S_IRUSR | S_IWUSR);
852 852
@@ -871,7 +871,7 @@ module_param_named(path_max, aa_g_path_max, aauint, S_IRUSR);
871 * DEPRECATED: read only as strict checking of load is always done now 871 * DEPRECATED: read only as strict checking of load is always done now
872 * that none root users (user namespaces) can load policy. 872 * that none root users (user namespaces) can load policy.
873 */ 873 */
874bool aa_g_paranoid_load = 1; 874bool aa_g_paranoid_load = true;
875module_param_named(paranoid_load, aa_g_paranoid_load, aabool, S_IRUGO); 875module_param_named(paranoid_load, aa_g_paranoid_load, aabool, S_IRUGO);
876 876
877/* Boot time disable flag */ 877/* Boot time disable flag */
@@ -1119,7 +1119,7 @@ static int __init apparmor_init(void)
1119 1119
1120 if (!apparmor_enabled || !security_module_enable("apparmor")) { 1120 if (!apparmor_enabled || !security_module_enable("apparmor")) {
1121 aa_info_message("AppArmor disabled by boot time parameter"); 1121 aa_info_message("AppArmor disabled by boot time parameter");
1122 apparmor_enabled = 0; 1122 apparmor_enabled = false;
1123 return 0; 1123 return 0;
1124 } 1124 }
1125 1125
@@ -1175,7 +1175,7 @@ alloc_out:
1175 aa_destroy_aafs(); 1175 aa_destroy_aafs();
1176 aa_teardown_dfa_engine(); 1176 aa_teardown_dfa_engine();
1177 1177
1178 apparmor_enabled = 0; 1178 apparmor_enabled = false;
1179 return error; 1179 return error;
1180} 1180}
1181 1181
diff --git a/security/apparmor/mount.c b/security/apparmor/mount.c
index 82a64b58041d..ed9b4d0f9f7e 100644
--- a/security/apparmor/mount.c
+++ b/security/apparmor/mount.c
@@ -216,13 +216,12 @@ static unsigned int match_mnt_flags(struct aa_dfa *dfa, unsigned int state,
216static struct aa_perms compute_mnt_perms(struct aa_dfa *dfa, 216static struct aa_perms compute_mnt_perms(struct aa_dfa *dfa,
217 unsigned int state) 217 unsigned int state)
218{ 218{
219 struct aa_perms perms; 219 struct aa_perms perms = {
220 220 .allow = dfa_user_allow(dfa, state),
221 perms.kill = 0; 221 .audit = dfa_user_audit(dfa, state),
222 perms.allow = dfa_user_allow(dfa, state); 222 .quiet = dfa_user_quiet(dfa, state),
223 perms.audit = dfa_user_audit(dfa, state); 223 .xindex = dfa_user_xindex(dfa, state),
224 perms.quiet = dfa_user_quiet(dfa, state); 224 };
225 perms.xindex = dfa_user_xindex(dfa, state);
226 225
227 return perms; 226 return perms;
228} 227}
diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c
index 4243b0c3f0e4..b0b58848c248 100644
--- a/security/apparmor/policy.c
+++ b/security/apparmor/policy.c
@@ -502,7 +502,7 @@ struct aa_profile *aa_new_null_profile(struct aa_profile *parent, bool hat,
502{ 502{
503 struct aa_profile *p, *profile; 503 struct aa_profile *p, *profile;
504 const char *bname; 504 const char *bname;
505 char *name; 505 char *name = NULL;
506 506
507 AA_BUG(!parent); 507 AA_BUG(!parent);
508 508
@@ -545,7 +545,7 @@ name:
545 profile->file.dfa = aa_get_dfa(nulldfa); 545 profile->file.dfa = aa_get_dfa(nulldfa);
546 profile->policy.dfa = aa_get_dfa(nulldfa); 546 profile->policy.dfa = aa_get_dfa(nulldfa);
547 547
548 mutex_lock(&profile->ns->lock); 548 mutex_lock_nested(&profile->ns->lock, profile->ns->level);
549 p = __find_child(&parent->base.profiles, bname); 549 p = __find_child(&parent->base.profiles, bname);
550 if (p) { 550 if (p) {
551 aa_free_profile(profile); 551 aa_free_profile(profile);
@@ -562,6 +562,7 @@ out:
562 return profile; 562 return profile;
563 563
564fail: 564fail:
565 kfree(name);
565 aa_free_profile(profile); 566 aa_free_profile(profile);
566 return NULL; 567 return NULL;
567} 568}
@@ -905,7 +906,7 @@ ssize_t aa_replace_profiles(struct aa_ns *policy_ns, struct aa_label *label,
905 } else 906 } else
906 ns = aa_get_ns(policy_ns ? policy_ns : labels_ns(label)); 907 ns = aa_get_ns(policy_ns ? policy_ns : labels_ns(label));
907 908
908 mutex_lock(&ns->lock); 909 mutex_lock_nested(&ns->lock, ns->level);
909 /* check for duplicate rawdata blobs: space and file dedup */ 910 /* check for duplicate rawdata blobs: space and file dedup */
910 list_for_each_entry(rawdata_ent, &ns->rawdata_list, list) { 911 list_for_each_entry(rawdata_ent, &ns->rawdata_list, list) {
911 if (aa_rawdata_eq(rawdata_ent, udata)) { 912 if (aa_rawdata_eq(rawdata_ent, udata)) {
@@ -1116,13 +1117,13 @@ ssize_t aa_remove_profiles(struct aa_ns *policy_ns, struct aa_label *subj,
1116 1117
1117 if (!name) { 1118 if (!name) {
1118 /* remove namespace - can only happen if fqname[0] == ':' */ 1119 /* remove namespace - can only happen if fqname[0] == ':' */
1119 mutex_lock(&ns->parent->lock); 1120 mutex_lock_nested(&ns->parent->lock, ns->level);
1120 __aa_remove_ns(ns); 1121 __aa_remove_ns(ns);
1121 __aa_bump_ns_revision(ns); 1122 __aa_bump_ns_revision(ns);
1122 mutex_unlock(&ns->parent->lock); 1123 mutex_unlock(&ns->parent->lock);
1123 } else { 1124 } else {
1124 /* remove profile */ 1125 /* remove profile */
1125 mutex_lock(&ns->lock); 1126 mutex_lock_nested(&ns->lock, ns->level);
1126 profile = aa_get_profile(__lookup_profile(&ns->base, name)); 1127 profile = aa_get_profile(__lookup_profile(&ns->base, name));
1127 if (!profile) { 1128 if (!profile) {
1128 error = -ENOENT; 1129 error = -ENOENT;
diff --git a/security/apparmor/policy_ns.c b/security/apparmor/policy_ns.c
index 62a3589c62ab..b1e629cba70b 100644
--- a/security/apparmor/policy_ns.c
+++ b/security/apparmor/policy_ns.c
@@ -256,7 +256,8 @@ static struct aa_ns *__aa_create_ns(struct aa_ns *parent, const char *name,
256 ns = alloc_ns(parent->base.hname, name); 256 ns = alloc_ns(parent->base.hname, name);
257 if (!ns) 257 if (!ns)
258 return NULL; 258 return NULL;
259 mutex_lock(&ns->lock); 259 ns->level = parent->level + 1;
260 mutex_lock_nested(&ns->lock, ns->level);
260 error = __aafs_ns_mkdir(ns, ns_subns_dir(parent), name, dir); 261 error = __aafs_ns_mkdir(ns, ns_subns_dir(parent), name, dir);
261 if (error) { 262 if (error) {
262 AA_ERROR("Failed to create interface for ns %s\n", 263 AA_ERROR("Failed to create interface for ns %s\n",
@@ -266,7 +267,6 @@ static struct aa_ns *__aa_create_ns(struct aa_ns *parent, const char *name,
266 return ERR_PTR(error); 267 return ERR_PTR(error);
267 } 268 }
268 ns->parent = aa_get_ns(parent); 269 ns->parent = aa_get_ns(parent);
269 ns->level = parent->level + 1;
270 list_add_rcu(&ns->base.list, &parent->sub_ns); 270 list_add_rcu(&ns->base.list, &parent->sub_ns);
271 /* add list ref */ 271 /* add list ref */
272 aa_get_ns(ns); 272 aa_get_ns(ns);
@@ -313,7 +313,7 @@ struct aa_ns *aa_prepare_ns(struct aa_ns *parent, const char *name)
313{ 313{
314 struct aa_ns *ns; 314 struct aa_ns *ns;
315 315
316 mutex_lock(&parent->lock); 316 mutex_lock_nested(&parent->lock, parent->level);
317 /* try and find the specified ns and if it doesn't exist create it */ 317 /* try and find the specified ns and if it doesn't exist create it */
318 /* released by caller */ 318 /* released by caller */
319 ns = aa_get_ns(__aa_find_ns(&parent->sub_ns, name)); 319 ns = aa_get_ns(__aa_find_ns(&parent->sub_ns, name));
@@ -336,7 +336,7 @@ static void destroy_ns(struct aa_ns *ns)
336 if (!ns) 336 if (!ns)
337 return; 337 return;
338 338
339 mutex_lock(&ns->lock); 339 mutex_lock_nested(&ns->lock, ns->level);
340 /* release all profiles in this namespace */ 340 /* release all profiles in this namespace */
341 __aa_profile_list_release(&ns->base.profiles); 341 __aa_profile_list_release(&ns->base.profiles);
342 342
diff --git a/security/apparmor/policy_unpack.c b/security/apparmor/policy_unpack.c
index 4ede87c30f8b..59a1a25b7d43 100644
--- a/security/apparmor/policy_unpack.c
+++ b/security/apparmor/policy_unpack.c
@@ -157,7 +157,7 @@ static void do_loaddata_free(struct work_struct *work)
157 struct aa_ns *ns = aa_get_ns(d->ns); 157 struct aa_ns *ns = aa_get_ns(d->ns);
158 158
159 if (ns) { 159 if (ns) {
160 mutex_lock(&ns->lock); 160 mutex_lock_nested(&ns->lock, ns->level);
161 __aa_fs_remove_rawdata(d); 161 __aa_fs_remove_rawdata(d);
162 mutex_unlock(&ns->lock); 162 mutex_unlock(&ns->lock);
163 aa_put_ns(ns); 163 aa_put_ns(ns);
diff --git a/security/apparmor/resource.c b/security/apparmor/resource.c
index d8bc842594ed..cf4d234febe9 100644
--- a/security/apparmor/resource.c
+++ b/security/apparmor/resource.c
@@ -47,7 +47,7 @@ static void audit_cb(struct audit_buffer *ab, void *va)
47/** 47/**
48 * audit_resource - audit setting resource limit 48 * audit_resource - audit setting resource limit
49 * @profile: profile being enforced (NOT NULL) 49 * @profile: profile being enforced (NOT NULL)
50 * @resoure: rlimit being auditing 50 * @resource: rlimit being auditing
51 * @value: value being set 51 * @value: value being set
52 * @error: error value 52 * @error: error value
53 * 53 *
@@ -128,7 +128,7 @@ int aa_task_setrlimit(struct aa_label *label, struct task_struct *task,
128 error = fn_for_each(label, profile, 128 error = fn_for_each(label, profile,
129 audit_resource(profile, resource, 129 audit_resource(profile, resource,
130 new_rlim->rlim_max, peer, 130 new_rlim->rlim_max, peer,
131 "cap_sys_resoure", -EACCES)); 131 "cap_sys_resource", -EACCES));
132 else 132 else
133 error = fn_for_each_confined(label, profile, 133 error = fn_for_each_confined(label, profile,
134 profile_setrlimit(profile, resource, new_rlim)); 134 profile_setrlimit(profile, resource, new_rlim));