Fix uio_prefaultpages for 0 length iovec
Userspace can freely pass in whatever iovec it feels like, and it's perfectly legal to pass an iovec which contains a zero length segment. In the current implementation, uio_prefaultpages would touch an out of bound byte in the "last byte" logic. While this probably wouldn't cause any critical error, we would like uio_prefaultpages to be able to continue gracefully. Signed-off-by: Chunwei Chen <david.chen@osnexus.com> Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov> Closes #4078
This commit is contained in:
parent
eba9e745dc
commit
502923bb44
|
@ -164,7 +164,7 @@ uio_prefaultpages(ssize_t n, struct uio *uio)
|
|||
caddr_t p;
|
||||
uint8_t tmp;
|
||||
int iovcnt;
|
||||
size_t skip = uio->uio_skip;
|
||||
size_t skip;
|
||||
|
||||
/* no need to fault in kernel pages */
|
||||
switch (uio->uio_segflg) {
|
||||
|
@ -180,9 +180,13 @@ uio_prefaultpages(ssize_t n, struct uio *uio)
|
|||
|
||||
iov = uio->uio_iov;
|
||||
iovcnt = uio->uio_iovcnt;
|
||||
skip = uio->uio_skip;
|
||||
|
||||
while ((n > 0) && (iovcnt > 0)) {
|
||||
for (; n > 0 && iovcnt > 0; iov++, iovcnt--, skip = 0) {
|
||||
cnt = MIN(iov->iov_len - skip, n);
|
||||
/* empty iov */
|
||||
if (cnt == 0)
|
||||
continue;
|
||||
n -= cnt;
|
||||
/*
|
||||
* touch each page in this segment.
|
||||
|
@ -201,9 +205,6 @@ uio_prefaultpages(ssize_t n, struct uio *uio)
|
|||
p--;
|
||||
if (fuword8((uint8_t *) p, &tmp))
|
||||
return;
|
||||
iov++;
|
||||
iovcnt--;
|
||||
skip = 0;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(uio_prefaultpages);
|
||||
|
|
Loading…
Reference in New Issue