Bug 1355573 - Fix AtomizeAndCopyChars to validate length before taking the lock as it may reenter. r=anba
authorJan de Mooij <jdemooij@mozilla.com>
Mon, 29 May 2017 21:29:11 +0200
changeset 361202 fe64a3b770fd421ee62896bce58369275555281b
parent 361201 4a50cfa3de8009f8e6900ce44a53afa45e28428e
child 361203 2cba4fc3c88a70702bddfaffb10863e10c36d407
push id31918
push usercbook@mozilla.com
push dateTue, 30 May 2017 09:39:11 +0000
treeherdermozilla-central@286f71223256 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersanba
bugs1355573
milestone55.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 1355573 - Fix AtomizeAndCopyChars to validate length before taking the lock as it may reenter. r=anba
js/src/jit-test/tests/basic/bug1355573.js
js/src/jsatom.cpp
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/basic/bug1355573.js
@@ -0,0 +1,6 @@
+// |jit-test| error:overflow
+if (getBuildConfiguration().debug === true)
+    throw "overflow";
+function f(){};
+Object.defineProperty(f, "name", {value: "a".repeat((1<<28)-1)});
+len = f.bind().name.length;
--- a/js/src/jsatom.cpp
+++ b/js/src/jsatom.cpp
@@ -340,32 +340,34 @@ AtomizeAndCopyChars(JSContext* cx, const
         if (pp) {
             JSAtom* atom = pp->asPtr(cx);
             if (zonePtr)
                 mozilla::Unused << zone->atomCache().add(*zonePtr, AtomStateEntry(atom, false));
             return atom;
         }
     }
 
+    // Validate the length before taking the exclusive access lock, as throwing
+    // an exception here may reenter this code.
+    if (MOZ_UNLIKELY(!JSString::validateLength(cx, length)))
+        return nullptr;
+
     AutoLockForExclusiveAccess lock(cx);
 
     AtomSet& atoms = cx->atoms(lock);
     AtomSet::AddPtr p = atoms.lookupForAdd(lookup);
     if (p) {
         JSAtom* atom = p->asPtr(cx);
         p->setPinned(bool(pin));
         cx->atomMarking().inlinedMarkAtom(cx, atom);
         if (zonePtr)
             mozilla::Unused << zone->atomCache().add(*zonePtr, AtomStateEntry(atom, false));
         return atom;
     }
 
-    if (!JSString::validateLength(cx, length))
-        return nullptr;
-
     JSAtom* atom;
     {
         AutoAtomsCompartment ac(cx, lock);
 
         JSFlatString* flat = NewStringCopyN<NoGC>(cx, tbchars, length);
         if (!flat) {
             // Grudgingly forgo last-ditch GC. The alternative would be to release
             // the lock, manually GC here, and retry from the top. If you fix this,