From b7c61cfb62550c7d43de651298659afc478c8581 Mon Sep 17 00:00:00 2001 From: Richard Yao Date: Mon, 21 Sep 2015 19:08:26 -0400 Subject: [PATCH] Userspace can pass zero length segments via writev/readv Userspace can trigger an assertion by passing a zero-length segment when assertions are enabled: [27961.614792] VERIFY3(skip < iov->iov_len) failed (0 < 0) [27961.614795] PANIC at zfs_uio.c:187:uio_prefaultpages() [27961.614796] Showing stack for process 99921 [27961.614798] CPU: 7 PID: 99921 Comm: cmake Tainted: P OE 4.1.3 #2 [27961.614799] Hardware name: Supermicro X10SAE/X10SAE, BIOS 3.0 05/20/2015 [27961.614800] 00000000000000bb ffff8804346838c8 ffffffff815e7d05 0000000000000007 [27961.614802] ffffffffa0a01451 ffff8804346838d8 ffffffffa07f96b4 ffff880434683a68 [27961.614803] ffffffffa07f977b ffff880426e2c600 ffff880426e2c6d0 ffff880400000030 [27961.614805] Call Trace: [27961.614811] [] dump_stack+0x45/0x57 [27961.614830] [] spl_dumpstack+0x44/0x50 [spl] [27961.614834] [] spl_panic+0xbb/0x100 [spl] [27961.614865] [] ? zap_add+0xec/0x1a0 [zfs] [27961.614886] [] ? zfs_link_create+0x38a/0x600 [zfs] [27961.614888] [] ? mutex_lock+0x16/0x40 [27961.614904] [] ? refcount_add_many+0xa1/0x140 [zfs] [27961.614908] [] uio_prefaultpages+0x134/0x140 [zcommon] [27961.614930] [] zfs_write+0x1fd/0xe80 [zfs] [27961.614934] [] ? security_transition_sid+0x2d/0x40 [27961.614950] [] ? rrm_exit+0x50/0xa0 [zfs] [27961.614951] [] ? mutex_lock+0x16/0x40 [27961.614967] [] ? rrm_exit+0x50/0xa0 [zfs] [27961.614988] [] ? zfs_open+0x86/0x120 [zfs] [27961.614990] [] ? inode_to_bdi+0x27/0x60 [27961.614992] [] ? file_ra_state_init+0x19/0x30 [27961.615014] [] zpl_write_common_iovec+0x7f/0x110 [zfs] [27961.615035] [] zpl_iter_write+0xa0/0xd0 [zfs] [27961.615037] [] do_iter_readv_writev+0x59/0x80 [27961.615061] [] ? zpl_read+0xa0/0xa0 [zfs] [27961.615063] [] do_readv_writev+0x11b/0x260 [27961.615093] [] ? zpl_compat_ioctl+0x10/0x10 [zfs] [27961.615096] [] ? putname+0x6f/0x80 [27961.615098] [] vfs_writev+0x39/0x50 [27961.615100] [] SyS_writev+0x4a/0xe0 [27961.615103] [] system_call_fastpath+0x16/0x6e The solution is to delete the assertion. This could potentially occur in uiomove as well, which contains analogous assertions that appear similarly unnecessary, so we remove those as well. Signed-off-by: Richard Yao --- module/zcommon/zfs_uio.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/module/zcommon/zfs_uio.c b/module/zcommon/zfs_uio.c index a5634fca0c05..6037fed80151 100644 --- a/module/zcommon/zfs_uio.c +++ b/module/zcommon/zfs_uio.c @@ -64,8 +64,6 @@ uiomove_iov(void *p, size_t n, enum uio_rw rw, struct uio *uio) size_t skip = uio->uio_skip; ulong_t cnt; - ASSERT3U(skip, <, iov->iov_len); - while (n && uio->uio_resid) { cnt = MIN(iov->iov_len - skip, n); switch (uio->uio_segflg) { @@ -114,8 +112,6 @@ uiomove_bvec(void *p, size_t n, enum uio_rw rw, struct uio *uio) size_t skip = uio->uio_skip; ulong_t cnt; - ASSERT3U(skip, <, bv->bv_len); - while (n && uio->uio_resid) { void *paddr; cnt = MIN(bv->bv_len - skip, n); @@ -184,7 +180,6 @@ uio_prefaultpages(ssize_t n, struct uio *uio) iov = uio->uio_iov; iovcnt = uio->uio_iovcnt; - ASSERT3U(skip, <, iov->iov_len); while ((n > 0) && (iovcnt > 0)) { cnt = MIN(iov->iov_len - skip, n);