aboutsummaryrefslogtreecommitdiffstats
path: root/security/apparmor
diff options
context:
space:
mode:
Diffstat (limited to 'security/apparmor')
-rw-r--r--security/apparmor/.gitignore1
-rw-r--r--security/apparmor/domain.c4
-rw-r--r--security/apparmor/lib.c1
-rw-r--r--security/apparmor/lsm.c2
-rw-r--r--security/apparmor/path.c65
5 files changed, 42 insertions, 31 deletions
diff --git a/security/apparmor/.gitignore b/security/apparmor/.gitignore
index 4d995aeaebc..9cdec70d72b 100644
--- a/security/apparmor/.gitignore
+++ b/security/apparmor/.gitignore
@@ -1,6 +1,5 @@
1# 1#
2# Generated include files 2# Generated include files
3# 3#
4af_names.h
5capability_names.h 4capability_names.h
6rlim_names.h 5rlim_names.h
diff --git a/security/apparmor/domain.c b/security/apparmor/domain.c
index c825c6e0b63..c1e18ba5bdc 100644
--- a/security/apparmor/domain.c
+++ b/security/apparmor/domain.c
@@ -67,13 +67,12 @@ static int may_change_ptraced_domain(struct task_struct *task,
67 int error = 0; 67 int error = 0;
68 68
69 rcu_read_lock(); 69 rcu_read_lock();
70 tracer = tracehook_tracer_task(task); 70 tracer = ptrace_parent(task);
71 if (tracer) { 71 if (tracer) {
72 /* released below */ 72 /* released below */
73 cred = get_task_cred(tracer); 73 cred = get_task_cred(tracer);
74 tracerp = aa_cred_profile(cred); 74 tracerp = aa_cred_profile(cred);
75 } 75 }
76 rcu_read_unlock();
77 76
78 /* not ptraced */ 77 /* not ptraced */
79 if (!tracer || unconfined(tracerp)) 78 if (!tracer || unconfined(tracerp))
@@ -82,6 +81,7 @@ static int may_change_ptraced_domain(struct task_struct *task,
82 error = aa_may_ptrace(tracer, tracerp, to_profile, PTRACE_MODE_ATTACH); 81 error = aa_may_ptrace(tracer, tracerp, to_profile, PTRACE_MODE_ATTACH);
83 82
84out: 83out:
84 rcu_read_unlock();
85 if (cred) 85 if (cred)
86 put_cred(cred); 86 put_cred(cred);
87 87
diff --git a/security/apparmor/lib.c b/security/apparmor/lib.c
index 506d2baf614..b82e383beb7 100644
--- a/security/apparmor/lib.c
+++ b/security/apparmor/lib.c
@@ -12,6 +12,7 @@
12 * License. 12 * License.
13 */ 13 */
14 14
15#include <linux/mm.h>
15#include <linux/slab.h> 16#include <linux/slab.h>
16#include <linux/string.h> 17#include <linux/string.h>
17#include <linux/vmalloc.h> 18#include <linux/vmalloc.h>
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
index 3d2fd141dff..37832026e58 100644
--- a/security/apparmor/lsm.c
+++ b/security/apparmor/lsm.c
@@ -127,7 +127,7 @@ static int apparmor_capget(struct task_struct *target, kernel_cap_t *effective,
127 *inheritable = cred->cap_inheritable; 127 *inheritable = cred->cap_inheritable;
128 *permitted = cred->cap_permitted; 128 *permitted = cred->cap_permitted;
129 129
130 if (!unconfined(profile)) { 130 if (!unconfined(profile) && !COMPLAIN_MODE(profile)) {
131 *effective = cap_intersect(*effective, profile->caps.allow); 131 *effective = cap_intersect(*effective, profile->caps.allow);
132 *permitted = cap_intersect(*permitted, profile->caps.allow); 132 *permitted = cap_intersect(*permitted, profile->caps.allow);
133 } 133 }
diff --git a/security/apparmor/path.c b/security/apparmor/path.c
index 36cc0cc39e7..b566eba4a65 100644
--- a/security/apparmor/path.c
+++ b/security/apparmor/path.c
@@ -57,23 +57,44 @@ static int prepend(char **buffer, int buflen, const char *str, int namelen)
57static int d_namespace_path(struct path *path, char *buf, int buflen, 57static int d_namespace_path(struct path *path, char *buf, int buflen,
58 char **name, int flags) 58 char **name, int flags)
59{ 59{
60 struct path root, tmp;
61 char *res; 60 char *res;
62 int connected, error = 0; 61 int error = 0;
62 int connected = 1;
63
64 if (path->mnt->mnt_flags & MNT_INTERNAL) {
65 /* it's not mounted anywhere */
66 res = dentry_path(path->dentry, buf, buflen);
67 *name = res;
68 if (IS_ERR(res)) {
69 *name = buf;
70 return PTR_ERR(res);
71 }
72 if (path->dentry->d_sb->s_magic == PROC_SUPER_MAGIC &&
73 strncmp(*name, "/sys/", 5) == 0) {
74 /* TODO: convert over to using a per namespace
75 * control instead of hard coded /proc
76 */
77 return prepend(name, *name - buf, "/proc", 5);
78 }
79 return 0;
80 }
63 81
64 /* Get the root we want to resolve too, released below */ 82 /* resolve paths relative to chroot?*/
65 if (flags & PATH_CHROOT_REL) { 83 if (flags & PATH_CHROOT_REL) {
66 /* resolve paths relative to chroot */ 84 struct path root;
67 get_fs_root(current->fs, &root); 85 get_fs_root(current->fs, &root);
68 } else { 86 res = __d_path(path, &root, buf, buflen);
69 /* resolve paths relative to namespace */ 87 if (res && !IS_ERR(res)) {
70 root.mnt = current->nsproxy->mnt_ns->root; 88 /* everything's fine */
71 root.dentry = root.mnt->mnt_root; 89 *name = res;
72 path_get(&root); 90 path_put(&root);
91 goto ok;
92 }
93 path_put(&root);
94 connected = 0;
73 } 95 }
74 96
75 tmp = root; 97 res = d_absolute_path(path, buf, buflen);
76 res = __d_path(path, &tmp, buf, buflen);
77 98
78 *name = res; 99 *name = res;
79 /* handle error conditions - and still allow a partial path to 100 /* handle error conditions - and still allow a partial path to
@@ -84,7 +105,10 @@ static int d_namespace_path(struct path *path, char *buf, int buflen,
84 *name = buf; 105 *name = buf;
85 goto out; 106 goto out;
86 } 107 }
108 if (!our_mnt(path->mnt))
109 connected = 0;
87 110
111ok:
88 /* Handle two cases: 112 /* Handle two cases:
89 * 1. A deleted dentry && profile is not allowing mediation of deleted 113 * 1. A deleted dentry && profile is not allowing mediation of deleted
90 * 2. On some filesystems, newly allocated dentries appear to the 114 * 2. On some filesystems, newly allocated dentries appear to the
@@ -97,10 +121,7 @@ static int d_namespace_path(struct path *path, char *buf, int buflen,
97 goto out; 121 goto out;
98 } 122 }
99 123
100 /* Determine if the path is connected to the expected root */ 124 /* If the path is not connected to the expected root,
101 connected = tmp.dentry == root.dentry && tmp.mnt == root.mnt;
102
103 /* If the path is not connected,
104 * check if it is a sysctl and handle specially else remove any 125 * check if it is a sysctl and handle specially else remove any
105 * leading / that __d_path may have returned. 126 * leading / that __d_path may have returned.
106 * Unless 127 * Unless
@@ -112,17 +133,9 @@ static int d_namespace_path(struct path *path, char *buf, int buflen,
112 * namespace root. 133 * namespace root.
113 */ 134 */
114 if (!connected) { 135 if (!connected) {
115 /* is the disconnect path a sysctl? */ 136 if (!(flags & PATH_CONNECT_PATH) &&
116 if (tmp.dentry->d_sb->s_magic == PROC_SUPER_MAGIC &&
117 strncmp(*name, "/sys/", 5) == 0) {
118 /* TODO: convert over to using a per namespace
119 * control instead of hard coded /proc
120 */
121 error = prepend(name, *name - buf, "/proc", 5);
122 } else if (!(flags & PATH_CONNECT_PATH) &&
123 !(((flags & CHROOT_NSCONNECT) == CHROOT_NSCONNECT) && 137 !(((flags & CHROOT_NSCONNECT) == CHROOT_NSCONNECT) &&
124 (tmp.mnt == current->nsproxy->mnt_ns->root && 138 our_mnt(path->mnt))) {
125 tmp.dentry == tmp.mnt->mnt_root))) {
126 /* disconnected path, don't return pathname starting 139 /* disconnected path, don't return pathname starting
127 * with '/' 140 * with '/'
128 */ 141 */
@@ -133,8 +146,6 @@ static int d_namespace_path(struct path *path, char *buf, int buflen,
133 } 146 }
134 147
135out: 148out:
136 path_put(&root);
137
138 return error; 149 return error;
139} 150}
140 151