⬢ DragonFlyBSD Kernel Audit
DF-5665 / fix.diff
← back to finding ↓ download raw
--- a/sys/cpu/x86_64/misc/ktr.c
+++ b/sys/cpu/x86_64/misc/ktr.c
@@ -64,8 +64,20 @@
     void **newframeptr;
 
     newframeptr = (void **)frameptr[0];
+    /*
+     * Accept the next frame only when it is (1) within ~16KB of the
+     * current frame, (2) strictly above the current frame, and
+     * (3) 8-byte aligned.  Genuine x86-64 frame chains always grow
+     * upwards; requiring monotonic upward progress keeps a stale or
+     * corrupted saved %rbp from walking the chain sideways/downwards
+     * into an unrelated (possibly unmapped) region inside the
+     * acceptance window.
+     */
     if (((uintptr_t)newframeptr ^ (uintptr_t)frameptr) & ~16383ULL)
 	newframeptr = frameptr;
+    else if ((uintptr_t)newframeptr <= (uintptr_t)frameptr ||
+	     ((uintptr_t)newframeptr & 7) != 0)
+	newframeptr = frameptr;
     return(newframeptr);
 }