diff options
author | Mark Johnston <markj@FreeBSD.org> | 2023-10-16 20:12:37 +0000 |
---|---|---|
committer | Mark Johnston <markj@FreeBSD.org> | 2023-10-24 13:19:01 +0000 |
commit | 2d49b111a312469447776e1b68fbea2a644249c8 (patch) | |
tree | 6a6456f8d5e35b46ef4c705011ab7cb542d2e7e4 | |
parent | f79b01d323c04e5530956ee071faff7b2ec5ec33 (diff) | |
download | src-2d49b111a312469447776e1b68fbea2a644249c8.tar.gz src-2d49b111a312469447776e1b68fbea2a644249c8.zip |
uiomove: Add some assertions
Make sure that we don't try to copy with a negative resid.
Make sure that we don't walk off the end of the iovec array.
Reviewed by: kib
MFC after: 1 week
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D42098
(cherry picked from commit 8fd0ec53deaad34383d4b344714b74d67105b258)
-rw-r--r-- | sys/amd64/amd64/uio_machdep.c | 6 | ||||
-rw-r--r-- | sys/arm/arm/uio_machdep.c | 6 | ||||
-rw-r--r-- | sys/arm64/arm64/uio_machdep.c | 6 | ||||
-rw-r--r-- | sys/i386/i386/uio_machdep.c | 6 | ||||
-rw-r--r-- | sys/kern/subr_uio.c | 5 | ||||
-rw-r--r-- | sys/powerpc/powerpc/uio_machdep.c | 5 | ||||
-rw-r--r-- | sys/riscv/riscv/uio_machdep.c | 6 |
7 files changed, 40 insertions, 0 deletions
diff --git a/sys/amd64/amd64/uio_machdep.c b/sys/amd64/amd64/uio_machdep.c index f3e80addc92c..67e14d8e0d12 100644 --- a/sys/amd64/amd64/uio_machdep.c +++ b/sys/amd64/amd64/uio_machdep.c @@ -71,10 +71,16 @@ uiomove_fromphys(vm_page_t ma[], vm_offset_t offset, int n, struct uio *uio) ("uiomove_fromphys: mode")); KASSERT(uio->uio_segflg != UIO_USERSPACE || uio->uio_td == curthread, ("uiomove_fromphys proc")); + KASSERT(uio->uio_resid >= 0, + ("%s: uio %p resid underflow", __func__, uio)); + save = td->td_pflags & TDP_DEADLKTREAT; td->td_pflags |= TDP_DEADLKTREAT; mapped = false; while (n > 0 && uio->uio_resid) { + KASSERT(uio->uio_iovcnt > 0, + ("%s: uio %p iovcnt underflow", __func__, uio)); + iov = uio->uio_iov; cnt = iov->iov_len; if (cnt == 0) { diff --git a/sys/arm/arm/uio_machdep.c b/sys/arm/arm/uio_machdep.c index 07531f76217b..18661ebd1652 100644 --- a/sys/arm/arm/uio_machdep.c +++ b/sys/arm/arm/uio_machdep.c @@ -72,9 +72,15 @@ uiomove_fromphys(vm_page_t ma[], vm_offset_t offset, int n, struct uio *uio) ("uiomove_fromphys: mode")); KASSERT(uio->uio_segflg != UIO_USERSPACE || uio->uio_td == curthread, ("uiomove_fromphys proc")); + KASSERT(uio->uio_resid >= 0, + ("%s: uio %p resid underflow", __func__, uio)); + save = td->td_pflags & TDP_DEADLKTREAT; td->td_pflags |= TDP_DEADLKTREAT; while (n > 0 && uio->uio_resid) { + KASSERT(uio->uio_iovcnt > 0, + ("%s: uio %p iovcnt underflow", __func__, uio)); + iov = uio->uio_iov; cnt = iov->iov_len; if (cnt == 0) { diff --git a/sys/arm64/arm64/uio_machdep.c b/sys/arm64/arm64/uio_machdep.c index f9e4e7a9547f..4fdcaf74890c 100644 --- a/sys/arm64/arm64/uio_machdep.c +++ b/sys/arm64/arm64/uio_machdep.c @@ -69,10 +69,16 @@ uiomove_fromphys(vm_page_t ma[], vm_offset_t offset, int n, struct uio *uio) ("uiomove_fromphys: mode")); KASSERT(uio->uio_segflg != UIO_USERSPACE || uio->uio_td == curthread, ("uiomove_fromphys proc")); + KASSERT(uio->uio_resid >= 0, + ("%s: uio %p resid underflow", __func__, uio)); + save = td->td_pflags & TDP_DEADLKTREAT; td->td_pflags |= TDP_DEADLKTREAT; mapped = false; while (n > 0 && uio->uio_resid) { + KASSERT(uio->uio_iovcnt > 0, + ("%s: uio %p iovcnt underflow", __func__, uio)); + iov = uio->uio_iov; cnt = iov->iov_len; if (cnt == 0) { diff --git a/sys/i386/i386/uio_machdep.c b/sys/i386/i386/uio_machdep.c index 07d71eac5db6..92e067b35bed 100644 --- a/sys/i386/i386/uio_machdep.c +++ b/sys/i386/i386/uio_machdep.c @@ -71,9 +71,15 @@ uiomove_fromphys(vm_page_t ma[], vm_offset_t offset, int n, struct uio *uio) ("uiomove_fromphys: mode")); KASSERT(uio->uio_segflg != UIO_USERSPACE || uio->uio_td == curthread, ("uiomove_fromphys proc")); + KASSERT(uio->uio_resid >= 0, + ("%s: uio %p resid underflow", __func__, uio)); + save = td->td_pflags & TDP_DEADLKTREAT; td->td_pflags |= TDP_DEADLKTREAT; while (n > 0 && uio->uio_resid) { + KASSERT(uio->uio_iovcnt > 0, + ("%s: uio %p iovcnt underflow", __func__, uio)); + iov = uio->uio_iov; cnt = iov->iov_len; if (cnt == 0) { diff --git a/sys/kern/subr_uio.c b/sys/kern/subr_uio.c index 21a1f044db54..b0c4a256cd17 100644 --- a/sys/kern/subr_uio.c +++ b/sys/kern/subr_uio.c @@ -216,6 +216,8 @@ uiomove_faultflag(void *cp, int n, struct uio *uio, int nofault) ("uiomove: mode")); KASSERT(uio->uio_segflg != UIO_USERSPACE || uio->uio_td == curthread, ("uiomove proc")); + KASSERT(uio->uio_resid >= 0, + ("%s: uio %p resid underflow", __func__, uio)); if (uio->uio_segflg == UIO_USERSPACE) { newflags = TDP_DEADLKTREAT; @@ -234,6 +236,9 @@ uiomove_faultflag(void *cp, int n, struct uio *uio, int nofault) } while (n > 0 && uio->uio_resid) { + KASSERT(uio->uio_iovcnt > 0, + ("%s: uio %p iovcnt underflow", __func__, uio)); + iov = uio->uio_iov; cnt = iov->iov_len; if (cnt == 0) { diff --git a/sys/powerpc/powerpc/uio_machdep.c b/sys/powerpc/powerpc/uio_machdep.c index 679139a96e99..5de2dd8b416b 100644 --- a/sys/powerpc/powerpc/uio_machdep.c +++ b/sys/powerpc/powerpc/uio_machdep.c @@ -75,10 +75,15 @@ uiomove_fromphys(vm_page_t ma[], vm_offset_t offset, int n, struct uio *uio) ("uiomove_fromphys: mode")); KASSERT(uio->uio_segflg != UIO_USERSPACE || uio->uio_td == curthread, ("uiomove_fromphys proc")); + KASSERT(uio->uio_resid >= 0, + ("%s: uio %p resid underflow", __func__, uio)); save = td->td_pflags & TDP_DEADLKTREAT; td->td_pflags |= TDP_DEADLKTREAT; while (n > 0 && uio->uio_resid) { + KASSERT(uio->uio_iovcnt > 0, + ("%s: uio %p iovcnt underflow", __func__, uio)); + iov = uio->uio_iov; cnt = iov->iov_len; if (cnt == 0) { diff --git a/sys/riscv/riscv/uio_machdep.c b/sys/riscv/riscv/uio_machdep.c index 86a39be12cdb..e2f82974b2e9 100644 --- a/sys/riscv/riscv/uio_machdep.c +++ b/sys/riscv/riscv/uio_machdep.c @@ -69,10 +69,16 @@ uiomove_fromphys(vm_page_t ma[], vm_offset_t offset, int n, struct uio *uio) ("uiomove_fromphys: mode")); KASSERT(uio->uio_segflg != UIO_USERSPACE || uio->uio_td == curthread, ("uiomove_fromphys proc")); + KASSERT(uio->uio_resid >= 0, + ("%s: uio %p resid underflow", __func__, uio)); + save = td->td_pflags & TDP_DEADLKTREAT; td->td_pflags |= TDP_DEADLKTREAT; mapped = false; while (n > 0 && uio->uio_resid) { + KASSERT(uio->uio_iovcnt > 0, + ("%s: uio %p iovcnt underflow", __func__, uio)); + iov = uio->uio_iov; cnt = iov->iov_len; if (cnt == 0) { |