Skip to content

Commit 2df322c

Browse files
committed
Don't overrun in error prints
vsprintf returns the amount it would have written if the buffer had been big enough, but we used that value directly when outputting, thus overrunning memory and dumping stack contents. Indicate truncation by inserting an ellipsis and newline. Slightly increase the buffer size, so that we don't slightly decrease the maximum printable characters because of the ellipsis insertion. Partially addresses #6850 by forcing a newline when truncation happens - often truncation will drop a newline and prevent a flush.
1 parent c989845 commit 2df322c

File tree

1 file changed

+20
-14
lines changed

1 file changed

+20
-14
lines changed

platform/mbed_board.c

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -56,25 +56,31 @@ void mbed_error_printf(const char *format, ...)
5656

5757
void mbed_error_vprintf(const char *format, va_list arg)
5858
{
59-
#define ERROR_BUF_SIZE (128)
6059
core_util_critical_section_enter();
61-
char buffer[ERROR_BUF_SIZE];
62-
int size = vsnprintf(buffer, ERROR_BUF_SIZE, format, arg);
63-
if (size > 0) {
60+
char buffer[132];
61+
int size = vsnprintf(buffer, sizeof buffer, format, arg);
62+
if (size >= sizeof buffer) {
63+
/* Output was truncated - indicate by overwriting last 4 bytes of buffer
64+
* with ellipsis and newline.
65+
* (Note that although vsnprintf always leaves a NUL terminator, we
66+
* don't need a terminator and can use the entire buffer)
67+
*/
68+
memcpy(&buffer[sizeof buffer - 4], "...\n", 4);
69+
size = sizeof buffer;
70+
}
6471
#if MBED_CONF_PLATFORM_STDIO_CONVERT_NEWLINES || MBED_CONF_PLATFORM_STDIO_CONVERT_TTY_NEWLINES
65-
char stdio_out_prev = '\0';
66-
for (int i = 0; i < size; i++) {
67-
if (buffer[i] == '\n' && stdio_out_prev != '\r') {
68-
const char cr = '\r';
69-
write(STDERR_FILENO, &cr, 1);
70-
}
71-
write(STDERR_FILENO, &buffer[i], 1);
72-
stdio_out_prev = buffer[i];
72+
char stdio_out_prev = '\0';
73+
for (int i = 0; i < size; i++) {
74+
if (buffer[i] == '\n' && stdio_out_prev != '\r') {
75+
const char cr = '\r';
76+
write(STDERR_FILENO, &cr, 1);
7377
}
78+
write(STDERR_FILENO, &buffer[i], 1);
79+
stdio_out_prev = buffer[i];
80+
}
7481
#else
75-
write(STDERR_FILENO, buffer, size);
82+
write(STDERR_FILENO, buffer, size);
7683
#endif
77-
}
7884
core_util_critical_section_exit();
7985
}
8086

0 commit comments

Comments
 (0)