diff options
author | Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> | 2012-02-29 07:53:22 -0500 |
---|---|---|
committer | James Morris <james.l.morris@oracle.com> | 2012-02-29 18:23:19 -0500 |
commit | df91e49477a9be15921cb2854e1d12a3bdb5e425 (patch) | |
tree | 8408a7d2a432a206070ac01b2939fefcdce9ca13 /security/tomoyo | |
parent | a69f15890292b5449f9056b4bb322b044e6ce0c6 (diff) |
TOMOYO: Fix mount flags checking order.
Userspace can pass in arbitrary combinations of MS_* flags to mount().
If both MS_BIND and one of MS_SHARED/MS_PRIVATE/MS_SLAVE/MS_UNBINDABLE are
passed, device name which should be checked for MS_BIND was not checked because
MS_SHARED/MS_PRIVATE/MS_SLAVE/MS_UNBINDABLE had higher priority than MS_BIND.
If both one of MS_BIND/MS_MOVE and MS_REMOUNT are passed, device name which
should not be checked for MS_REMOUNT was checked because MS_BIND/MS_MOVE had
higher priority than MS_REMOUNT.
Fix these bugs by changing priority to MS_REMOUNT -> MS_BIND ->
MS_SHARED/MS_PRIVATE/MS_SLAVE/MS_UNBINDABLE -> MS_MOVE as with do_mount() does.
Also, unconditionally return -EINVAL if more than one of
MS_SHARED/MS_PRIVATE/MS_SLAVE/MS_UNBINDABLE is passed so that TOMOYO will not
generate inaccurate audit logs, for commit 7a2e8a8f "VFS: Sanity check mount
flags passed to change_mnt_propagation()" clarified that these flags must be
exclusively passed.
Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Signed-off-by: James Morris <james.l.morris@oracle.com>
Diffstat (limited to 'security/tomoyo')
-rw-r--r-- | security/tomoyo/mount.c | 38 |
1 files changed, 20 insertions, 18 deletions
diff --git a/security/tomoyo/mount.c b/security/tomoyo/mount.c index bee09d062057..fe00cdfd0267 100644 --- a/security/tomoyo/mount.c +++ b/security/tomoyo/mount.c | |||
@@ -199,30 +199,32 @@ int tomoyo_mount_permission(char *dev_name, struct path *path, | |||
199 | if (flags & MS_REMOUNT) { | 199 | if (flags & MS_REMOUNT) { |
200 | type = tomoyo_mounts[TOMOYO_MOUNT_REMOUNT]; | 200 | type = tomoyo_mounts[TOMOYO_MOUNT_REMOUNT]; |
201 | flags &= ~MS_REMOUNT; | 201 | flags &= ~MS_REMOUNT; |
202 | } | 202 | } else if (flags & MS_BIND) { |
203 | if (flags & MS_MOVE) { | ||
204 | type = tomoyo_mounts[TOMOYO_MOUNT_MOVE]; | ||
205 | flags &= ~MS_MOVE; | ||
206 | } | ||
207 | if (flags & MS_BIND) { | ||
208 | type = tomoyo_mounts[TOMOYO_MOUNT_BIND]; | 203 | type = tomoyo_mounts[TOMOYO_MOUNT_BIND]; |
209 | flags &= ~MS_BIND; | 204 | flags &= ~MS_BIND; |
210 | } | 205 | } else if (flags & MS_SHARED) { |
211 | if (flags & MS_UNBINDABLE) { | 206 | if (flags & (MS_PRIVATE | MS_SLAVE | MS_UNBINDABLE)) |
212 | type = tomoyo_mounts[TOMOYO_MOUNT_MAKE_UNBINDABLE]; | 207 | return -EINVAL; |
213 | flags &= ~MS_UNBINDABLE; | 208 | type = tomoyo_mounts[TOMOYO_MOUNT_MAKE_SHARED]; |
214 | } | 209 | flags &= ~MS_SHARED; |
215 | if (flags & MS_PRIVATE) { | 210 | } else if (flags & MS_PRIVATE) { |
211 | if (flags & (MS_SHARED | MS_SLAVE | MS_UNBINDABLE)) | ||
212 | return -EINVAL; | ||
216 | type = tomoyo_mounts[TOMOYO_MOUNT_MAKE_PRIVATE]; | 213 | type = tomoyo_mounts[TOMOYO_MOUNT_MAKE_PRIVATE]; |
217 | flags &= ~MS_PRIVATE; | 214 | flags &= ~MS_PRIVATE; |
218 | } | 215 | } else if (flags & MS_SLAVE) { |
219 | if (flags & MS_SLAVE) { | 216 | if (flags & (MS_SHARED | MS_PRIVATE | MS_UNBINDABLE)) |
217 | return -EINVAL; | ||
220 | type = tomoyo_mounts[TOMOYO_MOUNT_MAKE_SLAVE]; | 218 | type = tomoyo_mounts[TOMOYO_MOUNT_MAKE_SLAVE]; |
221 | flags &= ~MS_SLAVE; | 219 | flags &= ~MS_SLAVE; |
222 | } | 220 | } else if (flags & MS_UNBINDABLE) { |
223 | if (flags & MS_SHARED) { | 221 | if (flags & (MS_SHARED | MS_PRIVATE | MS_SLAVE)) |
224 | type = tomoyo_mounts[TOMOYO_MOUNT_MAKE_SHARED]; | 222 | return -EINVAL; |
225 | flags &= ~MS_SHARED; | 223 | type = tomoyo_mounts[TOMOYO_MOUNT_MAKE_UNBINDABLE]; |
224 | flags &= ~MS_UNBINDABLE; | ||
225 | } else if (flags & MS_MOVE) { | ||
226 | type = tomoyo_mounts[TOMOYO_MOUNT_MOVE]; | ||
227 | flags &= ~MS_MOVE; | ||
226 | } | 228 | } |
227 | if (!type) | 229 | if (!type) |
228 | type = "<NULL>"; | 230 | type = "<NULL>"; |