Date: Mon, 8 Jul 2024 14:52:35 GMT From: Mitchell Horne <mhorne@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org Subject: git: 558c1b37334c - main - busdma: avoid buflen underflow Message-ID: <202407081452.468EqZWf046714@gitrepo.freebsd.org>
next in thread | raw e-mail | index | archive | help
The branch main has been updated by mhorne: URL: https://cgit.FreeBSD.org/src/commit/?id=558c1b37334c4dcc9913b7c157a491f9d244e335 commit 558c1b37334c4dcc9913b7c157a491f9d244e335 Author: Mitchell Horne <mhorne@FreeBSD.org> AuthorDate: 2024-07-08 14:51:31 +0000 Commit: Mitchell Horne <mhorne@FreeBSD.org> CommitDate: 2024-07-08 14:51:31 +0000 busdma: avoid buflen underflow The loop condition in the dmamap_load_buffer() method is 'buflen > 0', and buflen is an unsigned type (bus_size_t). A recent change made it possible for sgsize to exceed the remaining buflen, when the tag has a large alignment requirement. The result is that we would not break out of the loop at the correct time. Fix this by avoiding underflow in the subtraction at the end of the loop. PR: 279383 Reported by: Robert Morris <rtm@lcs.mit.edu> Reviewed by: jhibbits Fixes: a77e1f0f81df ("busdma: better handling of small segment bouncing") Differential Revision: https://reviews.freebsd.org/D45732 --- sys/arm/arm/busdma_machdep.c | 2 +- sys/arm64/arm64/busdma_bounce.c | 2 +- sys/powerpc/powerpc/busdma_machdep.c | 2 +- sys/riscv/riscv/busdma_bounce.c | 2 +- sys/x86/x86/busdma_bounce.c | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/sys/arm/arm/busdma_machdep.c b/sys/arm/arm/busdma_machdep.c index 13af7eb682d6..99a72c9e79d0 100644 --- a/sys/arm/arm/busdma_machdep.c +++ b/sys/arm/arm/busdma_machdep.c @@ -1035,7 +1035,7 @@ _bus_dmamap_load_buffer(bus_dma_tag_t dmat, bus_dmamap_t map, void *buf, segp)) break; vaddr += sgsize; - buflen -= sgsize; + buflen -= MIN(sgsize, buflen); /* avoid underflow */ } cleanup: diff --git a/sys/arm64/arm64/busdma_bounce.c b/sys/arm64/arm64/busdma_bounce.c index f218bc062642..3836f8c74b45 100644 --- a/sys/arm64/arm64/busdma_bounce.c +++ b/sys/arm64/arm64/busdma_bounce.c @@ -898,7 +898,7 @@ bounce_bus_dmamap_load_buffer(bus_dma_tag_t dmat, bus_dmamap_t map, void *buf, segp)) break; vaddr += sgsize; - buflen -= sgsize; + buflen -= MIN(sgsize, buflen); /* avoid underflow */ } /* diff --git a/sys/powerpc/powerpc/busdma_machdep.c b/sys/powerpc/powerpc/busdma_machdep.c index b023e7f353b9..5f7f88041a67 100644 --- a/sys/powerpc/powerpc/busdma_machdep.c +++ b/sys/powerpc/powerpc/busdma_machdep.c @@ -656,7 +656,7 @@ _bus_dmamap_load_buffer(bus_dma_tag_t dmat, segp)) break; vaddr += sgsize; - buflen -= sgsize; + buflen -= MIN(sgsize, buflen); /* avoid underflow */ } /* diff --git a/sys/riscv/riscv/busdma_bounce.c b/sys/riscv/riscv/busdma_bounce.c index e1c217f1d12e..68525bb742bc 100644 --- a/sys/riscv/riscv/busdma_bounce.c +++ b/sys/riscv/riscv/busdma_bounce.c @@ -705,7 +705,7 @@ bounce_bus_dmamap_load_buffer(bus_dma_tag_t dmat, bus_dmamap_t map, void *buf, segp)) break; vaddr += sgsize; - buflen -= sgsize; + buflen -= MIN(sgsize, buflen); /* avoid underflow */ } cleanup: diff --git a/sys/x86/x86/busdma_bounce.c b/sys/x86/x86/busdma_bounce.c index 5aa4ffcff3cc..656b76159250 100644 --- a/sys/x86/x86/busdma_bounce.c +++ b/sys/x86/x86/busdma_bounce.c @@ -733,7 +733,7 @@ bounce_bus_dmamap_load_buffer(bus_dma_tag_t dmat, bus_dmamap_t map, void *buf, segp)) break; vaddr += sgsize; - buflen -= sgsize; + buflen -= MIN(sgsize, buflen); /* avoid underflow */ } /* @@ -808,7 +808,7 @@ bounce_bus_dmamap_load_ma(bus_dma_tag_t dmat, bus_dmamap_t map, break; KASSERT(buflen >= sgsize, ("Segment length overruns original buffer")); - buflen -= sgsize; + buflen -= MIN(sgsize, buflen); /* avoid underflow */ if (((ma_offs + sgsize) & ~PAGE_MASK) != 0) page_index++; ma_offs = (ma_offs + sgsize) & PAGE_MASK;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202407081452.468EqZWf046714>