FreeBSD: Fix translation from ABD to physical pages

In hypothetical case of non-linear ABD with single segment, multiple
to page size but not aligned to it, vdev_geom_fill_unmap_cb() could
fill one page less into bio_ma array.

I am not sure it is exploitable, but better to be safe than sorry.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Ryan Moeller <ryan@iXsystems.com>
Reported-by: Mark Johnston <markj@FreeBSD.org>
Signed-off-by: Alexander Motin <mav@FreeBSD.org>
Closes #13345
This commit is contained in:
Alexander Motin 2022-04-20 19:05:38 -04:00 committed by GitHub
parent e37e7dd6a6
commit 9209ea69bc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -1131,8 +1131,12 @@ vdev_geom_fill_unmap_cb(void *buf, size_t len, void *priv)
vm_offset_t addr = (vm_offset_t)buf; vm_offset_t addr = (vm_offset_t)buf;
vm_offset_t end = addr + len; vm_offset_t end = addr + len;
if (bp->bio_ma_n == 0) if (bp->bio_ma_n == 0) {
bp->bio_ma_offset = addr & PAGE_MASK; bp->bio_ma_offset = addr & PAGE_MASK;
addr &= ~PAGE_MASK;
} else {
ASSERT0(P2PHASE(addr, PAGE_SIZE));
}
do { do {
bp->bio_ma[bp->bio_ma_n++] = bp->bio_ma[bp->bio_ma_n++] =
PHYS_TO_VM_PAGE(pmap_kextract(addr)); PHYS_TO_VM_PAGE(pmap_kextract(addr));