Skip to content

Commit b07e1fe

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, call exit instead. Signed-off-by: Jonas Rebmann <jre@pengutronix.de>
1 parent 4dab97e commit b07e1fe

File tree

2 files changed

+19
-26
lines changed

2 files changed

+19
-26
lines changed

commands.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ static int cmd_break(int argc, char *argv[])
149149

150150
static int cmd_quit(int argc, char *argv[])
151151
{
152-
microcom_exit(0);
152+
exit(0);
153153
return 0;
154154
}
155155

microcom.c

Lines changed: 18 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,12 @@ static struct termios sots; /* old stdout/in termios settings to restore */
3737
struct ios_ops *ios;
3838
int debug;
3939

40+
int opt_force = 0;
41+
unsigned long current_speed = DEFAULT_BAUDRATE;
42+
int current_flow = FLOW_NONE;
43+
int listenonly = 0;
44+
char escape_char = DEFAULT_ESCAPE_CHAR;
45+
4046
void init_terminal(void)
4147
{
4248
struct termios sts;
@@ -69,9 +75,8 @@ void microcom_exit(int signal)
6975
printf("exiting\n");
7076

7177
ios->exit(ios);
72-
tcsetattr(STDIN_FILENO, TCSANOW, &sots);
73-
74-
exit(0);
78+
if (listenonly)
79+
tcsetattr(STDIN_FILENO, TCSANOW, &sots);
7580
}
7681

7782
/********************************************************************
@@ -113,12 +118,6 @@ void main_usage(int exitcode, char *str, char *dev)
113118
exit(exitcode);
114119
}
115120

116-
int opt_force = 0;
117-
unsigned long current_speed = DEFAULT_BAUDRATE;
118-
int current_flow = FLOW_NONE;
119-
int listenonly = 0;
120-
char escape_char = DEFAULT_ESCAPE_CHAR;
121-
122121
int main(int argc, char *argv[])
123122
{
124123
struct sigaction sact; /* used to initialize the signal handler */
@@ -233,7 +232,7 @@ int main(int argc, char *argv[])
233232

234233
ret = ios->set_speed(ios, current_speed);
235234
if (ret)
236-
goto cleanup_ios;
235+
exit(1);
237236

238237
current_flow = FLOW_NONE;
239238
ios->set_flow(ios, current_flow);
@@ -243,27 +242,21 @@ int main(int argc, char *argv[])
243242
printf("Type the escape character to get to the prompt.\n");
244243

245244
/* Now deal with the local terminal side */
245+
/* microcom_exit will restore the old termios handler */
246246
tcgetattr(STDIN_FILENO, &sots);
247247
init_terminal();
248-
249-
/* set the signal handler to restore the old
250-
* termios handler */
251-
sact.sa_handler = &microcom_exit;
252-
sigaction(SIGHUP, &sact, NULL);
253-
sigaction(SIGINT, &sact, NULL);
254-
sigaction(SIGPIPE, &sact, NULL);
255-
sigaction(SIGTERM, &sact, NULL);
256-
sigaction(SIGQUIT, &sact, NULL);
257248
}
258249

259-
/* run the main program loop */
260-
ret = mux_loop(ios);
250+
sact.sa_handler = &microcom_exit;
261251

262-
if (!listenonly)
263-
tcsetattr(STDIN_FILENO, TCSANOW, &sots);
252+
sigaction(SIGHUP, &sact, NULL);
253+
sigaction(SIGINT, &sact, NULL);
254+
sigaction(SIGPIPE, &sact, NULL);
255+
sigaction(SIGTERM, &sact, NULL);
256+
sigaction(SIGQUIT, &sact, NULL);
264257

265-
cleanup_ios:
266-
ios->exit(ios);
258+
/* run the main program loop */
259+
ret = mux_loop(ios);
267260

268261
exit(ret ? 1 : 0);
269262
}

0 commit comments

Comments
 (0)