From d5748309bb8d75852c92966477277d4572d8920a Mon Sep 17 00:00:00 2001 From: Tetsuo Handa Date: Tue, 10 Apr 2012 20:54:43 -0500 Subject: TOMOYO: Fix mount flags checking order. commit df91e49477a9be15921cb2854e1d12a3bdb5e425 upstream. 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 Signed-off-by: James Morris Signed-off-by: Jonathan Nieder Signed-off-by: Greg Kroah-Hartman --- security/tomoyo/mount.c | 38 ++++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 18 deletions(-) (limited to 'security/tomoyo') diff --git a/security/tomoyo/mount.c b/security/tomoyo/mount.c index 9fc2e15..892494a 100644 --- a/security/tomoyo/mount.c +++ b/security/tomoyo/mount.c @@ -205,30 +205,32 @@ int tomoyo_mount_permission(char *dev_name, struct path *path, char *type, if (flags & MS_REMOUNT) { type = TOMOYO_MOUNT_REMOUNT_KEYWORD; flags &= ~MS_REMOUNT; - } - if (flags & MS_MOVE) { - type = TOMOYO_MOUNT_MOVE_KEYWORD; - flags &= ~MS_MOVE; - } - if (flags & MS_BIND) { + } else if (flags & MS_BIND) { type = TOMOYO_MOUNT_BIND_KEYWORD; flags &= ~MS_BIND; - } - if (flags & MS_UNBINDABLE) { - type = TOMOYO_MOUNT_MAKE_UNBINDABLE_KEYWORD; - flags &= ~MS_UNBINDABLE; - } - if (flags & MS_PRIVATE) { + } else if (flags & MS_SHARED) { + if (flags & (MS_PRIVATE | MS_SLAVE | MS_UNBINDABLE)) + return -EINVAL; + type = TOMOYO_MOUNT_MAKE_SHARED_KEYWORD; + flags &= ~MS_SHARED; + } else if (flags & MS_PRIVATE) { + if (flags & (MS_SHARED | MS_SLAVE | MS_UNBINDABLE)) + return -EINVAL; type = TOMOYO_MOUNT_MAKE_PRIVATE_KEYWORD; flags &= ~MS_PRIVATE; - } - if (flags & MS_SLAVE) { + } else if (flags & MS_SLAVE) { + if (flags & (MS_SHARED | MS_PRIVATE | MS_UNBINDABLE)) + return -EINVAL; type = TOMOYO_MOUNT_MAKE_SLAVE_KEYWORD; flags &= ~MS_SLAVE; - } - if (flags & MS_SHARED) { - type = TOMOYO_MOUNT_MAKE_SHARED_KEYWORD; - flags &= ~MS_SHARED; + } else if (flags & MS_UNBINDABLE) { + if (flags & (MS_SHARED | MS_PRIVATE | MS_SLAVE)) + return -EINVAL; + type = TOMOYO_MOUNT_MAKE_UNBINDABLE_KEYWORD; + flags &= ~MS_UNBINDABLE; + } else if (flags & MS_MOVE) { + type = TOMOYO_MOUNT_MOVE_KEYWORD; + flags &= ~MS_MOVE; } if (!type) type = ""; -- cgit v1.1