From 9967c9949e0436879354e76c2847d697c309984c Mon Sep 17 00:00:00 2001
From: Denys Vlasenko <vda.linux@googlemail.com>
Date: Thu, 26 Jan 2017 01:13:58 +0100
Subject: libbb: spawn_and_wait() fflushes before forking NOEXEC; child reinits
 logmode

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
---
 libbb/vfork_daemon_rexec.c | 36 +++++++++++++++++++-----------------
 1 file changed, 19 insertions(+), 17 deletions(-)

(limited to 'libbb/vfork_daemon_rexec.c')

diff --git a/libbb/vfork_daemon_rexec.c b/libbb/vfork_daemon_rexec.c
index c192829b5..2e7dc2d9b 100644
--- a/libbb/vfork_daemon_rexec.c
+++ b/libbb/vfork_daemon_rexec.c
@@ -183,26 +183,28 @@ int FAST_FUNC spawn_and_wait(char **argv)
 #if ENABLE_FEATURE_PREFER_APPLETS
 	int a = find_applet_by_name(argv[0]);
 
-	if (a >= 0 && (APPLET_IS_NOFORK(a)
-# if BB_MMU
-			|| APPLET_IS_NOEXEC(a) /* NOEXEC trick needs fork() */
-# endif
-	)) {
-# if BB_MMU
+	if (a >= 0) {
 		if (APPLET_IS_NOFORK(a))
-# endif
-		{
 			return run_nofork_applet(a, argv);
+# if BB_MMU /* NOEXEC needs fork(), thus this is done only on MMU machines: */
+		if (APPLET_IS_NOEXEC(a)) {
+			fflush_all();
+			rc = fork();
+			if (rc) /* parent or error */
+				return wait4pid(rc);
+
+			/* child */
+			/* reset some state and run without execing */
+
+			/* msg_eol = "\n"; - no caller needs this reinited yet */
+			logmode = LOGMODE_STDIO;
+			/* die_func = NULL; - needed if the caller is a shell,
+			 * init, or a NOFORK applet. But none of those call us
+			 * as of yet (and that should probably always stay true).
+			 */
+			/* xfunc_error_retval and applet_name are init by: */
+			run_applet_no_and_exit(a, argv);
 		}
-# if BB_MMU
-		/* MMU only */
-		/* a->noexec is true */
-		rc = fork();
-		if (rc) /* parent or error */
-			return wait4pid(rc);
-		/* child */
-		xfunc_error_retval = EXIT_FAILURE;
-		run_applet_no_and_exit(a, argv);
 # endif
 	}
 #endif /* FEATURE_PREFER_APPLETS */
-- 
cgit v1.2.3-55-g6feb