Closed Bug 1803682 Opened 2 years ago Closed 2 years ago

If CreateInterfaceObjects fails, call right below might try to reenter, causing stack exhaustion

Categories

(Core :: DOM: Bindings (WebIDL), defect)

defect

Tracking

()

RESOLVED DUPLICATE of bug 1746997

People

(Reporter: emilio, Assigned: emilio)

References

Details

Attachments

(1 obsolete file)

See Also: → 1803675

Here is a search for crashes that might be this issue. Basically, where the signature contains stackoverflow and the proto signature contains CreateInterfaceObjects. (The date is in there so if you do this much later it might not work.)

The code before this patch could end up looking like this:

JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::FontFaceSet);
JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::FontFaceSet);
dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
                            &sPrototypeClass.mBase, protoCache,
                            constructorProto, &sInterfaceObjectClass.mBase, 0, false, nullptr,
                            interfaceCache,
                            sNativeProperties.Upcast(),
                            nullptr,
                            "FontFaceSet", aDefineOnGlobal,
                            nullptr,
                            false,
                            nullptr,
                            false);

// Set up aliases on the interface prototype object we just created.
JS::Handle<JSObject*> proto = GetProtoObjectHandle(aCx);

If CreateInterfaceObjects() fails (leaving protoCache null),
GetProtoObjectHandle() would reenter CreateInterfaceObjects(), causing
stack exhaustion.

After this patch the code looks like:

JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::FontFaceSet);
JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::FontFaceSet);
dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
                            &sPrototypeClass.mBase, protoCache,
                            constructorProto, &sInterfaceObjectClass.mBase, 0, false, nullptr,
                            interfaceCache,
                            sNativeProperties.Upcast(),
                            nullptr,
                            "FontFaceSet", aDefineOnGlobal,
                            nullptr,
                            false,
                            nullptr,
                            false);
if (!*protoCache) {
  MOZ_ASSERT_IF(interfaceCache, !*interfaceCache);
  return;
}

// Set up aliases on the interface prototype object we just created.
JS::AssertObjectIsNotGray(*protoCache);
auto proto = JS::Handle<JSObject*>::fromMarkedLocation(protoCache->address());
MOZ_ASSERT(proto);

Which should handle failure properly.

Assignee: nobody → emilio
Status: NEW → ASSIGNED
Status: ASSIGNED → RESOLVED
Closed: 2 years ago
Duplicate of bug: 1746997
Resolution: --- → DUPLICATE
Attachment #9306336 - Attachment is obsolete: true
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: