diff options
Diffstat (limited to 'security/apparmor')
-rw-r--r-- | security/apparmor/.gitignore | 1 | ||||
-rw-r--r-- | security/apparmor/domain.c | 4 | ||||
-rw-r--r-- | security/apparmor/lib.c | 1 | ||||
-rw-r--r-- | security/apparmor/lsm.c | 2 | ||||
-rw-r--r-- | security/apparmor/path.c | 65 |
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 | # |
4 | af_names.h | ||
5 | capability_names.h | 4 | capability_names.h |
6 | rlim_names.h | 5 | rlim_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 | ||
84 | out: | 83 | out: |
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) | |||
57 | static int d_namespace_path(struct path *path, char *buf, int buflen, | 57 | static 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 | ||
111 | ok: | ||
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 | ||
135 | out: | 148 | out: |
136 | path_put(&root); | ||
137 | |||
138 | return error; | 149 | return error; |
139 | } | 150 | } |
140 | 151 | ||