From b07e1fee7a41e0b684d952fb2dc88a5fb3827b7b Mon Sep 17 00:00:00 2001 From: Jonas Rebmann Date: Sat, 13 Dec 2025 22:34:05 +0100 Subject: [PATCH] microcom.c: Call cleanup routines only once Repeated call to ios->exit(ios); was observed as used after free using asan. Only call it once: In the exit handler. Always call the exit handler and check there whether listenonly is set and there skip resetting the terminal if so. Do not reset the terminal elsewhere. Do not call the exit handler from the quit command, call exit instead. Signed-off-by: Jonas Rebmann --- commands.c | 2 +- microcom.c | 43 ++++++++++++++++++------------------------- 2 files changed, 19 insertions(+), 26 deletions(-) diff --git a/commands.c b/commands.c index 97c2dc7..6d135cf 100644 --- a/commands.c +++ b/commands.c @@ -149,7 +149,7 @@ static int cmd_break(int argc, char *argv[]) static int cmd_quit(int argc, char *argv[]) { - microcom_exit(0); + exit(0); return 0; } diff --git a/microcom.c b/microcom.c index a8810b4..e44e507 100644 --- a/microcom.c +++ b/microcom.c @@ -37,6 +37,12 @@ static struct termios sots; /* old stdout/in termios settings to restore */ struct ios_ops *ios; int debug; +int opt_force = 0; +unsigned long current_speed = DEFAULT_BAUDRATE; +int current_flow = FLOW_NONE; +int listenonly = 0; +char escape_char = DEFAULT_ESCAPE_CHAR; + void init_terminal(void) { struct termios sts; @@ -69,9 +75,8 @@ void microcom_exit(int signal) printf("exiting\n"); ios->exit(ios); - tcsetattr(STDIN_FILENO, TCSANOW, &sots); - - exit(0); + if (listenonly) + tcsetattr(STDIN_FILENO, TCSANOW, &sots); } /******************************************************************** @@ -113,12 +118,6 @@ void main_usage(int exitcode, char *str, char *dev) exit(exitcode); } -int opt_force = 0; -unsigned long current_speed = DEFAULT_BAUDRATE; -int current_flow = FLOW_NONE; -int listenonly = 0; -char escape_char = DEFAULT_ESCAPE_CHAR; - int main(int argc, char *argv[]) { struct sigaction sact; /* used to initialize the signal handler */ @@ -233,7 +232,7 @@ int main(int argc, char *argv[]) ret = ios->set_speed(ios, current_speed); if (ret) - goto cleanup_ios; + exit(1); current_flow = FLOW_NONE; ios->set_flow(ios, current_flow); @@ -243,27 +242,21 @@ int main(int argc, char *argv[]) printf("Type the escape character to get to the prompt.\n"); /* Now deal with the local terminal side */ + /* microcom_exit will restore the old termios handler */ tcgetattr(STDIN_FILENO, &sots); init_terminal(); - - /* set the signal handler to restore the old - * termios handler */ - sact.sa_handler = µcom_exit; - sigaction(SIGHUP, &sact, NULL); - sigaction(SIGINT, &sact, NULL); - sigaction(SIGPIPE, &sact, NULL); - sigaction(SIGTERM, &sact, NULL); - sigaction(SIGQUIT, &sact, NULL); } - /* run the main program loop */ - ret = mux_loop(ios); + sact.sa_handler = µcom_exit; - if (!listenonly) - tcsetattr(STDIN_FILENO, TCSANOW, &sots); + sigaction(SIGHUP, &sact, NULL); + sigaction(SIGINT, &sact, NULL); + sigaction(SIGPIPE, &sact, NULL); + sigaction(SIGTERM, &sact, NULL); + sigaction(SIGQUIT, &sact, NULL); -cleanup_ios: - ios->exit(ios); + /* run the main program loop */ + ret = mux_loop(ios); exit(ret ? 1 : 0); }