Revision a318f12ed8843cfac53198390c74a565c632f417 authored by Kees Cook on 16 July 2019, 23:30:21 UTC, committed by Linus Torvalds on 17 July 2019, 02:23:24 UTC
Andreas Christoforou reported:

  UBSAN: Undefined behaviour in ipc/mqueue.c:414:49 signed integer overflow:
  9 * 2305843009213693951 cannot be represented in type 'long int'
  ...
  Call Trace:
    mqueue_evict_inode+0x8e7/0xa10 ipc/mqueue.c:414
    evict+0x472/0x8c0 fs/inode.c:558
    iput_final fs/inode.c:1547 [inline]
    iput+0x51d/0x8c0 fs/inode.c:1573
    mqueue_get_inode+0x8eb/0x1070 ipc/mqueue.c:320
    mqueue_create_attr+0x198/0x440 ipc/mqueue.c:459
    vfs_mkobj+0x39e/0x580 fs/namei.c:2892
    prepare_open ipc/mqueue.c:731 [inline]
    do_mq_open+0x6da/0x8e0 ipc/mqueue.c:771

Which could be triggered by:

        struct mq_attr attr = {
                .mq_flags = 0,
                .mq_maxmsg = 9,
                .mq_msgsize = 0x1fffffffffffffff,
                .mq_curmsgs = 0,
        };

        if (mq_open("/testing", 0x40, 3, &attr) == (mqd_t) -1)
                perror("mq_open");

mqueue_get_inode() was correctly rejecting the giant mq_msgsize, and
preparing to return -EINVAL.  During the cleanup, it calls
mqueue_evict_inode() which performed resource usage tracking math for
updating "user", before checking if there was a valid "user" at all
(which would indicate that the calculations would be sane).  Instead,
delay this check to after seeing a valid "user".

The overflow was real, but the results went unused, so while the flaw is
harmless, it's noisy for kernel fuzzers, so just fix it by moving the
calculation under the non-NULL "user" where it actually gets used.

Link: http://lkml.kernel.org/r/201906072207.ECB65450@keescook
Signed-off-by: Kees Cook <keescook@chromium.org>
Reported-by: Andreas Christoforou <andreaschristofo@gmail.com>
Acked-by: "Eric W. Biederman" <ebiederm@xmission.com>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Davidlohr Bueso <dave@stgolabs.net>
Cc: Manfred Spraul <manfred@colorfullife.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
1 parent 6b15f67
History
File Mode Size
9p
adfs
affs
afs
autofs
befs
bfs
btrfs
cachefiles
ceph
cifs
coda
configfs
cramfs
crypto
debugfs
devpts
dlm
ecryptfs
efivarfs
efs
exportfs
ext2
ext4
f2fs
fat
freevxfs
fscache
fuse
gfs2
hfs
hfsplus
hostfs
hpfs
hugetlbfs
isofs
jbd2
jffs2
jfs
kernfs
lockd
minix
nfs
nfs_common
nfsd
nilfs2
nls
notify
ntfs
ocfs2
omfs
openpromfs
orangefs
overlayfs
proc
pstore
qnx4
qnx6
quota
ramfs
reiserfs
romfs
squashfs
sysfs
sysv
tracefs
ubifs
udf
ufs
unicode
xfs
Kconfig -rw-r--r-- 7.6 KB
Kconfig.binfmt -rw-r--r-- 7.6 KB
Makefile -rw-r--r-- 4.3 KB
aio.c -rw-r--r-- 56.1 KB
anon_inodes.c -rw-r--r-- 4.5 KB
attr.c -rw-r--r-- 9.7 KB
bad_inode.c -rw-r--r-- 5.3 KB
binfmt_aout.c -rw-r--r-- 8.3 KB
binfmt_elf.c -rw-r--r-- 63.7 KB
binfmt_elf_fdpic.c -rw-r--r-- 47.1 KB
binfmt_em86.c -rw-r--r-- 2.8 KB
binfmt_flat.c -rw-r--r-- 28.0 KB
binfmt_misc.c -rw-r--r-- 18.4 KB
binfmt_script.c -rw-r--r-- 4.4 KB
block_dev.c -rw-r--r-- 54.5 KB
buffer.c -rw-r--r-- 90.2 KB
char_dev.c -rw-r--r-- 16.5 KB
compat.c -rw-r--r-- 3.2 KB
compat_binfmt_elf.c -rw-r--r-- 3.2 KB
compat_ioctl.c -rw-r--r-- 31.0 KB
coredump.c -rw-r--r-- 21.2 KB
d_path.c -rw-r--r-- 11.2 KB
dax.c -rw-r--r-- 45.4 KB
dcache.c -rw-r--r-- 82.4 KB
dcookies.c -rw-r--r-- 7.1 KB
direct-io.c -rw-r--r-- 40.8 KB
drop_caches.c -rw-r--r-- 1.8 KB
eventfd.c -rw-r--r-- 11.1 KB
eventpoll.c -rw-r--r-- 64.5 KB
exec.c -rw-r--r-- 46.9 KB
fcntl.c -rw-r--r-- 23.3 KB
fhandle.c -rw-r--r-- 6.8 KB
file.c -rw-r--r-- 24.2 KB
file_table.c -rw-r--r-- 10.2 KB
filesystems.c -rw-r--r-- 6.4 KB
fs-writeback.c -rw-r--r-- 72.1 KB
fs_context.c -rw-r--r-- 18.5 KB
fs_parser.c -rw-r--r-- 10.7 KB
fs_pin.c -rw-r--r-- 2.0 KB
fs_struct.c -rw-r--r-- 3.3 KB
fs_types.c -rw-r--r-- 2.5 KB
fsopen.c -rw-r--r-- 11.1 KB
inode.c -rw-r--r-- 59.7 KB
internal.h -rw-r--r-- 5.1 KB
io_uring.c -rw-r--r-- 81.6 KB
ioctl.c -rw-r--r-- 17.7 KB
iomap.c -rw-r--r-- 55.2 KB
libfs.c -rw-r--r-- 32.4 KB
locks.c -rw-r--r-- 77.5 KB
mbcache.c -rw-r--r-- 12.0 KB
mount.h -rw-r--r-- 3.9 KB
mpage.c -rw-r--r-- 21.1 KB
namei.c -rw-r--r-- 123.0 KB
namespace.c -rw-r--r-- 96.3 KB
no-block.c -rw-r--r-- 478 bytes
nsfs.c -rw-r--r-- 6.1 KB
open.c -rw-r--r-- 29.3 KB
pipe.c -rw-r--r-- 27.6 KB
pnode.c -rw-r--r-- 15.1 KB
pnode.h -rw-r--r-- 1.9 KB
posix_acl.c -rw-r--r-- 21.5 KB
proc_namespace.c -rw-r--r-- 7.8 KB
read_write.c -rw-r--r-- 50.7 KB
readdir.c -rw-r--r-- 11.3 KB
select.c -rw-r--r-- 34.3 KB
seq_file.c -rw-r--r-- 24.7 KB
signalfd.c -rw-r--r-- 9.0 KB
splice.c -rw-r--r-- 40.2 KB
stack.c -rw-r--r-- 2.5 KB
stat.c -rw-r--r-- 19.4 KB
statfs.c -rw-r--r-- 9.9 KB
super.c -rw-r--r-- 46.3 KB
sync.c -rw-r--r-- 10.4 KB
timerfd.c -rw-r--r-- 13.4 KB
userfaultfd.c -rw-r--r-- 51.1 KB
utimes.c -rw-r--r-- 7.4 KB
xattr.c -rw-r--r-- 23.5 KB

back to top