diff --git a/compiler-rt/lib/dfsan/dfsan_custom.cpp b/compiler-rt/lib/dfsan/dfsan_custom.cpp --- a/compiler-rt/lib/dfsan/dfsan_custom.cpp +++ b/compiler-rt/lib/dfsan/dfsan_custom.cpp @@ -2460,6 +2460,49 @@ return ret; } +SANITIZER_INTERFACE_ATTRIBUTE +int __dfsw_vsprintf(char *str, const char *format, dfsan_label str_label, + dfsan_label format_label, dfsan_label *va_labels, + dfsan_label *ret_label, va_list ap) { + int ret = format_buffer(str, ~0ul, format, va_labels, ret_label, nullptr, + nullptr, ap); + return ret; +} + +SANITIZER_INTERFACE_ATTRIBUTE +int __dfso_vsprintf(char *str, const char *format, dfsan_label str_label, + dfsan_label format_label, dfsan_label *va_labels, + dfsan_label *ret_label, dfsan_origin str_origin, + dfsan_origin format_origin, dfsan_origin *va_origins, + dfsan_origin *ret_origin, va_list ap) { + int ret = format_buffer(str, ~0ul, format, va_labels, ret_label, va_origins, + ret_origin, ap); + return ret; +} + +SANITIZER_INTERFACE_ATTRIBUTE +int __dfsw_vsnprintf(char *str, size_t size, const char *format, + dfsan_label str_label, dfsan_label size_label, + dfsan_label format_label, dfsan_label *va_labels, + dfsan_label *ret_label, va_list ap) { + int ret = format_buffer(str, size, format, va_labels, ret_label, nullptr, + nullptr, ap); + return ret; +} + +SANITIZER_INTERFACE_ATTRIBUTE +int __dfso_vsnprintf(char *str, size_t size, const char *format, + dfsan_label str_label, dfsan_label size_label, + dfsan_label format_label, dfsan_label *va_labels, + dfsan_label *ret_label, dfsan_origin str_origin, + dfsan_origin size_origin, dfsan_origin format_origin, + dfsan_origin *va_origins, dfsan_origin *ret_origin, + va_list ap) { + int ret = format_buffer(str, size, format, va_labels, ret_label, va_origins, + ret_origin, ap); + return ret; +} + static void BeforeFork() { StackDepotLockAll(); GetChainedOriginDepot()->LockAll(); diff --git a/compiler-rt/lib/dfsan/done_abilist.txt b/compiler-rt/lib/dfsan/done_abilist.txt --- a/compiler-rt/lib/dfsan/done_abilist.txt +++ b/compiler-rt/lib/dfsan/done_abilist.txt @@ -206,6 +206,7 @@ fun:syscall=discard fun:unlink=discard fun:uselocale=discard +fun:vfprintf=discard # Functions that produce output does not depend on the input (need to zero the # shadow manually). @@ -285,6 +286,8 @@ # sprintf-like fun:sprintf=custom fun:snprintf=custom +fun:vsprintf=custom +fun:vsnprintf=custom # TODO: custom fun:asprintf=discard diff --git a/compiler-rt/test/dfsan/custom.cpp b/compiler-rt/test/dfsan/custom.cpp --- a/compiler-rt/test/dfsan/custom.cpp +++ b/compiler-rt/test/dfsan/custom.cpp @@ -1939,6 +1939,14 @@ ASSERT_LABEL(r, 0); } +// This is essentially the same as sprintf with the only difference that it +// uses a va_list instead of varargs. This empty function is here to appease +// the check-wrappers script. +void test_vsprintf() {} + +// Same here, but for snprintf. +void test_vsnprintf() {} + // Tested by a seperate source file. This empty function is here to appease the // check-wrappers script. void test_fork() {} @@ -2019,5 +2027,7 @@ test_strtoul(); test_strtoull(); test_time(); + test_vsprintf(); + test_vsnprintf(); test_write(); }