summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko2007-01-19 21:19:35 +0000
committerDenis Vlasenko2007-01-19 21:19:35 +0000
commit9af7c9d6b62ceb07a9ba24cee0cf4a08c689235e (patch)
tree69a650a8cd686f21087fc572a995420b6ac632cc
parentf8c11aa65df2af4ab20c0effc42997bbd7357cc3 (diff)
downloadbusybox-9af7c9d6b62ceb07a9ba24cee0cf4a08c689235e.zip
busybox-9af7c9d6b62ceb07a9ba24cee0cf4a08c689235e.tar.gz
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();
-rw-r--r--console-tools/openvt.c15
-rw-r--r--debianutils/start_stop_daemon.c2
-rw-r--r--include/libbb.h4
-rw-r--r--libbb/vfork_daemon_rexec.c4
-rw-r--r--libbb/xfuncs.c12
-rw-r--r--loginutils/getty.c32
-rw-r--r--miscutils/setsid.c7
-rw-r--r--networking/fakeidentd.c2
-rw-r--r--networking/inetd.c4
-rw-r--r--networking/isrv_identd.c2
-rw-r--r--networking/telnetd.c12
-rw-r--r--networking/zcip.c5
-rw-r--r--shell/hush.c6
-rw-r--r--shell/lash.c2
-rw-r--r--util-linux/mount.c2
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 <stdio.h>
-#include <unistd.h>
-#include <stdlib.h>
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;