Bug 1153382 - Make poison values more toxic when used as a Value; r=sfink
☠☠ backed out by c8ef1b55f785 ☠ ☠
authorTerrence Cole <terrence@mozilla.com>
Mon, 13 Apr 2015 09:56:02 -0700
changeset 239421 42ed856b37d93aedc448585c50fc89dcb063be10
parent 239420 bbfa03945585e60ac1bafee72190562b6acba697
child 239422 a54ea61e6fc4d30494497e34aacae735cf3b8dcc
push id28597
push usercbook@mozilla.com
push dateThu, 16 Apr 2015 10:41:20 +0000
treeherdermozilla-central@ec1351f9bc58 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssfink
bugs1153382
milestone40.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1153382 - Make poison values more toxic when used as a Value; r=sfink
js/src/jsutil.h
mfbt/PodOperations.h
--- a/js/src/jsutil.h
+++ b/js/src/jsutil.h
@@ -9,20 +9,22 @@
  */
 
 #ifndef jsutil_h
 #define jsutil_h
 
 #include "mozilla/Assertions.h"
 #include "mozilla/Compiler.h"
 #include "mozilla/GuardObjects.h"
+#include "mozilla/PodOperations.h"
 
 #include <limits.h>
 
 #include "js/Utility.h"
+#include "js/Value.h"
 
 #define JS_ALWAYS_TRUE(expr)      MOZ_ALWAYS_TRUE(expr)
 #define JS_ALWAYS_FALSE(expr)     MOZ_ALWAYS_FALSE(expr)
 
 #if defined(JS_DEBUG)
 # define JS_DIAGNOSTICS_ASSERT(expr) MOZ_ASSERT(expr)
 #elif defined(JS_CRASH_DIAGNOSTICS)
 # define JS_DIAGNOSTICS_ASSERT(expr) do { if (MOZ_UNLIKELY(!(expr))) MOZ_CRASH(); } while(0)
@@ -273,30 +275,41 @@ ClearAllBitArrayElements(size_t* array, 
 {
     for (unsigned i = 0; i < length; ++i)
         array[i] = 0;
 }
 
 }  /* namespace js */
 
 static inline void*
-Poison(void* ptr, int value, size_t num)
+Poison(void* ptr, uint8_t value, size_t num)
 {
-    static bool inited = false;
-    static bool poison = true;
-    if (!inited) {
-        char* env = getenv("JSGC_DISABLE_POISONING");
-        if (env)
-            poison = false;
-        inited = true;
+    static bool poison = getenv("JSGC_DISABLE_POISONING");
+    if (poison) {
+        // Without a valid Value tag, a poisoned Value may look like a valid
+        // floating point number. To ensure that we crash more readily when
+        // observing a poisoned Value, we make the poison an invalid ObjectValue.
+        uintptr_t obj;
+        memset(&obj, value, sizeof(obj));
+#if defined(JS_PUNBOX64)
+        obj >>= JSVAL_TAG_SHIFT;
+#endif
+        jsval_layout layout = OBJECT_TO_JSVAL_IMPL((JSObject*)obj);
+
+        size_t value_count = num / sizeof(jsval_layout);
+        size_t byte_count = num % sizeof(jsval_layout);
+        mozilla::PodSet((jsval_layout*)ptr, layout, value_count);
+        if (byte_count) {
+            uint8_t* bytes = static_cast<uint8_t*>(ptr);
+            uint8_t* end = bytes + num;
+            mozilla::PodSet(end - byte_count, value, byte_count);
+        }
+        return ptr;
     }
 
-    if (poison)
-        return memset(ptr, value, num);
-
     return nullptr;
 }
 
 /* Crash diagnostics */
 #if defined(DEBUG) && !defined(MOZ_ASAN)
 # define JS_CRASH_DIAGNOSTICS 1
 #endif
 #if defined(JS_CRASH_DIAGNOSTICS) || defined(JS_GC_ZEAL)
--- a/mfbt/PodOperations.h
+++ b/mfbt/PodOperations.h
@@ -84,16 +84,28 @@ PodAssign(T* aDst, const T* aSrc)
 {
   MOZ_ASSERT(aDst + 1 <= aSrc || aSrc + 1 <= aDst,
              "destination and source must not overlap");
   memcpy(reinterpret_cast<char*>(aDst), reinterpret_cast<const char*>(aSrc),
          sizeof(T));
 }
 
 /**
+ * Set the first |aNElem| T elements in |aDst| to |aSrc|.
+ */
+template<typename T>
+static MOZ_ALWAYS_INLINE void
+PodSet(T* aDst, T aSrc, size_t aNElem)
+{
+  for (const T* dstend = aDst + aNElem; aDst < dstend; aDst++) {
+    *aDst = aSrc;
+  }
+}
+
+/**
  * Copy |aNElem| T elements from |aSrc| to |aDst|.  The two memory ranges must
  * not overlap!
  */
 template<typename T>
 static MOZ_ALWAYS_INLINE void
 PodCopy(T* aDst, const T* aSrc, size_t aNElem)
 {
   MOZ_ASSERT(aDst + aNElem <= aSrc || aSrc + aNElem <= aDst,