The branch main has been updated by markj: URL: https://cgit.FreeBSD.org/src/commit/?id=982693bb729badac4e65ecd59772979f2849a2b2
commit 982693bb729badac4e65ecd59772979f2849a2b2 Author: Mark Johnston <ma...@freebsd.org> AuthorDate: 2021-03-15 20:02:17 +0000 Commit: Mark Johnston <ma...@freebsd.org> CommitDate: 2021-04-06 18:49:28 +0000 vm_fault: Shoot down multiply mapped COW source page mappings Reviewed by: kib, rlibby Discussed with: alc Approved by: so Security: CVE-2021-29626 Security: FreeBSD-SA-21:08.vm --- sys/vm/vm_fault.c | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/sys/vm/vm_fault.c b/sys/vm/vm_fault.c index dd112feefdcd..c9f3cdf2e4f6 100644 --- a/sys/vm/vm_fault.c +++ b/sys/vm/vm_fault.c @@ -900,6 +900,9 @@ vm_fault_cow(struct faultstate *fs) { bool is_first_object_locked; + KASSERT(fs->object != fs->first_object, + ("source and target COW objects are identical")); + /* * This allows pages to be virtually copied from a backing_object * into the first_object, where the backing object has no other @@ -963,11 +966,29 @@ vm_fault_cow(struct faultstate *fs) */ fs->m_cow = fs->m; fs->m = NULL; + + /* + * Typically, the shadow object is either private to this + * address space (OBJ_ONEMAPPING) or its pages are read only. + * In the highly unusual case where the pages of a shadow object + * are read/write shared between this and other address spaces, + * we need to ensure that any pmap-level mappings to the + * original, copy-on-write page from the backing object are + * removed from those other address spaces. + * + * The flag check is racy, but this is tolerable: if + * OBJ_ONEMAPPING is cleared after the check, the busy state + * ensures that new mappings of m_cow can't be created. + * pmap_enter() will replace an existing mapping in the current + * address space. If OBJ_ONEMAPPING is set after the check, + * removing mappings will at worse trigger some unnecessary page + * faults. + */ + vm_page_assert_xbusied(fs->m_cow); + if ((fs->first_object->flags & OBJ_ONEMAPPING) == 0) + pmap_remove_all(fs->m_cow); } - /* - * fs->object != fs->first_object due to above - * conditional - */ + vm_object_pip_wakeup(fs->object); /* _______________________________________________ dev-commits-src-main@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/dev-commits-src-main To unsubscribe, send any mail to "dev-commits-src-main-unsubscr...@freebsd.org"