mirror of
https://git.hardenedbsd.org/hardenedbsd/HardenedBSD.git
synced 2024-11-22 03:04:34 +01:00
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: a77e1f0f81
("busdma: better handling of small segment bouncing")
Differential Revision: https://reviews.freebsd.org/D45732
This commit is contained in:
parent
4e148a7baa
commit
558c1b3733
@ -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:
|
||||
|
@ -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 */
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -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 */
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user