--- 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); }