PATCH: removing hardcoded paths from init

Gabriel L. Somlo somlo at cmu.edu
Sat Jan 20 23:33:01 UTC 2007


On Sat, Jan 20, 2007 at 02:13:40PM +0100, Denis Vlasenko wrote:
> -		execv(cmdpath, cmd);
> +		path = cmdpath;
> +		if (ENABLE_FEATURE_EXEC_PREFER_APPLETS && find_applet_by_name(cmdpath))
> +			path = CONFIG_BUSYBOX_EXEC_PATH;
> +		execvp(path, cmd);
> 
> Looks less obfuscated. (Or just reuse cmdpath instead of new 'path' ptr,
> if you can).

Long term it should all be hidden inside an execlp wrapper anyway.
BTW, is there a naming convention for busybox-specific wrappers around
library functions ? How about bb_execlp() ?

> 
> Can you redo these places like this?

Sure. See below.

Cheers,
Gabriel


diff -NarU5 busybox-svn-17314.orig/Config.in busybox-svn-17314/Config.in
--- busybox-svn-17314.orig/Config.in	2007-01-15 15:18:07.000000000 -0500
+++ busybox-svn-17314/Config.in	2007-01-19 17:58:46.000000000 -0500
@@ -229,10 +229,18 @@
 		LDFLAGS=-L<libselinux-lib-path> \
 		make
 
 	  Most people will leave this set to 'N'.
 
+config FEATURE_EXEC_PREFER_APPLETS
+        bool "exec prefers applets"
+        default n
+        help
+          This is an experimental option which directs applets about to
+          call 'exec' to try and find an applicable busybox applet before
+          searching the executable path for a binary or symlink to execute.
+
 config BUSYBOX_EXEC_PATH
 	string "Path to BusyBox executable"
 	default "/proc/self/exe"
 	help
 	  When Busybox applets need to run other busybox applets, BusyBox
@@ -437,11 +445,11 @@
          on a filesystem with few inodes.
 
 config INSTALL_APPLET_DONT
        bool
        prompt "not installed"
-       depends on FEATURE_INSTALLER || FEATURE_SH_STANDALONE_SHELL
+       depends on FEATURE_INSTALLER || FEATURE_SH_STANDALONE_SHELL || FEATURE_EXEC_PREFER_APPLETS
        help
          Do not install applet links. Useful when using the -install feature
          or a standalone shell for rescue pruposes.
 
 endchoice
diff -NarU5 busybox-svn-17314.orig/init/init.c busybox-svn-17314/init/init.c
--- busybox-svn-17314.orig/init/init.c	2007-01-15 15:18:06.000000000 -0500
+++ busybox-svn-17314/init/init.c	2007-01-20 18:23:04.000000000 -0500
@@ -387,10 +387,11 @@
 	static const char press_enter[] =
 #ifdef CUSTOMIZED_BANNER
 #include CUSTOMIZED_BANNER
 #endif
 		"\nPlease press Enter to activate this console. ";
+	char *prog;
 
 	/* Block sigchild while forking.  */
 	sigemptyset(&nmask);
 	sigaddset(&nmask, SIGCHLD);
 	sigprocmask(SIG_BLOCK, &nmask, &omask);
@@ -558,11 +559,14 @@
 		}
 #endif
 
 		/* Now run it.  The new program will take over this PID,
 		 * so nothing further in init.c should be run. */
-		execv(cmdpath, cmd);
+		prog = cmdpath;
+		if (ENABLE_FEATURE_EXEC_PREFER_APPLETS && find_applet_by_name(prog))
+			prog = CONFIG_BUSYBOX_EXEC_PATH;
+		execvp(prog, cmd);
 
 		/* We're still here?  Some error happened. */
 		message(LOG | CONSOLE, "Bummer, cannot run '%s': %m", cmdpath);
 		_exit(-1);
 	}
@@ -676,10 +680,11 @@
 
 static void exec_signal(int sig ATTRIBUTE_UNUSED)
 {
 	struct init_action *a, *tmp;
 	sigset_t unblock_signals;
+	char *prog;
 
 	for (a = init_action_list; a; a = tmp) {
 		tmp = a->next;
 		if (a->action & RESTART) {
 			shutdown_system();
@@ -711,11 +716,14 @@
 			/* Setup stdout, stderr on the supplied terminal */
 			dup(0);
 			dup(0);
 
 			messageD(CONSOLE | LOG, "Trying to re-exec %s", a->command);
-			execl(a->command, a->command, NULL);
+			prog = a->command;
+			if (ENABLE_FEATURE_EXEC_PREFER_APPLETS && find_applet_by_name(prog))
+				prog = CONFIG_BUSYBOX_EXEC_PATH;
+			execlp(prog, a->command, NULL);
 
 			message(CONSOLE | LOG, "exec of '%s' failed: %m",
 					a->command);
 			sync();
 			sleep(2);
@@ -850,17 +858,17 @@
 	file = fopen(INITTAB, "r");
 	if (file == NULL) {
 		/* No inittab file -- set up some default behavior */
 #endif
 		/* Reboot on Ctrl-Alt-Del */
-		new_init_action(CTRLALTDEL, "/sbin/reboot", "");
+		new_init_action(CTRLALTDEL, "reboot", "");
 		/* Umount all filesystems on halt/reboot */
-		new_init_action(SHUTDOWN, "/bin/umount -a -r", "");
+		new_init_action(SHUTDOWN, "umount -a -r", "");
 		/* Swapoff on halt/reboot */
-		if(ENABLE_SWAPONOFF) new_init_action(SHUTDOWN, "/sbin/swapoff -a", "");
+		if(ENABLE_SWAPONOFF) new_init_action(SHUTDOWN, "swapoff -a", "");
 		/* Prepare to restart init when a HUP is received */
-		new_init_action(RESTART, "/sbin/init", "");
+		new_init_action(RESTART, "init", "");
 		/* Askfirst shell on tty1-4 */
 		new_init_action(ASKFIRST, bb_default_login_shell, "");
 		new_init_action(ASKFIRST, bb_default_login_shell, VC_2);
 		new_init_action(ASKFIRST, bb_default_login_shell, VC_3);
 		new_init_action(ASKFIRST, bb_default_login_shell, VC_4);
@@ -1037,13 +1045,13 @@
 		if (!sysinfo(&info) &&
 			(info.mem_unit ? : 1) * (long long)info.totalram < 1024*1024)
 		{
 			message(CONSOLE,"Low memory: forcing swapon.");
 			/* swapon -a requires /proc typically */
-			new_init_action(SYSINIT, "/bin/mount -t proc proc /proc", "");
+			new_init_action(SYSINIT, "mount -t proc proc /proc", "");
 			/* Try to turn on swap */
-			new_init_action(SYSINIT, "/sbin/swapon -a", "");
+			new_init_action(SYSINIT, "swapon -a", "");
 			run_actions(SYSINIT);   /* wait and removing */
 		}
 	}
 
 	/* Check if we are supposed to be in single user mode */
@@ -1066,11 +1074,14 @@
 	if (getenv("SELINUX_INIT") == NULL) {
 		int enforce = 0;
 
 		putenv("SELINUX_INIT=YES");
 		if (selinux_init_load_policy(&enforce) == 0) {
-			execv(argv[0], argv);
+			char *prog = argv[0];
+			if (ENABLE_FEATURE_EXEC_PREFER_APPLETS && find_applet_by_name(prog))
+				prog = CONFIG_BUSYBOX_EXEC_PATH;
+			execvp(prog, argv);
 		} else if (enforce > 0) {
 			/* SELinux in enforcing mode but load_policy failed */
 			/* At this point, we probably can't open /dev/console, so log() won't work */
 			message(CONSOLE,"Unable to load SELinux Policy. Machine is in enforcing mode. Halting now.");
 			exit(1);
diff -NarU5 busybox-svn-17314.orig/libbb/xfuncs.c busybox-svn-17314/libbb/xfuncs.c
--- busybox-svn-17314.orig/libbb/xfuncs.c	2007-01-15 15:18:04.000000000 -0500
+++ busybox-svn-17314/libbb/xfuncs.c	2007-01-20 18:17:02.000000000 -0500
@@ -181,18 +181,21 @@
 pid_t spawn(char **argv)
 {
 	/* Why static? */
 	static int failed;
 	pid_t pid;
-	void *app = ENABLE_FEATURE_SH_STANDALONE_SHELL ? find_applet_by_name(argv[0]) : 0;
+	char *prog;
 
 	// Be nice to nommu machines.
 	failed = 0;
 	pid = vfork();
 	if (pid < 0) return pid;
 	if (!pid) {
-		execvp(app ? CONFIG_BUSYBOX_EXEC_PATH : *argv, argv);
+		prog = argv[0];
+		if (ENABLE_FEATURE_EXEC_PREFER_APPLETS && find_applet_by_name(prog))
+			prog = CONFIG_BUSYBOX_EXEC_PATH;
+		execvp(prog, argv);
 
 		// We're sharing a stack with blocked parent, let parent know we failed
 		// and then exit to unblock parent (but don't run atexit() stuff, which
 		// would screw up parent.)
 
diff -NarU5 busybox-svn-17314.orig/scripts/defconfig busybox-svn-17314/scripts/defconfig
--- busybox-svn-17314.orig/scripts/defconfig	2007-01-15 15:17:59.000000000 -0500
+++ busybox-svn-17314/scripts/defconfig	2007-01-19 18:10:04.000000000 -0500
@@ -25,10 +25,11 @@
 CONFIG_FEATURE_SUID=y
 CONFIG_FEATURE_SYSLOG=y
 CONFIG_FEATURE_SUID_CONFIG=y
 CONFIG_FEATURE_SUID_CONFIG_QUIET=y
 # CONFIG_SELINUX is not set
+#CONFIG_FEATURE_EXEC_PREFER_APPLETS is not set
 CONFIG_BUSYBOX_EXEC_PATH="/proc/self/exe"
 
 #
 # Build Options
 #



More information about the busybox mailing list