git: 517c5854588e - main - vm_phys: Make sure that vm_phys_enq_chunk() stays in bounds

From: Mark Johnston <markj_at_FreeBSD.org>
Date: Fri, 14 Jun 2024 19:55:28 UTC
The branch main has been updated by markj:

URL: https://cgit.FreeBSD.org/src/commit/?id=517c5854588eaa7c2248d97cd750b8b8bad9d69f

commit 517c5854588eaa7c2248d97cd750b8b8bad9d69f
Author:     Mark Johnston <markj@FreeBSD.org>
AuthorDate: 2024-06-14 14:45:02 +0000
Commit:     Mark Johnston <markj@FreeBSD.org>
CommitDate: 2024-06-14 19:55:02 +0000

    vm_phys: Make sure that vm_phys_enq_chunk() stays in bounds
    
    vm_phys_enq_chunk() inserts a run of pages into the buddy queues.  When
    lazy initialization is enabled, only the first page of each run is
    initialized; vm_phys_enq_chunk() thus initializes the page following the
    just-inserted run.
    
    This fails to account for the possibility that the page following the
    run doesn't belong to the segment.  Handle that in vm_phys_enq_chunk().
    
    Reported by:    KASAN
    Reported by:    syzbot+1097ef4cee8dfb240e31@syzkaller.appspotmail.com
    Fixes:  b16b4c22d2d1 ("vm_page: Implement lazy page initialization")
---
 sys/vm/vm_phys.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/sys/vm/vm_phys.c b/sys/vm/vm_phys.c
index 53e58283eb9f..59ab7d13c55d 100644
--- a/sys/vm/vm_phys.c
+++ b/sys/vm/vm_phys.c
@@ -711,12 +711,16 @@ vm_phys_enq_chunk(struct vm_freelist *fl, vm_page_t m, int order, int tail)
 #ifdef VM_FREEPOOL_LAZYINIT
 	if (__predict_false(m->pool == VM_FREEPOOL_LAZYINIT)) {
 		vm_page_t m_next;
+		vm_paddr_t pa;
 		int npages;
 
 		npages = 1 << order;
 		m_next = m + npages;
-		vm_page_init_page(m_next, m->phys_addr + ptoa(npages), m->segind,
-		    VM_FREEPOOL_LAZYINIT);
+		pa = m->phys_addr + ptoa(npages);
+		if (pa < vm_phys_segs[m->segind].end) {
+			vm_page_init_page(m_next, pa, m->segind,
+			    VM_FREEPOOL_LAZYINIT);
+		}
 	}
 #endif
 }