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&lt;T&gt;()) 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

Reply via email to