llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: Vassil Vassilev (vgvassilev) <details> <summary>Changes</summary> __clang_Interpreter_SetValueNoAlloc receives the runtime value through a varargs ABI: the JIT-emitted caller copies real bits into the varargs slot, and the runtime callee reads them via va_arg and stores them in the user-provided Value. MSan tracks parameter shadow through TLS, but the JIT does not emit MSan TLS shadow setup for its calls, so the varargs source reads as uninitialized. The end result is correct bits with an uninit shadow on the stored Value; downstream reads (V.getLongDouble(), V.convertTo<T>()) then report use-of-uninitialized-value. The bits are real -- only the shadow is wrong. Unpoison the written Value before returning, gated on __has_feature(memory_sanitizer) so non-MSan builds compile out to nothing. --- Full diff: https://github.com/llvm/llvm-project/pull/196894.diff 1 Files Affected: - (modified) clang/lib/Interpreter/InterpreterValuePrinter.cpp (+19-1) ``````````diff diff --git a/clang/lib/Interpreter/InterpreterValuePrinter.cpp b/clang/lib/Interpreter/InterpreterValuePrinter.cpp index 1754e7812469a..2a00a86a2838e 100644 --- a/clang/lib/Interpreter/InterpreterValuePrinter.cpp +++ b/clang/lib/Interpreter/InterpreterValuePrinter.cpp @@ -31,6 +31,21 @@ #include <sstream> #include <string> +// MSan cannot track value shadow across the JIT/native varargs boundary in +// __clang_Interpreter_SetValueNoAlloc: the JIT-emitted caller does not set +// up MSan TLS shadow, so writes via va_arg propagate uninit shadow into the +// resulting Value. Unpoison the written Value before returning. +#if defined(__has_feature) +# if __has_feature(memory_sanitizer) +# include <sanitizer/msan_interface.h> +# define CLANG_INTERP_MSAN_UNPOISON(p, n) __msan_unpoison((p), (n)) +# else +# define CLANG_INTERP_MSAN_UNPOISON(p, n) ((void)0) +# endif +#else +# define CLANG_INTERP_MSAN_UNPOISON(p, n) ((void)0) +#endif + #define DEBUG_TYPE "interp-value" using namespace clang; @@ -651,8 +666,10 @@ __clang_Interpreter_SetValueNoAlloc(void *This, void *OutVal, void *OpaqueType, Value &VRef = *(Value *)OutVal; Interpreter *I = static_cast<Interpreter *>(This); VRef = Value(I, OpaqueType); - if (VRef.isVoid()) + if (VRef.isVoid()) { + CLANG_INTERP_MSAN_UNPOISON(OutVal, sizeof(Value)); return; + } va_list args; va_start(args, /*last named param*/ OpaqueType); @@ -721,6 +738,7 @@ __clang_Interpreter_SetValueNoAlloc(void *This, void *OutVal, void *OpaqueType, } } va_end(args); + CLANG_INTERP_MSAN_UNPOISON(OutVal, sizeof(Value)); } } `````````` </details> https://github.com/llvm/llvm-project/pull/196894 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
