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 <jvasquez1011@gmail.com> Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov> Signed-off-by: Richard Yao <ryao@gentoo.org> Issue #3792
This commit is contained in:
parent
13e3c4be75
commit
c9e237a7b2
|
@ -64,8 +64,6 @@ uiomove_iov(void *p, size_t n, enum uio_rw rw, struct uio *uio)
|
||||||
size_t skip = uio->uio_skip;
|
size_t skip = uio->uio_skip;
|
||||||
ulong_t cnt;
|
ulong_t cnt;
|
||||||
|
|
||||||
ASSERT3U(skip, <, iov->iov_len);
|
|
||||||
|
|
||||||
while (n && uio->uio_resid) {
|
while (n && uio->uio_resid) {
|
||||||
cnt = MIN(iov->iov_len - skip, n);
|
cnt = MIN(iov->iov_len - skip, n);
|
||||||
switch (uio->uio_segflg) {
|
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;
|
size_t skip = uio->uio_skip;
|
||||||
ulong_t cnt;
|
ulong_t cnt;
|
||||||
|
|
||||||
ASSERT3U(skip, <, bv->bv_len);
|
|
||||||
|
|
||||||
while (n && uio->uio_resid) {
|
while (n && uio->uio_resid) {
|
||||||
void *paddr;
|
void *paddr;
|
||||||
cnt = MIN(bv->bv_len - skip, n);
|
cnt = MIN(bv->bv_len - skip, n);
|
||||||
|
@ -184,7 +180,6 @@ uio_prefaultpages(ssize_t n, struct uio *uio)
|
||||||
|
|
||||||
iov = uio->uio_iov;
|
iov = uio->uio_iov;
|
||||||
iovcnt = uio->uio_iovcnt;
|
iovcnt = uio->uio_iovcnt;
|
||||||
ASSERT3U(skip, <, iov->iov_len);
|
|
||||||
|
|
||||||
while ((n > 0) && (iovcnt > 0)) {
|
while ((n > 0) && (iovcnt > 0)) {
|
||||||
cnt = MIN(iov->iov_len - skip, n);
|
cnt = MIN(iov->iov_len - skip, n);
|
||||||
|
|
Loading…
Reference in New Issue