[git commit] sulogin: increase util-linux compatibility

Denys Vlasenko vda.linux at googlemail.com
Wed Jan 12 22:19:11 UTC 2022


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

Change to root's HOME. Set some envvars. Steal ctty if necessary and possible.

function                                             old     new   delta
sulogin_main                                         240     340    +100
setup_environment                                    225     233      +8
su_main                                              479     474      -5
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 2/1 up/down: 108/-5)            Total: 103 bytes

Signed-off-by: Denys Vlasenko <vda.linux at googlemail.com>
---
 include/libbb.h           | 18 ++++++++++--------
 libbb/setup_environment.c |  8 ++++----
 loginutils/sulogin.c      | 23 +++++++++++++++++++++++
 3 files changed, 37 insertions(+), 12 deletions(-)

diff --git a/include/libbb.h b/include/libbb.h
index daa310776..a0ffbef62 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -1726,15 +1726,16 @@ extern void selinux_or_die(void) FAST_FUNC;
 
 
 /* setup_environment:
- * if chdir pw->pw_dir: ok: else if to_tmp == 1: goto /tmp else: goto / or die
- * if clear_env = 1: cd(pw->pw_dir), clear environment, then set
+ * if !SETUP_ENV_NO_CHDIR:
+ *   if cd(pw->pw_dir): ok: else if SETUP_ENV_TO_TMP: cd(/tmp) else: cd(/) or die
+ * if SETUP_ENV_CLEARENV: cd(pw->pw_dir), clear environment, then set
  *   TERM=(old value)
  *   USER=pw->pw_name, LOGNAME=pw->pw_name
  *   PATH=bb_default_[root_]path
  *   HOME=pw->pw_dir
  *   SHELL=shell
- * else if change_env = 1:
- *   if not root (if pw->pw_uid != 0):
+ * else if SETUP_ENV_CHANGEENV:
+ *   if not root (if pw->pw_uid != 0) or if SETUP_ENV_CHANGEENV_LOGNAME:
  *     USER=pw->pw_name, LOGNAME=pw->pw_name
  *   HOME=pw->pw_dir
  *   SHELL=shell
@@ -1743,10 +1744,11 @@ extern void selinux_or_die(void) FAST_FUNC;
  * NB: CHANGEENV and CLEARENV use setenv() - this leaks memory!
  * If setup_environment() is used is vforked child, this leaks memory _in parent too_!
  */
-#define SETUP_ENV_CHANGEENV (1 << 0)
-#define SETUP_ENV_CLEARENV  (1 << 1)
-#define SETUP_ENV_TO_TMP    (1 << 2)
-#define SETUP_ENV_NO_CHDIR  (1 << 4)
+#define SETUP_ENV_CHANGEENV         (1 << 0)
+#define SETUP_ENV_CHANGEENV_LOGNAME (1 << 1)
+#define SETUP_ENV_CLEARENV          (1 << 2)
+#define SETUP_ENV_TO_TMP            (1 << 3)
+#define SETUP_ENV_NO_CHDIR          (1 << 4)
 void setup_environment(const char *shell, int flags, const struct passwd *pw) FAST_FUNC;
 void nuke_str(char *str) FAST_FUNC;
 #if ENABLE_FEATURE_SECURETTY && !ENABLE_PAM
diff --git a/libbb/setup_environment.c b/libbb/setup_environment.c
index f8de44967..df2983958 100644
--- a/libbb/setup_environment.c
+++ b/libbb/setup_environment.c
@@ -54,15 +54,15 @@ void FAST_FUNC setup_environment(const char *shell, int flags, const struct pass
 			xsetenv("TERM", term);
 		xsetenv("PATH", (pw->pw_uid ? bb_default_path : bb_default_root_path));
 		goto shortcut;
-		// No, gcc (4.2.1) is not clever enougn to do it itself.
+		// No, gcc (4.2.1) is not clever enough to do it itself.
 		//xsetenv("USER",    pw->pw_name);
 		//xsetenv("LOGNAME", pw->pw_name);
 		//xsetenv("HOME",    pw->pw_dir);
 		//xsetenv("SHELL",   shell);
 	} else if (flags & SETUP_ENV_CHANGEENV) {
-		/* Set HOME, SHELL, and if not becoming a super-user,
-		 * USER and LOGNAME.  */
-		if (pw->pw_uid) {
+		/* Set HOME, SHELL, and if not becoming a super-user
+		 * or if SETUP_ENV_CHANGEENV_LOGNAME, USER and LOGNAME.  */
+		if ((flags & SETUP_ENV_CHANGEENV_LOGNAME) || pw->pw_uid != 0) {
  shortcut:
 			xsetenv("USER",    pw->pw_name);
 			xsetenv("LOGNAME", pw->pw_name);
diff --git a/loginutils/sulogin.c b/loginutils/sulogin.c
index 69d8b5ec7..5f1c1178f 100644
--- a/loginutils/sulogin.c
+++ b/loginutils/sulogin.c
@@ -28,6 +28,7 @@
 int sulogin_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
 int sulogin_main(int argc UNUSED_PARAM, char **argv)
 {
+	int tsid;
 	int timeout = 0;
 	struct passwd *pwd;
 	const char *shell;
@@ -88,6 +89,28 @@ int sulogin_main(int argc UNUSED_PARAM, char **argv)
 	if (!shell)
 		shell = pwd->pw_shell;
 
+	/* util-linux 2.36.1 compat: cd to root's HOME, set a few envvars */
+	setup_environment(shell, SETUP_ENV_CHANGEENV | SETUP_ENV_CHANGEENV_LOGNAME, pwd);
+	// no SETUP_ENV_CLEARENV
+	// SETUP_ENV_CHANGEENV[+LOGNAME] - set HOME, SHELL, USER,and LOGNAME
+	// no SETUP_ENV_NO_CHDIR - IOW: cd to $HOME
+
+	/* util-linux 2.36.1 compat: steal ctty if we don't have it yet
+	 * (yes, util-linux uses force=1)  */
+	tsid = tcgetsid(STDIN_FILENO);
+	if (tsid < 0 || getpid() != tsid) {
+		if (ioctl(STDIN_FILENO, TIOCSCTTY, /*force:*/ (long)1) != 0) {
+//			bb_perror_msg("TIOCSCTTY1 tsid:%d", tsid);
+			if (setsid() > 0) {
+//				bb_error_msg("done setsid()");
+				/* If it still does not work, ignore */
+				if (ioctl(STDIN_FILENO, TIOCSCTTY, /*force:*/ (long)1) != 0) {
+//					bb_perror_msg("TIOCSCTTY2 tsid:%d", tsid);
+				}
+			}
+		}
+	}
+
 	/* Exec login shell with no additional parameters. Never returns. */
 	exec_login_shell(shell);
 }


More information about the busybox-cvs mailing list