fdsan: reset va_list between varargs traversals
When error_level != ANDROID_FDSAN_ERROR_LEVEL_FATAL, fdsan_error()
traverses the varargs twice. Each traversal needs its own
va_start()/va_end() pair. Otherwise async_safe_format_buffer_va_list()
will start consuming arguments where async_safe_format_log_va_list()
stopped, ironically causing the sanitizer runtime to perform bad memory
accesses.
Test: debuggerd_test32
Test: debuggerd_test64
Change-Id: Ic85ca94501e55e9a435410fab89edb273c381a5a
Signed-off-by: Greg Hackmann <ghackmann@google.com>
diff --git a/libc/bionic/fdsan.cpp b/libc/bionic/fdsan.cpp
index 11ebf52..9a9fee2 100644
--- a/libc/bionic/fdsan.cpp
+++ b/libc/bionic/fdsan.cpp
@@ -188,6 +188,8 @@
async_safe_fatal_va_list("fdsan", fmt, va);
} else {
async_safe_format_log_va_list(ANDROID_LOG_ERROR, "fdsan", fmt, va);
+ va_end(va);
+ va_start(va, fmt);
size_t len =
async_safe_format_buffer_va_list(abort_message.buf, sizeof(abort_message.buf), fmt, va);
abort_message.size = len + sizeof(size_t);