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 409319 fe64a3b770fd421ee62896bce58369275555281b
parent 409318 4a50cfa3de8009f8e6900ce44a53afa45e28428e
child 409320 2cba4fc3c88a70702bddfaffb10863e10c36d407
push id7391
push usermtabara@mozilla.com
push dateMon, 12 Jun 2017 13:08:53 +0000
treeherdermozilla-beta@2191d7f87e2e [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,