[git commit] shell: fix script's comm field if ENABLE_FEATURE_PREFER_APPLETS=y

Denys Vlasenko vda.linux at googlemail.com
Mon Oct 11 16:44:00 UTC 2021


commit: https://git.busybox.net/busybox/commit/?id=5acf5e1f870fb5382556d4b434158f7d497893ca
branch: https://git.busybox.net/busybox/commit/?id=refs/heads/master

function                                             old     new   delta
re_execed_comm                                         -      46     +46
main                                                  72      86     +14
------------------------------------------------------------------------------
(add/remove: 1/0 grow/shrink: 1/0 up/down: 60/0)               Total: 60 bytes

Signed-off-by: Denys Vlasenko <vda.linux at googlemail.com>
---
 include/libbb.h                      |  2 ++
 libbb/appletlib.c                    | 10 ++++++++--
 libbb/vfork_daemon_rexec.c           | 16 ++++++++++++++++
 shell/ash_test/ash-comm/comm.right   |  6 ++++++
 shell/ash_test/ash-comm/comm.tests   | 20 ++++++++++++++++++++
 shell/hush_test/hush-comm/comm.right |  6 ++++++
 shell/hush_test/hush-comm/comm.tests | 20 ++++++++++++++++++++
 7 files changed, 78 insertions(+), 2 deletions(-)

diff --git a/include/libbb.h b/include/libbb.h
index a340f27d2..2a0b272c6 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -1271,8 +1271,10 @@ void run_applet_no_and_exit(int a, const char *name, char **argv) NORETURN FAST_
 #endif
 void show_usage_if_dash_dash_help(int applet_no, char **argv) FAST_FUNC;
 #if defined(__linux__)
+int re_execed_comm(void) FAST_FUNC;
 void set_task_comm(const char *comm) FAST_FUNC;
 #else
+# define re_execed_comm() 0
 # define set_task_comm(name) ((void)0)
 #endif
 
diff --git a/libbb/appletlib.c b/libbb/appletlib.c
index e8c308467..03389f541 100644
--- a/libbb/appletlib.c
+++ b/libbb/appletlib.c
@@ -1112,8 +1112,14 @@ int main(int argc UNUSED_PARAM, char **argv)
 	 || ENABLE_FEATURE_PREFER_APPLETS
 	 || !BB_MMU
 	) {
-		if (NUM_APPLETS > 1)
-			set_task_comm(applet_name);
+		if (NUM_APPLETS > 1) {
+			/* Careful, do not trash comm of "SCRIPT.sh" -
+			 * the case when started from e.g. #!/bin/ash script.
+			 * (not limited to shells - #!/bin/awk scripts also exist)
+			 */
+			if (re_execed_comm())
+				set_task_comm(applet_name);
+		}
 	}
 
 	parse_config_file(); /* ...maybe, if FEATURE_SUID_CONFIG */
diff --git a/libbb/vfork_daemon_rexec.c b/libbb/vfork_daemon_rexec.c
index a49fe8e01..31e97051f 100644
--- a/libbb/vfork_daemon_rexec.c
+++ b/libbb/vfork_daemon_rexec.c
@@ -28,6 +28,22 @@
 # ifndef PR_GET_NAME
 # define PR_GET_NAME 16
 # endif
+# if ENABLE_FEATURE_SH_STANDALONE || ENABLE_FEATURE_PREFER_APPLETS || !BB_MMU
+int FAST_FUNC re_execed_comm(void)
+{
+	const char *e, *expected_comm;
+	char comm[16];
+
+	BUILD_BUG_ON(CONFIG_BUSYBOX_EXEC_PATH[0] != '/');
+	e = CONFIG_BUSYBOX_EXEC_PATH;
+	/* Hopefully (strrchr(e) - e) evaluates to constant at compile time: */
+	expected_comm = bb_busybox_exec_path + (strrchr(e, '/') - e) + 1;
+
+	prctl(PR_GET_NAME, (long)comm, 0, 0, 0);
+	//bb_error_msg("comm:'%.*s' expected:'%s'", 16, comm, expected_comm);
+	return strcmp(comm, expected_comm) == 0;
+}
+# endif
 void FAST_FUNC set_task_comm(const char *comm)
 {
 	/* okay if too long (truncates) */
diff --git a/shell/ash_test/ash-comm/comm.right b/shell/ash_test/ash-comm/comm.right
new file mode 100644
index 000000000..1d836656f
--- /dev/null
+++ b/shell/ash_test/ash-comm/comm.right
@@ -0,0 +1,6 @@
+./SCRIPT.sh:
+  /proc/N/comm: SCRIPT.sh
+exec ./SCRIPT.sh:
+  /proc/N/comm: SCRIPT.sh
+sh ./SCRIPT.sh:
+  /proc/N/comm: ash
diff --git a/shell/ash_test/ash-comm/comm.tests b/shell/ash_test/ash-comm/comm.tests
new file mode 100755
index 000000000..671bfc176
--- /dev/null
+++ b/shell/ash_test/ash-comm/comm.tests
@@ -0,0 +1,20 @@
+{
+echo "#!$THIS_SH"
+echo 'procdir=/proc/$$'
+#echo 'echo "  /proc/N/exe:  $(basename $(readlink $procdir/exe))"'
+echo 'echo "  /proc/N/comm: $(cat $procdir/comm)"'
+} >SCRIPT.sh
+chmod 755 SCRIPT.sh
+
+# comm field was wrong if CONFIG_FEATURE_PREFER_APPLETS=y
+echo './SCRIPT.sh:'
+./SCRIPT.sh
+
+# comm field was wrong if CONFIG_FEATURE_PREFER_APPLETS=y
+echo 'exec ./SCRIPT.sh:'
+(exec ./SCRIPT.sh)
+
+echo 'sh ./SCRIPT.sh:'
+$THIS_SH ./SCRIPT.sh
+
+rm SCRIPT.sh
diff --git a/shell/hush_test/hush-comm/comm.right b/shell/hush_test/hush-comm/comm.right
new file mode 100644
index 000000000..1b62b617e
--- /dev/null
+++ b/shell/hush_test/hush-comm/comm.right
@@ -0,0 +1,6 @@
+./SCRIPT.sh:
+  /proc/N/comm: SCRIPT.sh
+exec ./SCRIPT.sh:
+  /proc/N/comm: SCRIPT.sh
+sh ./SCRIPT.sh:
+  /proc/N/comm: hush
diff --git a/shell/hush_test/hush-comm/comm.tests b/shell/hush_test/hush-comm/comm.tests
new file mode 100755
index 000000000..671bfc176
--- /dev/null
+++ b/shell/hush_test/hush-comm/comm.tests
@@ -0,0 +1,20 @@
+{
+echo "#!$THIS_SH"
+echo 'procdir=/proc/$$'
+#echo 'echo "  /proc/N/exe:  $(basename $(readlink $procdir/exe))"'
+echo 'echo "  /proc/N/comm: $(cat $procdir/comm)"'
+} >SCRIPT.sh
+chmod 755 SCRIPT.sh
+
+# comm field was wrong if CONFIG_FEATURE_PREFER_APPLETS=y
+echo './SCRIPT.sh:'
+./SCRIPT.sh
+
+# comm field was wrong if CONFIG_FEATURE_PREFER_APPLETS=y
+echo 'exec ./SCRIPT.sh:'
+(exec ./SCRIPT.sh)
+
+echo 'sh ./SCRIPT.sh:'
+$THIS_SH ./SCRIPT.sh
+
+rm SCRIPT.sh


More information about the busybox-cvs mailing list