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 | |
| 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')
| -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>"; |
