]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
crash-handler: Call vhangup on /dev/console before spawning crash shell
authorDaan De Meyer <daan.j.demeyer@gmail.com>
Wed, 7 Aug 2024 18:44:38 +0000 (20:44 +0200)
committerDaan De Meyer <daan.j.demeyer@gmail.com>
Wed, 7 Aug 2024 19:24:57 +0000 (21:24 +0200)
When pid 1 crashes, the getty unit for the console will happily keep
running which means we end up with two shells competing for the same
tty. Let's call vhangup on /dev/console to kill every other process
attached to the console before we spawn the crash shell. The getty
units have Restart=always but lucky for us, pid 1 just crashed in fire
and flames so it isn't actually able to restart the getty unit.

src/basic/terminal-util.c
src/basic/terminal-util.h
src/core/crash-handler.c

index c2ff3ca85a8ea5fb246d8ec77edee1c2d905b976..1f5204cca5568c1f1db697366e610b0713af9ada 100644 (file)
@@ -434,6 +434,18 @@ int terminal_vhangup_fd(int fd) {
         return RET_NERRNO(ioctl(fd, TIOCVHANGUP));
 }
 
+int terminal_vhangup(const char *tty) {
+        _cleanup_close_ int fd = -EBADF;
+
+        assert(tty);
+
+        fd = open_terminal(tty, O_RDWR|O_NOCTTY|O_CLOEXEC);
+        if (fd < 0)
+                return fd;
+
+        return terminal_vhangup_fd(fd);
+}
+
 int vt_disallocate(const char *tty_path) {
         assert(tty_path);
 
index 84d4731ea8b300173cfdd9f82889b083b7d044d7..f8a30bbb646304e6a5c4c6df708ef2acb5a96d51 100644 (file)
@@ -68,6 +68,7 @@ const char* color_mode_to_string(ColorMode m) _const_;
 ColorMode color_mode_from_string(const char *s) _pure_;
 
 int terminal_vhangup_fd(int fd);
+int terminal_vhangup(const char *tty);
 
 int terminal_set_size_fd(int fd, const char *ident, unsigned rows, unsigned cols);
 int proc_cmdline_tty_size(const char *tty, unsigned *ret_rows, unsigned *ret_cols);
index 056cb103fe4f8257c791da151d1a035c2b11b1f9..26e59b92d25996c20845cc2a5be59a8e8690e9a6 100644 (file)
@@ -165,6 +165,7 @@ _noreturn_ static void crash(int sig, siginfo_t *siginfo, void *context) {
                                          "MESSAGE_ID=" SD_MESSAGE_CRASH_SHELL_FORK_FAILED_STR);
                 else if (pid == 0) {
                         (void) setsid();
+                        (void) terminal_vhangup("/dev/console");
                         (void) make_console_stdio();
                         (void) rlimit_nofile_safe();
                         (void) execle("/bin/sh", "/bin/sh", NULL, environ);