[uClibc]BusyBox `msh' doesn't work correctly with vfork / uClibc

Miles Bader miles at lsi.nec.co.jp
Fri Mar 1 07:34:24 UTC 2002


[I tried to find an address for the busybox mailing list, but couldn't
 find it anywhere in the READMEs or on the web-site ... even though the
 website points to the mailing-list archives, the list info page is a
 broken link, and all the messages in the archive have conveniently had
 their To: addresses removed!]

I was having problems with msh crashing after trying to execute a
non-existant application multiple times.  E.g., at a shell prompt, type
`blahblah', and you'll get `blahblah: not found'; then type `blahblah'
again, and if you're running an unprotected OS like uClinux, your system
will crash.

The reason turns out to be that msh uses vfork, and if the child's exec
fails, it calls `exit' (indirectly through `leave').  exit calls
`__exit_handler', which will run down the list of exit handlers, modifying
`__exit_count'.  So after the first nonexistant program, the child will do
this, but since vfork was used, the _parent's_ __exit_count variable will
end up with a value of -1 (since __exit_handler uses a postdecrement test
in its loop).  Then, since the test of __exit_count in __exit_handler is
!= 0 (rather than >0 or something),, the 2nd time a child tries to do
this, it will think the exit handler table contains (unsigned)-1 entries,
and basically the system is toast.

As a comment in msh.c says, /* who wrote this crappy non vfork safe shit? */

I'm not sure the best way to fix it, but I'd think that replacing the
call to `leave' (and nearby calls to `exit') with `_exit' might be a good
idea.

[It might also be a good idea to make the test in `__exit_handler' be > 0,
instead of != 0, to limit the damage caused in cases like this, though
obviously the real fault here lies with msh.]

Thanks,

-Miles
-- 
Suburbia: where they tear out the trees and then name streets after them.



More information about the uClibc mailing list