summaryrefslogtreecommitdiff
path: root/libc/sysdeps/linux/common/waitpid.c
diff options
context:
space:
mode:
authorMike Frysinger <vapier@gentoo.org>2011-02-21 17:19:35 -0500
committerMike Frysinger <vapier@gentoo.org>2011-02-24 08:25:06 -0500
commit7a583ea370974998b4584595b9a4088fc070df1f (patch)
tree61c75c4cd5c9e40e3efb1e35861752aaa1af5596 /libc/sysdeps/linux/common/waitpid.c
parent73d59554144f429b1cf0d4d7fa7de42bdf59ad92 (diff)
linuxthreads.old: fix nommu initial thread stack detection
Because the nommu address space is flat, and the application stack can literally be located anywhere, we cannot rely on the assumptions that the mmu port gets away with. Namely, that the first thread's stack lives at the top of memory and nothing will be created above it. Currently, the code rounds the current stack up a page and sets that as the "top" of the stack, and then marks the "bottom" of the stack as "1". Then as new threads are created, this assumption is further refined by slowly backing off the "bottom" when a new stack is created within the range of the initial stack. Simple ascii example (tid0 is the initial thread): 1 thread: [bos tid0 stack tos] 2 threads: [ tid0 stack ] [tid1 stack] 3 threads: [ tid0 stack ] [tid1 stack] [tid2 stack] As you can kind of see, this algorithm operates on one basic assumption: the initial top of stack calculation is the absolute top of the stack. While this assumption was fairly safe in the original nommu days of yore where the only file format was FLAT (which defaults to a 4KiB stack -- exactly 1 page), and memory was fairly tight, we can see that this falls apart pretty quickly as soon as the initial stack is larger than a page. The issue that crops up now is simple to hit: start an application with an 8KiB stack, execute some functions that put pressure on the stack so that it exceeds 4KiB, then start up some threads. The initial tos will be rounded up by a page, but this is actually the middle of the stack. Now when the initial thread returns from its functions (thus unwinding the stack) and tries to call something which calls back into libpthread, the thread_self() func fails to detect itself as the initial thread as the current stack is now above the tos. The __pthread_find_self() func kicks in, walks all the thread arrays, fails to find a hit, and then walks into uninitialized memory for the thread descriptor. Use of this garbage memory has obvious results -- things fall down & go boom. To address this, I extend the current algorithm to automatically scale back both the bottom and the top stack limits of the initial thread. We use the current stack pointer at "thread boot time" only as a single known point. The initial thread stack bottom is set to the bottom of memory and the initial thread stack top is set to the top of memory. Then as we create new stack threads, we figure out whether the new stack is above or below the single known good address, and then scale back either the tos or the bos accordingly. Reviewed-by: Steven J. Magnani <steve@digidescorp.com> Signed-off-by: Mike Frysinger <vapier@gentoo.org>
Diffstat (limited to 'libc/sysdeps/linux/common/waitpid.c')
0 files changed, 0 insertions, 0 deletions