Messages in this thread Patch in this message | | | Date | Thu, 10 Dec 1998 17:25:38 +0000 | From | Jamie Lokier <> | Subject | [PATCH] i386 get_wchan() bugs (fs/proc/array.c) |
| |
Linus, Alan,
This is against 2.1.131, i386. Two buglets:
1. For a newly forked but never scheduled process, whose eip value is ret_from_fork, get_wchan() traverses an incorrect ebp chain, because *esp isn't the saved frame pointer for a new process.
Usually this just returns 0, but it is not guaranteed because the first word on the stack depends on the user-supplied ebx.
The fix makes get_wchan() return the appropriate eip value in a generic way.
2. The comparison ebp >= 8188+stack_page is followed by dereferencing *(ebp+4), which could be off the end of the stack (if everything were misaligned etc.)
It never happens in practice. The patch fixes the comparisons for aesthetic pleasantness.
-- Jamie
--- linux/fs/proc/array.c.devel Sun Dec 6 15:44:03 1998 +++ linux/fs/proc/array.c Thu Dec 10 16:44:27 1998 @@ -494,14 +494,18 @@ unsigned long stack_page; int count = 0; + /* ebp isn't valid for newly created threads, but eip is. */ + eip = p->tss.eip; + if (eip < first_sched || eip >= last_sched) + return eip; stack_page = (unsigned long)p; esp = p->tss.esp; - if (!stack_page || esp < stack_page || esp >= 8188+stack_page) + if (!stack_page || esp < stack_page || esp > 8188+stack_page) return 0; /* include/asm-i386/system.h:switch_to() pushes ebp last. */ ebp = *(unsigned long *) esp; do { - if (ebp < stack_page || ebp >= 8188+stack_page) + if (ebp < stack_page || ebp > 8184+stack_page) return 0; eip = *(unsigned long *) (ebp+4); if (eip < first_sched || eip >= last_sched) - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/
| |