[PATCH] i386 get_wchan() bugs (fs/proc/array.c)

Jamie Lokier (lkd@tantalophile.demon.co.uk)
Thu, 10 Dec 1998 17:25:38 +0000


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/