Closed thehajime closed 2 days ago
static void init_exec(const char *command)
{
/* +8 allows to write VLA sizes below more efficiently: */
unsigned command_size = strlen(command) + 8;
/* strlen(command) + strlen("exec ")+1: */
char buf[command_size];
/* strlen(command) / 2 + 4: */
char *cmd[command_size / 2];
int dash;
(in busybox/init/init.c)
around this area, child after vfork before exec, stack becomes corrupted and command_size
becomes huge. during that, it has hard_handler
with SIGALRM, which might be relevant (or not) to be puzzled...
with CONFIG_DEBUG
, the stack corruption above disappeared...
but after that, rcS finished w/o problems but stacked at spawn /bin/sh in endless manner.
around this area, child after vfork before exec, stack becomes corrupted and command_size becomes huge. during that, it has hard_handler with SIGALRM, which might be relevant (or not) to be puzzled...
this might not be related.
even if i stopped SIGALRM by handle SIGALRM nostop print nopass
, the corruption happened.
when hush is invoked from init (via inittab), the argv[0] variable on hush_main is -/bin/sh
, which is the variable set in inittab.
if argv[0][0] == '-'
, hush tries to load /etc/profile
.
Then, in the profile file, there is id -u
command, which also (internally) invokes hush via re_execute_command
, with the argv[0][0] == '-', which trigger another /etc/profile
load again (recursively).
so, it won't stop until memory failures occur.
this diff (not upstreamed) to busybox fixes this issue.
diff --git a/shell/hush.c b/shell/hush.c
index 6b6ec7c6b..ae027dcae 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -10337,6 +10337,8 @@ int hush_main(int argc, char **argv)
_exit(0);
}
G.argv0_for_re_execing = argv[0];
+ if (G.argv0_for_re_execing[0] == '-')
+ G.argv0_for_re_execing += 1;
#endif
#if ENABLE_HUSH_TRAP
# if ENABLE_HUSH_FUNCTIONS
-
before/bin/sh
might be the issue