Backed out changeset a31159fb6888 (bug 1433642) to fix a CLOSED TREE
authorSteve Fink <sfink@mozilla.com>
Tue, 24 Apr 2018 16:02:00 -0700
changeset 471578 d7be222e99c633f30137e37b8f72742caa715011
parent 471577 0bea67efaa0a746dc54229ad5475cf73bb5356d6
child 471579 b92a5613a631a85996ce7d60e8a455b25355405e
push id1728
push userjlund@mozilla.com
push dateMon, 18 Jun 2018 21:12:27 +0000
treeherdermozilla-release@c296fde26f5f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1433642
milestone61.0a1
backs outa31159fb68887f49dccc854cd0637dfe77ed6df6
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
Backed out changeset a31159fb6888 (bug 1433642) to fix a CLOSED TREE
js/src/vm/StructuredClone.cpp
--- a/js/src/vm/StructuredClone.cpp
+++ b/js/src/vm/StructuredClone.cpp
@@ -425,16 +425,23 @@ struct JSStructuredCloneReader {
     SCInput& in;
 
     // The widest scope that the caller will accept, where
     // SameProcessSameThread is the widest (it can store anything it wants) and
     // DifferentProcess is the narrowest (it cannot contain pointers and must
     // be valid cross-process.)
     JS::StructuredCloneScope allowedScope;
 
+    // The scope the buffer was generated for (what sort of buffer it is.) The
+    // scope is not just a permissions thing; it also affects the storage
+    // format (eg a Transferred ArrayBuffer can be stored as a pointer for
+    // SameProcessSameThread but must have its contents in the clone buffer for
+    // DifferentProcess.)
+    JS::StructuredCloneScope storedScope;
+
     // Stack of objects with properties remaining to be read.
     AutoValueVector objs;
 
     // Array of all objects read during this deserialization, for resolving
     // backreferences.
     //
     // For backreferences to work correctly, objects must be added to this
     // array in exactly the order expected by the version of the Writer that
@@ -2047,16 +2054,24 @@ JSStructuredCloneReader::readSharedArray
     // transmission point, but that's tricky, and it will be a very rare problem
     // in any case.  Just fail at the receiving end if we can't handle it.
 
     if (!context()->compartment()->creationOptions().getSharedMemoryAndAtomicsEnabled()) {
         JS_ReportErrorNumberASCII(context(), GetErrorMessage, nullptr, JSMSG_SC_SAB_DISABLED);
         return false;
     }
 
+    // We must not transfer buffer pointers cross-process.  The cloneDataPolicy
+    // in the sender should guard against this; check that it does.
+    if (storedScope > JS::StructuredCloneScope::SameProcessDifferentThread) {
+        JS_ReportErrorNumberASCII(context(), GetErrorMessage, nullptr, JSMSG_SC_BAD_SERIALIZED_DATA,
+                                  "can't transfer SharedArrayBuffer cross-process");
+        return false;
+    }
+
     // The new object will have a new reference to the rawbuf.
 
     if (!rawbuf->addReference()) {
         JS_ReportErrorNumberASCII(context(), GetErrorMessage, nullptr, JSMSG_SC_SAB_REFCNT_OFLO);
         return false;
     }
 
     JSObject* obj = SharedArrayBufferObject::New(context(), rawbuf, byteLength);
@@ -2375,35 +2390,38 @@ JSStructuredCloneReader::startRead(Mutab
 
 bool
 JSStructuredCloneReader::readHeader()
 {
     uint32_t tag, data;
     if (!in.getPair(&tag, &data))
         return in.reportTruncated();
 
-    JS::StructuredCloneScope storedScope;
-    if (tag == SCTAG_HEADER) {
-        MOZ_ALWAYS_TRUE(in.readPair(&tag, &data));
-        storedScope = JS::StructuredCloneScope(data);
-    } else {
+    if (tag != SCTAG_HEADER) {
         // Old structured clone buffer. We must have read it from disk.
         storedScope = JS::StructuredCloneScope::DifferentProcess;
+        return true;
     }
 
-    if (storedScope != JS::StructuredCloneScope::SameProcessSameThread &&
-        storedScope != JS::StructuredCloneScope::SameProcessDifferentThread &&
-        storedScope != JS::StructuredCloneScope::DifferentProcess)
+    MOZ_ALWAYS_TRUE(in.readPair(&tag, &data));
+    storedScope = JS::StructuredCloneScope(data);
+
+    if (data != uint32_t(JS::StructuredCloneScope::SameProcessSameThread) &&
+        data != uint32_t(JS::StructuredCloneScope::SameProcessDifferentThread) &&
+        data != uint32_t(JS::StructuredCloneScope::DifferentProcess))
     {
         JS_ReportErrorNumberASCII(context(), GetErrorMessage, nullptr, JSMSG_SC_BAD_SERIALIZED_DATA,
                                   "invalid structured clone scope");
         return false;
     }
-
-    // Do not check storedScope due to bug 1434308, until bug 1456604 is fixed.
+    if (storedScope < allowedScope) {
+        JS_ReportErrorNumberASCII(context(), GetErrorMessage, nullptr, JSMSG_SC_BAD_SERIALIZED_DATA,
+                                  "incompatible structured clone scope");
+        return false;
+    }
 
     return true;
 }
 
 bool
 JSStructuredCloneReader::readTransferMap()
 {
     JSContext* cx = context();
@@ -2434,22 +2452,20 @@ JSStructuredCloneReader::readTransferMap
         if (!in.readPtr(&content))
             return false;
 
         uint64_t extraData;
         if (!in.read(&extraData))
             return false;
 
         if (tag == SCTAG_TRANSFER_MAP_ARRAY_BUFFER) {
-            if (allowedScope == JS::StructuredCloneScope::DifferentProcess) {
+            if (storedScope == JS::StructuredCloneScope::DifferentProcess) {
                 // Transferred ArrayBuffers in a DifferentProcess clone buffer
-                // are treated as if they weren't Transferred at all. We should
-                // only see SCTAG_TRANSFER_MAP_STORED_ARRAY_BUFFER.
-                ReportDataCloneError(cx, callbacks, JS_SCERR_TRANSFERABLE);
-                return false;
+                // are treated as if they weren't Transferred at all.
+                continue;
             }
 
             size_t nbytes = extraData;
             MOZ_ASSERT(data == JS::SCTAG_TMO_ALLOC_DATA ||
                        data == JS::SCTAG_TMO_MAPPED_DATA);
             if (data == JS::SCTAG_TMO_ALLOC_DATA)
                 obj = JS_NewArrayBufferWithContents(cx, nbytes, content);
             else if (data == JS::SCTAG_TMO_MAPPED_DATA)