diff options
| author | Mark Johnston <markj@FreeBSD.org> | 2026-06-22 14:40:22 +0000 |
|---|---|---|
| committer | Mark Johnston <markj@FreeBSD.org> | 2026-06-29 19:16:40 +0000 |
| commit | 958de92ab2dc00498681d0ed8b11b2956c317c6d (patch) | |
| tree | bbe4c0b29ac007df5ced2f58ecae16fd0947b97a /sys/vm/vm_object.h | |
| parent | c04ca8bd36f778a8190e5aa3249075929a916dbe (diff) | |
device_pager: Avoid double-insertion of pages into the pager list
Unmanaged device pager objects maintain a linked list of pages that were
returned from the fault handler. Initially, such pages are valid, but
msync(MS_INVALIDATE) can mark them invalid (and clean). They are not
removed from page tables (since they are unmanaged), but a subsequent
mlock() call can trigger a page fault that is handled by the pager.
dev_pager_getpages() then re-inserts the page into the linked list even
though it's already present there.
This patch fixes the problem by removing the linked list. OBJ_PG_DTOR
is set, so vm_object_terminate_pages() does nothing, and
dev_pager_dealloc() instead handles cleanup of the object.
Add a regression test case which triggers a queue.h assertion failure in
unpatched kernels.
Note, in stable branches we should avoid changing the layout of struct
vm_object.
Approved by: so
Security: FreeBSD-SA-26:37.vm
Security: CVE-2026-49418
Reported by: slidybat
Reviewed by: kib
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D57743
Diffstat (limited to 'sys/vm/vm_object.h')
| -rw-r--r-- | sys/vm/vm_object.h | 2 |
1 files changed, 1 insertions, 1 deletions
diff --git a/sys/vm/vm_object.h b/sys/vm/vm_object.h index b056ebe9a4b7..694b9d77a12d 100644 --- a/sys/vm/vm_object.h +++ b/sys/vm/vm_object.h @@ -134,7 +134,7 @@ struct vm_object { * devp_pglist - list of allocated pages */ struct { - TAILQ_HEAD(, vm_page) devp_pglist; + void *spare[2]; const struct cdev_pager_ops *ops; void *handle; } devp; |
