aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Johnston <markj@FreeBSD.org>2023-10-16 20:12:37 +0000
committerMark Johnston <markj@FreeBSD.org>2023-10-24 13:19:01 +0000
commit2d49b111a312469447776e1b68fbea2a644249c8 (patch)
tree6a6456f8d5e35b46ef4c705011ab7cb542d2e7e4
parentf79b01d323c04e5530956ee071faff7b2ec5ec33 (diff)
downloadsrc-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.c6
-rw-r--r--sys/arm/arm/uio_machdep.c6
-rw-r--r--sys/arm64/arm64/uio_machdep.c6
-rw-r--r--sys/i386/i386/uio_machdep.c6
-rw-r--r--sys/kern/subr_uio.c5
-rw-r--r--sys/powerpc/powerpc/uio_machdep.c5
-rw-r--r--sys/riscv/riscv/uio_machdep.c6
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) {