Skip to content

Commit 3efc952

Browse files
committed
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, just call exit, invoking the signal handler too. Signed-off-by: Jonas Rebmann <jre@pengutronix.de>
1 parent 8ee78d9 commit 3efc952

File tree

2 files changed

+18
-24
lines changed

2 files changed

+18
-24
lines changed

commands.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,6 @@ static int cmd_break(int argc, char *argv[])
144144
static int cmd_quit(int argc, char *argv[])
145145
{
146146
fflush(NULL);
147-
microcom_exit(0);
148147
exit(0);
149148
return 0;
150149
}

microcom.c

Lines changed: 18 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,12 @@ static struct termios sots; /* old stdout/in termios settings to restore */
1919
struct ios_ops *ios;
2020
int debug = 0;
2121

22+
int opt_force = 0;
23+
unsigned long current_speed = DEFAULT_BAUDRATE;
24+
int current_flow = FLOW_NONE;
25+
int listenonly = 0;
26+
char escape_char = DEFAULT_ESCAPE_CHAR;
27+
2228
void init_terminal(void)
2329
{
2430
struct termios sts;
@@ -51,7 +57,8 @@ void microcom_exit(int signal)
5157
write(1, "exiting\n", 8);
5258

5359
ios->exit(ios);
54-
tcsetattr(STDIN_FILENO, TCSANOW, &sots);
60+
if (listenonly)
61+
tcsetattr(STDIN_FILENO, TCSANOW, &sots);
5562

5663
if (signal)
5764
_Exit(0);
@@ -96,12 +103,6 @@ void main_usage(int exitcode, char *str, char *dev)
96103
exit(exitcode);
97104
}
98105

99-
int opt_force = 0;
100-
unsigned long current_speed = DEFAULT_BAUDRATE;
101-
int current_flow = FLOW_NONE;
102-
int listenonly = 0;
103-
char escape_char = DEFAULT_ESCAPE_CHAR;
104-
105106
int main(int argc, char *argv[])
106107
{
107108
struct sigaction sact = {0}; /* used to initialize the signal handler */
@@ -210,7 +211,7 @@ int main(int argc, char *argv[])
210211

211212
ret = ios->set_speed(ios, current_speed);
212213
if (ret)
213-
goto cleanup_ios;
214+
exit(1);
214215

215216
current_flow = FLOW_NONE;
216217
ios->set_flow(ios, current_flow);
@@ -220,27 +221,21 @@ int main(int argc, char *argv[])
220221
printf("Type the escape character to get to the prompt.\n");
221222

222223
/* Now deal with the local terminal side */
224+
/* microcom_exit will restore the old termios handler */
223225
tcgetattr(STDIN_FILENO, &sots);
224226
init_terminal();
225-
226-
/* set the signal handler to restore the old
227-
* termios handler */
228-
sact.sa_handler = &microcom_exit;
229-
sigaction(SIGHUP, &sact, NULL);
230-
sigaction(SIGINT, &sact, NULL);
231-
sigaction(SIGPIPE, &sact, NULL);
232-
sigaction(SIGTERM, &sact, NULL);
233-
sigaction(SIGQUIT, &sact, NULL);
234227
}
235228

236-
/* run the main program loop */
237-
ret = mux_loop(ios);
229+
sact.sa_handler = &microcom_exit;
238230

239-
if (!listenonly)
240-
tcsetattr(STDIN_FILENO, TCSANOW, &sots);
231+
sigaction(SIGHUP, &sact, NULL);
232+
sigaction(SIGINT, &sact, NULL);
233+
sigaction(SIGPIPE, &sact, NULL);
234+
sigaction(SIGTERM, &sact, NULL);
235+
sigaction(SIGQUIT, &sact, NULL);
241236

242-
cleanup_ios:
243-
ios->exit(ios);
237+
/* run the main program loop */
238+
ret = mux_loop(ios);
244239

245240
exit(ret ? 1 : 0);
246241
}

0 commit comments

Comments
 (0)