From bc3477fdc561f6eda5e73a357e2049d46f2b3077 Mon Sep 17 00:00:00 2001 From: Daan De Meyer Date: Wed, 7 Aug 2024 20:44:38 +0200 Subject: [PATCH] crash-handler: Call vhangup on /dev/console before spawning crash shell 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 | 12 ++++++++++++ src/basic/terminal-util.h | 1 + src/core/crash-handler.c | 1 + 3 files changed, 14 insertions(+) diff --git a/src/basic/terminal-util.c b/src/basic/terminal-util.c index c2ff3ca85a..1f5204cca5 100644 --- a/src/basic/terminal-util.c +++ b/src/basic/terminal-util.c @@ -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); diff --git a/src/basic/terminal-util.h b/src/basic/terminal-util.h index 84d4731ea8..f8a30bbb64 100644 --- a/src/basic/terminal-util.h +++ b/src/basic/terminal-util.h @@ -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); diff --git a/src/core/crash-handler.c b/src/core/crash-handler.c index 056cb103fe..26e59b92d2 100644 --- a/src/core/crash-handler.c +++ b/src/core/crash-handler.c @@ -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); -- 2.25.1