linux-brain/fs/nfsd
Scott Mayhew 8bccc6c902 nfsd: fix potential use-after-free in nfsd4_decode_getdeviceinfo
[ Upstream commit 3171822fdc ]

When running a fuzz tester against a KASAN-enabled kernel, the following
splat periodically occurs.

The problem occurs when the test sends a GETDEVICEINFO request with a
malformed xdr array (size but no data) for gdia_notify_types and the
array size is > 0x3fffffff, which results in an overflow in the value of
nbytes which is passed to read_buf().

If the array size is 0x40000000, 0x80000000, or 0xc0000000, then after
the overflow occurs, the value of nbytes 0, and when that happens the
pointer returned by read_buf() points to the end of the xdr data (i.e.
argp->end) when really it should be returning NULL.

Fix this by returning NFS4ERR_BAD_XDR if the array size is > 1000 (this
value is arbitrary, but it's the same threshold used by
nfsd4_decode_bitmap()... in could really be any value >= 1 since it's
expected to get at most a single bitmap in gdia_notify_types).

[  119.256854] ==================================================================
[  119.257611] BUG: KASAN: use-after-free in nfsd4_decode_getdeviceinfo+0x5a4/0x5b0 [nfsd]
[  119.258422] Read of size 4 at addr ffff880113ada000 by task nfsd/538

[  119.259146] CPU: 0 PID: 538 Comm: nfsd Not tainted 4.17.0+ #1
[  119.259662] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.9.3-1.fc25 04/01/2014
[  119.261202] Call Trace:
[  119.262265]  dump_stack+0x71/0xab
[  119.263371]  print_address_description+0x6a/0x270
[  119.264609]  kasan_report+0x258/0x380
[  119.265854]  ? nfsd4_decode_getdeviceinfo+0x5a4/0x5b0 [nfsd]
[  119.267291]  nfsd4_decode_getdeviceinfo+0x5a4/0x5b0 [nfsd]
[  119.268549]  ? nfs4svc_decode_compoundargs+0xa5b/0x13c0 [nfsd]
[  119.269873]  ? nfsd4_decode_sequence+0x490/0x490 [nfsd]
[  119.271095]  nfs4svc_decode_compoundargs+0xa5b/0x13c0 [nfsd]
[  119.272393]  ? nfsd4_release_compoundargs+0x1b0/0x1b0 [nfsd]
[  119.273658]  nfsd_dispatch+0x183/0x850 [nfsd]
[  119.274918]  svc_process+0x161c/0x31a0 [sunrpc]
[  119.276172]  ? svc_printk+0x190/0x190 [sunrpc]
[  119.277386]  ? svc_xprt_release+0x451/0x680 [sunrpc]
[  119.278622]  nfsd+0x2b9/0x430 [nfsd]
[  119.279771]  ? nfsd_destroy+0x1c0/0x1c0 [nfsd]
[  119.281157]  kthread+0x2db/0x390
[  119.282347]  ? kthread_create_worker_on_cpu+0xc0/0xc0
[  119.283756]  ret_from_fork+0x35/0x40

[  119.286041] Allocated by task 436:
[  119.287525]  kasan_kmalloc+0xa0/0xd0
[  119.288685]  kmem_cache_alloc+0xe9/0x1f0
[  119.289900]  get_empty_filp+0x7b/0x410
[  119.291037]  path_openat+0xca/0x4220
[  119.292242]  do_filp_open+0x182/0x280
[  119.293411]  do_sys_open+0x216/0x360
[  119.294555]  do_syscall_64+0xa0/0x2f0
[  119.295721]  entry_SYSCALL_64_after_hwframe+0x44/0xa9

[  119.298068] Freed by task 436:
[  119.299271]  __kasan_slab_free+0x130/0x180
[  119.300557]  kmem_cache_free+0x78/0x210
[  119.301823]  rcu_process_callbacks+0x35b/0xbd0
[  119.303162]  __do_softirq+0x192/0x5ea

[  119.305443] The buggy address belongs to the object at ffff880113ada000
                which belongs to the cache filp of size 256
[  119.308556] The buggy address is located 0 bytes inside of
                256-byte region [ffff880113ada000, ffff880113ada100)
[  119.311376] The buggy address belongs to the page:
[  119.312728] page:ffffea00044eb680 count:1 mapcount:0 mapping:0000000000000000 index:0xffff880113ada780
[  119.314428] flags: 0x17ffe000000100(slab)
[  119.315740] raw: 0017ffe000000100 0000000000000000 ffff880113ada780 00000001000c0001
[  119.317379] raw: ffffea0004553c60 ffffea00045c11e0 ffff88011b167e00 0000000000000000
[  119.319050] page dumped because: kasan: bad access detected

[  119.321652] Memory state around the buggy address:
[  119.322993]  ffff880113ad9f00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[  119.324515]  ffff880113ad9f80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[  119.326087] >ffff880113ada000: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[  119.327547]                    ^
[  119.328730]  ffff880113ada080: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[  119.330218]  ffff880113ada100: fc fc fc fc fc fc fc fc fb fb fb fb fb fb fb fb
[  119.331740] ==================================================================

Signed-off-by: Scott Mayhew <smayhew@redhat.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Signed-off-by: Sasha Levin <alexander.levin@microsoft.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2018-08-03 07:55:13 +02:00
..
acl.h nfsd4: remove nfs4_acl_new 2014-07-08 17:14:27 -04:00
auth.c nfsd: auth: Fix gid sorting when rootsquash enabled 2018-01-31 12:55:57 +01:00
auth.h nfsd: Remove nfsd_luid, nfsd_lgid, nfsd_ruid and nfsd_rgid 2013-02-13 06:15:51 -08:00
blocklayout.c fs: add i_blocksize() 2017-06-14 15:06:00 +02:00
blocklayoutxdr.c Highlights: 2016-08-04 19:59:06 -04:00
blocklayoutxdr.h nfsd: add SCSI layout support 2016-03-18 11:42:53 -04:00
cache.h nfsd: Remove the cache_hash list 2014-08-17 12:00:12 -04:00
current_stateid.h nfsd41: use current stateid by value 2012-02-15 11:20:45 -05:00
export.c nfsd: allow nfsd to advertise multiple layout types 2016-07-15 15:31:32 -04:00
export.h nfsd: allow nfsd to advertise multiple layout types 2016-07-15 15:31:32 -04:00
fault_inject.c nfsd: remove old fault injection infrastructure 2014-08-05 10:55:10 -04:00
flexfilelayout.c nfsd: don't set a FL_LAYOUT lease for flexfiles layouts 2016-09-16 16:15:52 -04:00
flexfilelayoutxdr.c nfsd: Add a super simple flex file server 2016-07-13 15:40:48 -04:00
flexfilelayoutxdr.h nfsd: Add a super simple flex file server 2016-07-13 15:40:48 -04:00
idmap.h nfsd: Remove duplicate define of IDMAP_NAMESZ/IDMAP_TYPE_xx 2015-07-20 14:58:46 -04:00
Kconfig xfs: abstract block export operations from nfsd layouts 2016-07-15 15:31:29 -04:00
lockd.c lockd: constify nlmsvc_binding structure 2016-01-07 10:10:50 -05:00
Makefile nfsd: Add a super simple flex file server 2016-07-13 15:40:48 -04:00
netns.h nfsd: move blocked lock handling under a dedicated spinlock 2016-10-24 16:51:21 -04:00
nfs2acl.c nfsd: check permissions when setting ACLs 2016-06-24 12:11:52 -04:00
nfs3acl.c nfsd: check permissions when setting ACLs 2016-06-24 12:11:52 -04:00
nfs3proc.c don't bother with ->d_inode->i_sb - it's always equal to ->d_sb 2016-04-10 17:11:51 -04:00
nfs3xdr.c nfsd: stricter decoding of write-like NFSv2/v3 ops 2017-05-03 08:36:38 -07:00
nfs4acl.c nfsd: check permissions when setting ACLs 2016-06-24 12:11:52 -04:00
nfs4callback.c nfsd/callback: Cleanup callback cred on shutdown 2017-10-21 17:21:38 +02:00
nfs4idmap.c nfsd: Remove duplicate define of IDMAP_NAMESZ/IDMAP_TYPE_xx 2015-07-20 14:58:46 -04:00
nfs4layouts.c NFSD: Fix a null reference case in find_or_create_lock_stateid() 2017-02-09 08:08:27 +01:00
nfs4proc.c nfsd4: permit layoutget of executable-only files 2018-03-24 11:00:26 +01:00
nfs4recover.c Various bugfixes, a RDMA update from Chuck Lever, and support for a new 2016-03-24 10:41:00 -07:00
nfs4state.c nfsd: remove blocked locks on client teardown 2018-03-28 18:39:21 +02:00
nfs4xdr.c nfsd: fix potential use-after-free in nfsd4_decode_getdeviceinfo 2018-08-03 07:55:13 +02:00
nfscache.c nfsd: remove recurring workqueue job to clean DRC 2015-11-10 09:25:51 -05:00
nfsctl.c nfsd: randomize SETCLIENTID reply to help distinguish servers 2016-09-26 15:20:38 -04:00
nfsd.h nfsd: implement machine credential support for some operations 2016-07-13 15:32:47 -04:00
nfsfh.c nfsd: check d_can_lookup in fh_verify of directories 2016-08-04 17:11:48 -04:00
nfsfh.h wrappers for ->i_mutex access 2016-01-22 18:04:28 -05:00
nfsproc.c nfsd: map the ENOKEY to nfserr_perm for avoiding warning 2017-04-08 09:30:33 +02:00
nfssvc.c NFSD: fix nfsd_reset_versions for NFSv4. 2017-12-20 10:07:20 +01:00
nfsxdr.c nfsd: stricter decoding of write-like NFSv2/v3 ops 2017-05-03 08:36:38 -07:00
pnfs.h nfsd: don't set a FL_LAYOUT lease for flexfiles layouts 2016-09-16 16:15:52 -04:00
state.h nfsd/callback: Cleanup callback cred on shutdown 2017-10-21 17:21:38 +02:00
stats.c drop redundant ->owner initializations 2016-05-29 19:08:00 -04:00
stats.h nfsd: move <linux/nfsd/stats.h> to fs/nfsd 2014-05-06 17:54:55 -04:00
trace.c nfsd: move include of state.h from trace.c to trace.h 2015-10-23 15:57:29 -04:00
trace.h nfsd: add new io class tracepoint 2016-01-14 17:32:51 -05:00
vfs.c NFS: don't try to cross a mountpount when there isn't one there. 2018-03-24 11:00:15 +01:00
vfs.h NFSD: Implement the COPY call 2016-10-07 14:54:25 -04:00
xdr.h nfsd: handle vfs_getattr errors in acl protocol 2013-02-26 02:46:09 -05:00
xdr3.h nfsd: fix encode_entryplus_baggage stack usage 2014-01-23 13:50:27 -05:00
xdr4.h NFSD: Implement the COPY call 2016-10-07 14:54:25 -04:00
xdr4cb.h nfsd: plumb in a CB_NOTIFY_LOCK operation 2016-09-26 15:20:35 -04:00