From 0de3c55b4286498753751b7cd63f3af12f0ebd0f Mon Sep 17 00:00:00 2001 From: Denis Vlasenko Date: Thu, 12 Apr 2007 12:31:02 +0000 Subject: [PATCH] login: remove setpgrp call (makes it work from shell prompt again). login: sanitize stdio descriptors (we are suid, need to be careful!) shrink login and set_environment by ~100 bytes. --- include/platform.h | 6 +++--- libbb/info_msg.c | 4 ---- libbb/setup_environment.c | 15 ++++--------- loginutils/login.c | 45 ++++++++++++++++++++++----------------- 4 files changed, 32 insertions(+), 38 deletions(-) diff --git a/include/platform.h b/include/platform.h index d7389f1aa..4ed5fe624 100644 --- a/include/platform.h +++ b/include/platform.h @@ -259,8 +259,8 @@ static ATTRIBUTE_ALWAYS_INLINE char* strchrnul(const char *s, char c) { #define HAVE_INTTYPES_H #define PRIu32 "u" -/* use legacy setpgrp(pidt_,pid_t) for now. move to platform.c */ -#define bb_setpgrp do { pid_t __me = getpid(); setpgrp(__me,__me); } while (0) +/* use legacy setpgrp(pid_t,pid_t) for now. move to platform.c */ +#define bb_setpgrp() do { pid_t __me = getpid(); setpgrp(__me,__me); } while (0) #if !defined ADJ_OFFSET_SINGLESHOT && defined MOD_CLKA && defined MOD_OFFSET #define ADJ_OFFSET_SINGLESHOT (MOD_CLKA | MOD_OFFSET) @@ -276,7 +276,7 @@ static ATTRIBUTE_ALWAYS_INLINE char* strchrnul(const char *s, char c) { #endif #else -#define bb_setpgrp setpgrp() +#define bb_setpgrp() setpgrp() #endif #if defined(__linux__) diff --git a/libbb/info_msg.c b/libbb/info_msg.c index 78d5c8f32..c763ce60c 100644 --- a/libbb/info_msg.c +++ b/libbb/info_msg.c @@ -7,10 +7,6 @@ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. */ -#include -#include -#include -#include #include "libbb.h" void bb_info_msg(const char *s, ...) diff --git a/libbb/setup_environment.c b/libbb/setup_environment.c index 874a58efa..18d5a0610 100644 --- a/libbb/setup_environment.c +++ b/libbb/setup_environment.c @@ -28,19 +28,12 @@ * SUCH DAMAGE. */ -#include -#include -#include -#include -#include -#include -#include #include "libbb.h" - - -#define DEFAULT_LOGIN_PATH "/bin:/usr/bin" -#define DEFAULT_ROOT_LOGIN_PATH "/usr/sbin:/bin:/usr/bin:/sbin" +/* util-linux manpage says /sbin:/bin:/usr/sbin:/usr/bin, + * but I want to save a few bytes here */ +static const char DEFAULT_ROOT_LOGIN_PATH[] = "/sbin:/usr/sbin:/bin:/usr/bin"; +#define DEFAULT_LOGIN_PATH (DEFAULT_ROOT_LOGIN_PATH + sizeof("/sbin:/usr/sbin")) void setup_environment(const char *shell, int loginshell, int changeenv, const struct passwd *pw) { diff --git a/loginutils/login.c b/loginutils/login.c index 3d8b8e540..6a829986e 100644 --- a/loginutils/login.c +++ b/loginutils/login.c @@ -181,14 +181,13 @@ prompt: static void motd(void) { - FILE *fp; - int c; + int fd; - fp = fopen(bb_path_motd_file, "r"); - if (fp) { - while ((c = getc(fp)) != EOF) - putchar(c); - fclose(fp); + fd = open(bb_path_motd_file, O_RDONLY); + if (fd) { + fflush(stdout); + bb_copyfd_eof(fd, STDOUT_FILENO); + close(fd); } } @@ -199,7 +198,7 @@ static void alarm_handler(int sig ATTRIBUTE_UNUSED) * We don't want to block here */ ndelay_on(1); ndelay_on(2); - bb_info_msg("\r\nLogin timed out after %d seconds\r", TIMEOUT); + printf("\r\nLogin timed out after %d seconds\r\n", TIMEOUT); exit(EXIT_SUCCESS); } @@ -230,6 +229,12 @@ int login_main(int argc, char **argv) signal(SIGALRM, alarm_handler); alarm(TIMEOUT); + /* Mandatory paranoia for suid applet: + * ensure that fd# 0,1,2 are opened (at least to /dev/null) + * and any extra open fd's are closed. + * (The name of the function is misleading. Not daemonizing here.) */ + bb_daemonize_or_rexec(DAEMON_ONLY_SANITIZE | DAEMON_CLOSE_EXTRA_FDS, NULL); + opt = getopt32(argc, argv, "f:h:p", &opt_user, &opt_host); if (opt & LOGIN_OPT_f) { if (!amroot) @@ -261,7 +266,8 @@ int login_main(int argc, char **argv) } else snprintf(fromhost, sizeof(fromhost)-1, " on '%.100s'", short_tty); - bb_setpgrp; + // Was breaking "login " from shell command line: + // bb_setpgrp(); openlog(applet_name, LOG_PID | LOG_CONS | LOG_NOWAIT, LOG_AUTH); @@ -292,7 +298,7 @@ int login_main(int argc, char **argv) if (correct_password(pw)) break; -auth_failed: + auth_failed: opt &= ~LOGIN_OPT_f; bb_do_delay(FAIL_DELAY); puts("Login incorrect"); @@ -343,17 +349,13 @@ auth_failed: t_argv[0] = getenv("LOGIN_PRE_SUID_SCRIPT"); if (t_argv[0]) { t_argv[1] = NULL; - setenv("LOGIN_TTY", full_tty, 1); - setenv("LOGIN_USER", pw->pw_name, 1); - setenv("LOGIN_UID", utoa(pw->pw_uid), 1); - setenv("LOGIN_GID", utoa(pw->pw_gid), 1); - setenv("LOGIN_SHELL", pw->pw_shell, 1); + xsetenv("LOGIN_TTY", full_tty); + xsetenv("LOGIN_USER", pw->pw_name); + xsetenv("LOGIN_UID", utoa(pw->pw_uid)); + xsetenv("LOGIN_GID", utoa(pw->pw_gid)); + xsetenv("LOGIN_SHELL", pw->pw_shell); xspawn(argv); /* NOMMU-friendly */ - unsetenv("LOGIN_TTY"); - unsetenv("LOGIN_USER"); - unsetenv("LOGIN_UID"); - unsetenv("LOGIN_GID"); - unsetenv("LOGIN_SHELL"); + /* All variables are unset by setup_environment */ wait(NULL); } } @@ -379,6 +381,9 @@ auth_failed: // setsid(); // /* TIOCSCTTY: steal tty from other process group */ // if (ioctl(0, TIOCSCTTY, 1)) error_msg... + // BBox login used to do this (see above): + // bb_setpgrp(); + // If this stuff is really needed, add it and explain why! /* set signals to defaults */ signal(SIGALRM, SIG_DFL);