On 02/17/2011 05:42 PM, Lauri T. Aarnio wrote:
On Feb 16, 2011, at 6:53 PM, ext Karol Lewandowski wrote:
It looks like bash's malloc() is to blame - it relies on false
assumption that memory after sbrk(0) is free to use. However, dynamic
linker uses mmap() to allocate memory for its data before bash is run.
For these requests kernel usually returns addresses that are
sbrk(0)+getpagesize() (with ASLR disabled this seems be always true).
Dynamic linker succeeds to allocate memory, but when bash is run it
dies in pain as it can't extend its data segment.
Recompiling bash with --without-bash-malloc (or killing /bin/bash
altogether) seems to magically solve this issue.
For some unknown reason Debian provides packages with bash using its
internal malloc implementation. I'll file bug against it.
That is bad, really bad. Having a common, old, widely used program which
relies on a false assumption means that that false assumption has now
practically turned to a requirement. Which isn't met anymore.
Actually I think there is something fishy going on somewhere.
I think it might be make, bash, dynamic linker, kernel (exactly in that
order). Sadly, I'm not sure which component is to blame for this problem.
From my understanding the problem we observe might occur when one
incorrectly sets RLIMIT_DATA to the size of sbrk(0). In this situation
kernel correctly returns mmap() addresses that are just after sbrk(0).
I guess that doing setrlimit(RLIMIT_DATA,
"infinity-or-some-large-number") just before exec() would provide
sensible workaround.
Here is idea - because we run run dynamic linker by ourself we inherit
RLIMIT_DATA (along with all other limits) from the parent process. This
*isn't* true when kernel invokes dynamic linker via it's own ELF loader,
right? Shouldn't we reset all the limits to some sane defaults just
before exec?
What do you think about this?
(I'm aware that this might be a bit tricky. ;)
Honestly, I've hard time believing that brk(2) isn't supported anymore.
(I mean - now - after I've got some sleep I think blaming bash was a bit
too fast).
Sadly, I don't have little time right now to investigate this issue
properly.
Even if bash is now recompiled by debian, it still leaves countless
amount of installation where the bug exists in binaries. Binaries that
happen to work magically outside of sb2, but fail when executed with sb2.
All this makes it look like the problem was in sb2 (another false
assumption), and that is what worries me now. Especially because it
wasn't too easy to find this out, was it?
This issue hunts us for several months now. No, it isn't obvious nor
easy to find. Specifically, to find _real_ culprit.
And there may even be other
programs that use similar memory allocation practices & requirements.
I'd guess that no one wants to analyze those one-by-one, if these kind
of problems start to appear in a different context someday.
This is the question right now - is it possible that brk(2)
sematics/guaratess aren't preserved anymore? I think answer to this
question is no, but I don't have anything to back it up (right now!).
Fortunately the fix is easy, at least in theory. And it wouldn't be the
first time when sb2 is used to fix somebody else's problems:
Probably we should replace brk() and sbrk() completely. For example, by
introducing new versions that do not use the brk syscall, but instead
mmap() a block of anonymous memory, and then let applications reserve
memory from there.
I did some prototyping today and found out that this is not as
straightforward as it sounds. glibc uses sbrk internally, and sbrk is a
weak alias there, which means for example that strdup() instantly ends
up calling our version of sbrk... Trying to add a simple wrapper for brk
and sbrk failed because of that. So compatibility with glibc needs to be
taken into account, and it will very probably cause some additional pain
before this feature can be finalized.
Conclusion was that more work is needed to solve the remaining issues.
Unfortunately it seems that I don't have time to continue with this in
the near future, maybe later..
Lauri
PS. It seems that "interesting" memory management practices have been
common in shells; See this paper about the original Bourne shell:
http://www.collyer.net/who/geoff/sh.tour.ps
Thanks for the link - it really makes interesting read. I weren't aware
that shells are special wrt memory management. :)
Thanks!
--
Karol Lewandowski | Samsung Poland R&D Center | Linux/Platform
_______________________________________________
Scratchbox-devel mailing list
[email protected]
http://lists.scratchbox.org/cgi-bin/mailman/listinfo/scratchbox-devel