Просмотр исходного кода

s-s-d: Fix abort when opening /dev/tty with --background

Commit 2e2cab1228a6efdee57d165c508c2e05c8520f43, introducing error
checks, revealed that the TIOCNOTTY ioctl() was being issued after
having called setsid(), which already detaches the current controlling
tty, making the subsequent detach fail, and s-s-d abort.

TIOCNOTTY should only be used if setsid() is not available. In addition,
if open("/dev/tty") fails, that means there's no controlling tty, so we
should skip detaching it.

This problem got introduced in 3d6f3a9e54c437d62c58eaab4eeb9f02eb9059e6,
when enabling setsid() as a replacement for setpgid(), but not disabling
TIOCNOTTY.

Reported-by: Raphaël Hertzog <hertzog@debian.org>
Signed-off-by: Guillem Jover <guillem@debian.org>
Guillem Jover лет назад: 16
Родитель
Сommit
3706d6214a
1 измененных файлов с 23 добавлено и 14 удалено
  1. 23 14
      utils/start-stop-daemon.c

+ 23 - 14
utils/start-stop-daemon.c

@@ -296,6 +296,27 @@ get_open_fd_max(void)
 #endif
 }
 
+#ifndef HAVE_SETSID
+static void
+detach_controlling_tty(void)
+{
+#ifdef HAVE_TIOCNOTTY
+	int tty_fd;
+
+	tty_fd = open("/dev/tty", O_RDWR);
+
+	/* The current process does not have a controlling tty. */
+	if (tty_fd < 0)
+		return;
+
+	if (ioctl(tty_fd, TIOCNOTTY, 0) != 0)
+		fatal("unable to detach controlling tty");
+
+	close(tty_fd);
+#endif
+}
+#endif
+
 static void
 daemonize(void)
 {
@@ -315,6 +336,7 @@ daemonize(void)
 	setsid();
 #else
 	setpgid(0, 0);
+	detach_controlling_tty();
 #endif
 
 	pid = fork();
@@ -1445,9 +1467,6 @@ main(int argc, char **argv)
 	int devnull_fd = -1;
 	gid_t rgid;
 	uid_t ruid;
-#ifdef HAVE_TIOCNOTTY
-	int tty_fd = -1;
-#endif
 	progname = argv[0];
 
 	parse_options(argc, argv);
@@ -1554,11 +1573,6 @@ main(int argc, char **argv)
 		/* Ok, we need to detach this process. */
 		daemonize();
 
-#ifdef HAVE_TIOCNOTTY
-		tty_fd = open("/dev/tty", O_RDWR);
-		if (tty_fd < 0)
-			fatal("unable to open '%s'", "/dev/tty");
-#endif
 		devnull_fd = open("/dev/null", O_RDWR);
 		if (devnull_fd < 0)
 			fatal("unable to open '%s'", "/dev/null");
@@ -1621,12 +1635,7 @@ main(int argc, char **argv)
 	if (background) {
 		/* Continue background setup. */
 		int i;
-#ifdef HAVE_TIOCNOTTY
-		 /* Change tty. */
-		if (ioctl(tty_fd, TIOCNOTTY, 0) != 0)
-			fatal("unable to change tty");
-		close(tty_fd);
-#endif
+
 		if (umask_value < 0)
 			umask(022); /* Set a default for dumb programs. */
 		dup2(devnull_fd, 0); /* stdin */