iovec_import() has a safer calling convention than import_iovec(). Signed-off-by: David Laight <david.laight@xxxxxxxxxx> --- mm/process_vm_access.c | 81 ++++++++++++++++++++++-------------------- 1 file changed, 42 insertions(+), 39 deletions(-) diff --git a/mm/process_vm_access.c b/mm/process_vm_access.c index 1cc3d6f66b31..048637944d47 100644 --- a/mm/process_vm_access.c +++ b/mm/process_vm_access.c @@ -260,10 +260,10 @@ static ssize_t process_vm_rw(pid_t pid, unsigned long riovcnt, unsigned long flags, int vm_write) { - struct iovec iovstack_l[UIO_FASTIOV]; - struct iovec iovstack_r[UIO_FASTIOV]; - struct iovec *iov_l = iovstack_l; - struct iovec *iov_r = iovstack_r; + struct iovec_cache cache_l; + struct iovec_cache cache_r; + struct iovec *iov_l; + struct iovec *iov_r; struct iov_iter iter_l, iter_r; ssize_t rc; int dir = vm_write ? WRITE : READ; @@ -272,24 +272,25 @@ static ssize_t process_vm_rw(pid_t pid, return -EINVAL; /* Check iovecs */ - rc = import_iovec(dir, lvec, liovcnt, UIO_FASTIOV, &iov_l, &iter_l); - if (rc < 0) - return rc; - if (!iov_iter_count(&iter_l)) - goto free_iovecs; - - rc = import_iovec(CHECK_IOVEC_ONLY, rvec, riovcnt, UIO_FASTIOV, &iov_r, &iter_r); - if (rc <= 0) - goto free_iovecs; - - rc = process_vm_rw_core(pid, &iter_l, iter_r.iov, iter_r.nr_segs, - flags, vm_write); + iov_l = iovec_import(dir, lvec, liovcnt, &cache_l, &iter_l); + if (IS_ERR(iov_l)) + return PTR_ERR(iov_l); + if (!iov_iter_count(&iter_l)) { + rc = 0; + goto free_iovec_l; + } -free_iovecs: - if (iov_r != iovstack_r) + iov_r = iovec_import(CHECK_IOVEC_ONLY, rvec, riovcnt, &cache_r, &iter_r); + if (IS_ERR(iov_r)) { + rc = PTR_ERR(iov_r); + } else { + rc = process_vm_rw_core(pid, &iter_l, iter_r.iov, + iter_r.nr_segs, flags, vm_write); kfree(iov_r); - if (iov_l != iovstack_l) - kfree(iov_l); + } + +free_iovec_l: + kfree(iov_l); return rc; } @@ -319,10 +320,10 @@ compat_process_vm_rw(compat_pid_t pid, unsigned long riovcnt, unsigned long flags, int vm_write) { - struct iovec iovstack_l[UIO_FASTIOV]; - struct iovec iovstack_r[UIO_FASTIOV]; - struct iovec *iov_l = iovstack_l; - struct iovec *iov_r = iovstack_r; + struct iovec_cache cache_l; + struct iovec_cache cache_r; + struct iovec *iov_l; + struct iovec *iov_r; struct iov_iter iter_l, iter_r; ssize_t rc = -EFAULT; int dir = vm_write ? WRITE : READ; @@ -330,23 +331,25 @@ compat_process_vm_rw(compat_pid_t pid, if (flags != 0) return -EINVAL; - rc = compat_import_iovec(dir, lvec, liovcnt, UIO_FASTIOV, &iov_l, &iter_l); - if (rc < 0) - return rc; - if (!iov_iter_count(&iter_l)) - goto free_iovecs; - rc = compat_import_iovec(0, rvec, riovcnt, UIO_FASTIOV, &iov_r, &iter_r); - if (rc <= 0) - goto free_iovecs; - - rc = process_vm_rw_core(pid, &iter_l, iter_r.iov, iter_r.nr_segs, - flags, vm_write); + iov_l = compat_iovec_import(dir, lvec, liovcnt, &cache_l, &iter_l); + if (IS_ERR(iov_l)) + return PTR_ERR(iov_l); + if (!iov_iter_count(&iter_l)) { + rc = 0; + goto free_iovec_l; + } -free_iovecs: - if (iov_r != iovstack_r) + iov_r = compat_iovec_import(0, rvec, riovcnt, &cache_r, &iter_r); + if (IS_ERR(iov_r)) { + rc = PTR_ERR(iov_r); + } else { + rc = process_vm_rw_core(pid, &iter_l, iter_r.iov, + iter_r.nr_segs, flags, vm_write); kfree(iov_r); - if (iov_l != iovstack_l) - kfree(iov_l); + } + +free_iovec_l: + kfree(iov_l); return rc; } -- 2.25.1 - Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK Registration No: 1397386 (Wales)