From 9209ea69bc03e7e9f678b2294da7a0317b5c9c5b Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Wed, 20 Apr 2022 19:05:38 -0400 Subject: [PATCH] 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 Reviewed-by: Ryan Moeller Reported-by: Mark Johnston Signed-off-by: Alexander Motin Closes #13345 --- module/os/freebsd/zfs/vdev_geom.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/module/os/freebsd/zfs/vdev_geom.c b/module/os/freebsd/zfs/vdev_geom.c index 914e0e6ded..1ac41f616a 100644 --- a/module/os/freebsd/zfs/vdev_geom.c +++ b/module/os/freebsd/zfs/vdev_geom.c @@ -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 end = addr + len; - if (bp->bio_ma_n == 0) + if (bp->bio_ma_n == 0) { bp->bio_ma_offset = addr & PAGE_MASK; + addr &= ~PAGE_MASK; + } else { + ASSERT0(P2PHASE(addr, PAGE_SIZE)); + } do { bp->bio_ma[bp->bio_ma_n++] = PHYS_TO_VM_PAGE(pmap_kextract(addr));