summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkettenis <kettenis@openbsd.org>2010-03-28 18:00:51 +0000
committerkettenis <kettenis@openbsd.org>2010-03-28 18:00:51 +0000
commit032e11043ac47c1b3d13a473edd33d616b7067fa (patch)
tree1b8cb384584368b020750d4d5eece5dd0c9fab6a
parentnew sentence, new line; (diff)
downloadwireguard-openbsd-032e11043ac47c1b3d13a473edd33d616b7067fa.tar.xz
wireguard-openbsd-032e11043ac47c1b3d13a473edd33d616b7067fa.zip
Fix user-after-free bug in pmap_remove(). Page table pages are freed as soon
as the last page table entry that was actually used is cleared. So make sure we check the page table page is still there for every page we remove. Otherwise we will bring back the tlb entry and cache lines when we touch the freed page, and we will create an illegal alias (non-equivalent mapping) as soon as the page gets re-used. Seems to fix the last remaining issue with fast page recycling (although I need to do a bit more testing to be sure). Help from drahn@, ok jsing@ and miod@ (for an earlier version of this diff)
-rw-r--r--sys/arch/hppa/hppa/pmap.c18
1 files changed, 9 insertions, 9 deletions
diff --git a/sys/arch/hppa/hppa/pmap.c b/sys/arch/hppa/hppa/pmap.c
index 500afce5632..5303315aed8 100644
--- a/sys/arch/hppa/hppa/pmap.c
+++ b/sys/arch/hppa/hppa/pmap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pmap.c,v 1.148 2010/03/16 17:12:50 miod Exp $ */
+/* $OpenBSD: pmap.c,v 1.149 2010/03/28 18:00:51 kettenis Exp $ */
/*
* Copyright (c) 1998-2004 Michael Shalayeff
@@ -886,14 +886,14 @@ pmap_remove(pmap, sva, eva)
simple_lock(&pmap->pm_lock);
- for (batch = 0, pdemask = 1; sva < eva; sva += PAGE_SIZE) {
- if (pdemask != (sva & PDE_MASK)) {
- pdemask = sva & PDE_MASK;
- if (!(pde = pmap_pde_get(pmap->pm_pdir, sva))) {
- sva = pdemask + (~PDE_MASK + 1) - PAGE_SIZE;
- continue;
- }
- if (pdemask == sva && sva + (~PDE_MASK + 1) <= eva)
+ for (batch = 0; sva < eva; sva += PAGE_SIZE) {
+ pdemask = sva & PDE_MASK;
+ if (!(pde = pmap_pde_get(pmap->pm_pdir, sva))) {
+ sva = pdemask + (~PDE_MASK + 1) - PAGE_SIZE;
+ continue;
+ }
+ if (pdemask == sva) {
+ if (sva + (~PDE_MASK + 1) <= eva)
batch = 1;
else
batch = 0;