diff options
author | Richard Yao <[email protected]> | 2015-09-21 19:08:26 -0400 |
---|---|---|
committer | Brian Behlendorf <[email protected]> | 2015-09-25 12:51:16 -0700 |
commit | b815ec32b3ba04ad7307ca8945a865eec0ec766b (patch) | |
tree | 95ae699a9aff7153da1236022660758e67b6861d /module | |
parent | a3000f9358159d761bdf59bd1c4d318f7ec71815 (diff) |
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.614805] Call Trace:
[27961.614811] dump_stack+0x45/0x57
[27961.614830] spl_dumpstack+0x44/0x50 [spl]
[27961.614834] spl_panic+0xbb/0x100 [spl]
[27961.614908] uio_prefaultpages+0x134/0x140 [zcommon]
[27961.614930] zfs_write+0x1fd/0xe80 [zfs]
[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.615063] do_readv_writev+0x11b/0x260
[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.
Reported-by: Jonathan Vasquez <[email protected]>
Signed-off-by: Brian Behlendorf <[email protected]>
Signed-off-by: Richard Yao <[email protected]>
Issue #3792
Diffstat (limited to 'module')
-rw-r--r-- | module/zcommon/zfs_uio.c | 5 |
1 files changed, 0 insertions, 5 deletions
diff --git a/module/zcommon/zfs_uio.c b/module/zcommon/zfs_uio.c index a5634fca0..6037fed80 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); |