From 9af7c9d6b62ceb07a9ba24cee0cf4a08c689235e Mon Sep 17 00:00:00 2001 From: Denis Vlasenko Date: Fri, 19 Jan 2007 21:19:35 +0000 Subject: openvt,getty,vfork_daemon_rexec,mount: tighten up fd cleanup code (will close all fd's > 2 on daemonization now) getty: fix "getty -" support, and also do not try to chown/chmod "-" telnetd: fix "lost ctty" bug Yet another attempt on saner function names: bb_sanitize_server_stdio(0/1) -> bb_sanitize_stdio() + bb_daemonize(); --- console-tools/openvt.c | 15 ++++++--------- debianutils/start_stop_daemon.c | 2 +- include/libbb.h | 4 +++- libbb/vfork_daemon_rexec.c | 4 ++-- libbb/xfuncs.c | 12 ++++++++++-- loginutils/getty.c | 32 ++++++++++++-------------------- miscutils/setsid.c | 7 ++----- networking/fakeidentd.c | 2 ++ networking/inetd.c | 4 ++-- networking/isrv_identd.c | 2 +- networking/telnetd.c | 12 ++++++++---- networking/zcip.c | 5 +++-- shell/hush.c | 6 +++--- shell/lash.c | 2 +- util-linux/mount.c | 2 +- 15 files changed, 57 insertions(+), 54 deletions(-) diff --git a/console-tools/openvt.c b/console-tools/openvt.c index f1cf564..c7b3e4f 100644 --- a/console-tools/openvt.c +++ b/console-tools/openvt.c @@ -17,7 +17,6 @@ int openvt_main(int argc, char **argv) int fd; char vtname[sizeof(VC_FORMAT) + 2]; - if (argc < 3) { bb_show_usage(); } @@ -25,18 +24,16 @@ int openvt_main(int argc, char **argv) sprintf(vtname, VC_FORMAT, (int)xatoul_range(argv[1], 1, 63)); if (fork() == 0) { - /* leave current vt */ - if (setsid() < 0) { - bb_perror_msg_and_die("setsid"); - } - close(0); /* so that new vt becomes stdin */ - + /* child */ + /* leave current vt (controlling tty) */ + setsid(); /* and grab new one */ fd = xopen(vtname, O_RDWR); - - /* Reassign stdout and sterr */ + /* Reassign stdin, stdout and sterr */ + dup2(fd, STDIN_FILENO); dup2(fd, STDOUT_FILENO); dup2(fd, STDERR_FILENO); + while (fd > 2) close(fd--); execvp(argv[2], &argv[2]); _exit(1); diff --git a/debianutils/start_stop_daemon.c b/debianutils/start_stop_daemon.c index 521b43d..9a865f6 100644 --- a/debianutils/start_stop_daemon.c +++ b/debianutils/start_stop_daemon.c @@ -291,8 +291,8 @@ int start_stop_daemon_main(int argc, char **argv) } *--argv = startas; if (opt & OPT_BACKGROUND) { - xdaemon(0, 0); setsid(); + bb_daemonize(); } if (opt & OPT_MAKEPID) { /* user wants _us_ to make the pidfile */ diff --git a/include/libbb.h b/include/libbb.h index 2089d23..7721cbf 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -268,7 +268,9 @@ extern void xsetgid(gid_t gid); extern void xsetuid(uid_t uid); extern void xdaemon(int nochdir, int noclose); /* More clever/thorough xdaemon */ -extern void bb_sanitize_server_stdio(int daemonize); +extern void bb_sanitize_stdio_maybe_daemonize(int daemonize); +extern void bb_sanitize_stdio(void); +extern void bb_daemonize(void); extern void xchdir(const char *path); extern void xsetenv(const char *key, const char *value); extern int xopen(const char *pathname, int flags); diff --git a/libbb/vfork_daemon_rexec.c b/libbb/vfork_daemon_rexec.c index 81ae126..26d1826 100644 --- a/libbb/vfork_daemon_rexec.c +++ b/libbb/vfork_daemon_rexec.c @@ -35,8 +35,8 @@ void vfork_daemon_rexec(int nochdir, int noclose, dup2(fd, STDIN_FILENO); dup2(fd, STDOUT_FILENO); dup2(fd, STDERR_FILENO); - if (fd > 2) - close(fd); + while (fd > 2) + close(fd--); } vfork_args = xzalloc(sizeof(char *) * (argc + 3)); diff --git a/libbb/xfuncs.c b/libbb/xfuncs.c index 84d4741..dc160bf 100644 --- a/libbb/xfuncs.c +++ b/libbb/xfuncs.c @@ -509,7 +509,7 @@ void xdaemon(int nochdir, int noclose) } #endif -void bb_sanitize_server_stdio(int daemonize) +void bb_sanitize_stdio_maybe_daemonize(int daemonize) { int fd; /* Mega-paranoid */ @@ -523,8 +523,8 @@ void bb_sanitize_server_stdio(int daemonize) if (pid) /* parent */ exit(0); /* child */ - setsid(); /* if daemonizing, make sure we detach from stdio */ + setsid(); dup2(fd, 0); dup2(fd, 1); dup2(fd, 2); @@ -532,6 +532,14 @@ void bb_sanitize_server_stdio(int daemonize) while (fd > 2) close(fd--); /* close everything after fd#2 */ } +void bb_sanitize_stdio(void) +{ + bb_sanitize_stdio_maybe_daemonize(0); +} +void bb_daemonize(void) +{ + bb_sanitize_stdio_maybe_daemonize(1); +} // Die with an error message if we can't open a new socket. int xsocket(int domain, int type, int protocol) diff --git a/loginutils/getty.c b/loginutils/getty.c index 5ceaefc..be49389 100644 --- a/loginutils/getty.c +++ b/loginutils/getty.c @@ -211,7 +211,7 @@ static void parse_args(int argc, char **argv, struct options *op) bb_show_usage(); /* we loosen up a bit and accept both "baudrate tty" and "tty baudrate" */ - if ('0' <= argv[0][0] && argv[0][0] <= '9') { + if (isdigit(argv[0][0])) { /* a number first, assume it's a speed (BSD style) */ parse_speeds(op, argv[0]); /* baud rate(s) */ op->tty = argv[1]; /* tty name */ @@ -255,10 +255,8 @@ static void open_tty(char *tty, struct termios *tp, int local) debug("open(2)\n"); fd = xopen(tty, O_RDWR | O_NONBLOCK); - if (fd) { - xdup2(fd, 0, tty); - close(fd); - } + xdup2(fd, 0, tty); + while (fd > 2) close(fd--); } else { /* * Standard input should already be connected to an open port. Make @@ -327,8 +325,10 @@ static void open_tty(char *tty, struct termios *tp, int local) } } #else - chown(tty, 0, 0); /* root, sys */ - chmod(tty, 0622); /* crw--w--w- */ + if (NOT_LONE_DASH(tty)) { + chown(tty, 0, 0); /* 0:0 */ + chmod(tty, 0622); /* crw--w--w- */ + } #endif if (chdir_to_root) xchdir("/"); @@ -736,22 +736,14 @@ int getty_main(int argc, char **argv) /* Already too late because of theoretical * possibility of getty --help somehow triggered * inadvertently before we reach this. Oh well. */ - close(0); - close(1); - close(2); logmode = LOGMODE_NONE; -#ifdef __linux__ setsid(); -#endif - /* Was "/dev/console". Why should we spam *system console* - * if there is a problem with getty on /dev/ttyS15?... */ nullfd = xopen(bb_dev_null, O_RDWR); - if (nullfd) { - dup2(nullfd, 0); - close(nullfd); - } - dup2(0, 1); - dup2(0, 2); + /* dup2(nullfd, 0); - no, because of possible "getty - 9600" */ + /* open_tty() will take care of fd# 0 anyway */ + dup2(nullfd, 1); + dup2(nullfd, 2); + while (nullfd > 2) close(nullfd--); /* We want special flavor of error_msg_and_die */ die_sleep = 10; msg_eol = "\r\n"; diff --git a/miscutils/setsid.c b/miscutils/setsid.c index 347b2ba..47c44d2 100644 --- a/miscutils/setsid.c +++ b/miscutils/setsid.c @@ -15,9 +15,6 @@ */ #include "busybox.h" -#include -#include -#include int setsid_main(int argc, char *argv[]) { @@ -25,7 +22,7 @@ int setsid_main(int argc, char *argv[]) bb_show_usage(); if (getpgrp() == getpid()) { - switch (fork()){ + switch (fork()) { case -1: bb_perror_msg_and_die("fork"); case 0: @@ -33,8 +30,8 @@ int setsid_main(int argc, char *argv[]) default: /* parent */ exit(0); } - /* child falls through */ } + /* child */ setsid(); /* no error possible */ diff --git a/networking/fakeidentd.c b/networking/fakeidentd.c index 8c07082..6f766a8 100644 --- a/networking/fakeidentd.c +++ b/networking/fakeidentd.c @@ -1,3 +1,5 @@ +/* NB: this file is to be removed soon. See isrv_identd.c */ + /* vi: set sw=4 ts=4: */ /* * A fake identd server diff --git a/networking/inetd.c b/networking/inetd.c index 370dcbb..218f85e 100644 --- a/networking/inetd.c +++ b/networking/inetd.c @@ -1292,9 +1292,9 @@ inetd_main(int argc, char *argv[]) /* reexec for vfork() do continue parent */ vfork_daemon_rexec(0, 0, argc, argv, "-f"); } - bb_sanitize_server_stdio(0); + bb_sanitize_stdio(); #else - bb_sanitize_server_stdio(!(opt & 2)); + bb_sanitize_stdio_maybe_daemonize(!(opt & 2)); #endif openlog(applet_name, LOG_PID | LOG_NOWAIT, LOG_DAEMON); logmode = LOGMODE_SYSLOG; diff --git a/networking/isrv_identd.c b/networking/isrv_identd.c index e757d7c..2d4399c 100644 --- a/networking/isrv_identd.c +++ b/networking/isrv_identd.c @@ -111,7 +111,7 @@ int fakeidentd_main(int argc, char **argv) bogouser = argv[optind]; /* Daemonize if no -f and no -i and no -w */ - bb_sanitize_server_stdio(!(opt & OPT_fiw)); + bb_sanitize_stdio_maybe_daemonize(!(opt & OPT_fiw)); /* Where to log in inetd modes? "Classic" inetd * probably has its stderr /dev/null'ed (we need log to syslog?), * but daemontools-like utilities usually expect that children diff --git a/networking/telnetd.c b/networking/telnetd.c index 51bd0c0..25cba3e 100644 --- a/networking/telnetd.c +++ b/networking/telnetd.c @@ -283,15 +283,19 @@ make_new_session( /* child */ + /* make new process group */ + setsid(); + tcsetpgrp(0, getpid()); + /* ^^^ strace says: "ioctl(0, TIOCSPGRP, [pid]) = -1 ENOTTY" -- ??! */ + /* open the child's side of the tty. */ - fd = xopen(tty_name, O_RDWR /*| O_NOCTTY*/); + /* NB: setsid() disconnects from any previous ctty's. Therefore + * we must open child's side of the tty AFTER setsid! */ + fd = xopen(tty_name, O_RDWR); /* becomes our ctty */ dup2(fd, 0); dup2(fd, 1); dup2(fd, 2); while (fd > 2) close(fd--); - /* make new process group */ - setsid(); - tcsetpgrp(0, getpid()); /* The pseudo-terminal allocated to the client is configured to operate in * cooked mode, and with XTABS CRMOD enabled (see tty(4)). */ diff --git a/networking/zcip.c b/networking/zcip.c index 27e281c..5d57c42 100644 --- a/networking/zcip.c +++ b/networking/zcip.c @@ -221,7 +221,8 @@ int zcip_main(int argc, char *argv[]) } if (opts & 4) { // -r n.n.n.n if (inet_aton(r_opt, &ip) == 0 - || (ntohl(ip.s_addr) & IN_CLASSB_NET) != LINKLOCAL_ADDR) { + || (ntohl(ip.s_addr) & IN_CLASSB_NET) != LINKLOCAL_ADDR + ) { bb_error_msg_and_die("invalid link address"); } } @@ -270,7 +271,7 @@ int zcip_main(int argc, char *argv[]) // daemonize now; don't delay system startup if (!FOREGROUND) { setsid(); - xdaemon(0, 0); + bb_daemonize(); bb_info_msg("start, interface %s", intf); } diff --git a/shell/hush.c b/shell/hush.c index 9bc0013..8f2dc80 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -2634,8 +2634,8 @@ static void setup_job_control(void) /* Put ourselves in our own process group. */ setsid(); - shell_pgrp = getpid (); - setpgid (shell_pgrp, shell_pgrp); + shell_pgrp = getpid(); + setpgid(shell_pgrp, shell_pgrp); /* Grab control of the terminal. */ tcsetpgrp(shell_terminal, shell_pgrp); @@ -2665,7 +2665,7 @@ int hush_main(int argc, char **argv) /* Initialize some more globals to non-zero values */ set_cwd(); - if (ENABLE_FEATURE_COMMAND_EDITING) cmdedit_set_initial_prompt(); + if (ENABLE_FEATURE_COMMAND_EDITING) cmdedit_set_initial_prompt(); else PS1 = NULL; PS2 = "> "; diff --git a/shell/lash.c b/shell/lash.c index 52b1174..b2ccaf0 100644 --- a/shell/lash.c +++ b/shell/lash.c @@ -1486,7 +1486,7 @@ static void setup_job_control(void) /* Put ourselves in our own process group. */ setsid(); - shell_pgrp = getpid (); + shell_pgrp = getpid(); setpgid(shell_pgrp, shell_pgrp); /* Grab control of the terminal. */ diff --git a/util-linux/mount.c b/util-linux/mount.c index b3e8c47..77382ff 100644 --- a/util-linux/mount.c +++ b/util-linux/mount.c @@ -737,7 +737,7 @@ static int daemonize(void) dup2(fd, 0); dup2(fd, 1); dup2(fd, 2); - if (fd > 2) close(fd); + while (fd > 2) close(fd--); setsid(); openlog(applet_name, LOG_PID, LOG_DAEMON); logmode = LOGMODE_SYSLOG; -- cgit v1.1