Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

endless loop with respawn with inittab #22

Closed
thehajime opened this issue Oct 10, 2024 · 3 comments
Closed

endless loop with respawn with inittab #22

thehajime opened this issue Oct 10, 2024 · 3 comments
Labels
bug Something isn't working
Milestone

Comments

@thehajime
Copy link
Owner

- before /bin/sh might be the issue

# /etc/inittab

::sysinit:/etc/init.d/rcS

+::respawn:/bin/sh
-# XXX: '-' makes endless loop with busybox 1.36.1
-#::respawn:-/bin/sh

# Stuff to do when restarting the init process
::restart:/sbin/init

# Stuff to do before rebooting
::ctrlaltdel:/sbin/reboot
::shutdown:/bin/umount -a -r
::shutdown:/sbin/swapoff -a
@thehajime thehajime added the bug Something isn't working label Oct 10, 2024
@thehajime thehajime added this to the RFC milestone Oct 10, 2024
@thehajime
Copy link
Owner Author

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...

@thehajime
Copy link
Owner Author

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.

@thehajime
Copy link
Owner Author

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

1 participant