Visitar URL original
fix: use-after-free when event handlers re-enter chooser, protocol stream, webauthn and local AI code by trop[bot] · Pull Request #53269 · electron/electron · GitHub
Skip to content

fix: use-after-free when event handlers re-enter chooser, protocol stream, webauthn and local AI code - #53269

Merged
jkleinsc merged 6 commits into
45-x-yfrom
trop/45-x-y-bp-fix-use-after-free-when-event-handlers-re-enter-chooser-protocol-stream-webauthn-and-local-ai-code-1787911124719
Aug 28, 2026
Merged

jkleinsc merged 6 commits into
45-x-yfrom
trop/45-x-y-bp-fix-use-after-free-when-event-handlers-re-enter-chooser-protocol-stream-webauthn-and-local-ai-code-1787911124719

Conversation

@trop

@trop trop Bot commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

Backport of #53258

See that PR for details.

Notes: Fixed crashes when certain app event handlers call back into Electron synchronously.

trop Bot and others added 6 commits August 28, 2026 09:58
Running the callback from inside the 'select-bluetooth-device' handler
completes the request, and the content layer deletes the chooser in
response. ShowDiscoveryState and AddOrUpdateDevice then carried on and
ran event_handler_ on the destroyed object when the handler had not
called preventDefault. Check a weak pointer to ourselves after the emit
and bail out if the chooser is gone.

Co-authored-by: Sam Attard <sattard@anthropic.com>
HidChooserController emits 'select-hid-device' and 'hid-device-removed'
on the session and then keeps using its own members. If the handler
tears down the requesting frame (e.g. destroys a guest webContents,
which is deleted synchronously) RenderFrameDeleted removes the
controller from ElectronHidDelegate's map and the code after the emit
runs on a freed object. Check a weak pointer after each emit and return
early if the controller has been destroyed.

Co-authored-by: Sam Attard <sattard@anthropic.com>
…ntly

NodeStreamLoader calls the stream's on(), removeListener() and destroy()
methods, which are user JS. A stream whose on() invokes the 'end' or
'error' listener synchronously ran NotifyComplete() and deleted the
loader while Start() was still subscribing the remaining events, and a
removeListener()/destroy() that invoked a listener from inside the
destructor re-entered NotifyComplete() and deleted the loader a second
time. Check the weak pointer between subscriptions in Start(), and
invalidate weak pointers at the top of the destructor so the weakly
bound listeners are no-ops during teardown.

Co-authored-by: Sam Attard <sattard@anthropic.com>
…ng back

Invoking the callback from a 'select-webauthn-account' or
'select-webauthn-authenticator' listener completes the request
synchronously, and the content layer destroys the request delegate as
part of that. If the listener then threw, emit() reported no listener
and the delegate went on to cancel / dispatch the default on an object
that had already been freed. Check a weak pointer to ourselves after
the emit in both SelectAccount and MaybeEmitSelectAuthenticator.

Co-authored-by: Sam Attard <sattard@anthropic.com>
When a pending LanguageModel.create() or append() was cancelled from the
renderer, the utility-side disconnect handler looked up the request's
AbortController in a flat_hash_map and called abort() on it while still
holding the iterator. abort() fires the signal listeners and then runs a
microtask checkpoint, so a handler that rejects on abort settles the
promise right there and the reaction erases the same map entry; the
erase(it) that followed then operated on a dead slot and tripped the
hardened swisstable check. Take the controller out of the map and erase
the entry before calling into JS.

Co-authored-by: Sam Attard <sattard@anthropic.com>
…steners

ElectronRenderFrameObserver notified isolated world creation by walking
its callback vector with a range-for and running each JS callback in
turn. A listener that subscribes further webFrame wrappers to
'isolated-world-created' appends to that same vector, and once it
reallocates the loop carries on through freed storage. Iterate over a
copy of the callbacks instead.

Co-authored-by: Sam Attard <sattard@anthropic.com>
@trop
trop Bot requested a review from MarshallOfSound August 28, 2026 09:59
@trop trop Bot added 45-x-y backport This is a backport PR semver/patch backwards-compatible bug fixes labels Aug 28, 2026
@jkleinsc
jkleinsc merged commit 39e3a2b into 45-x-y Aug 28, 2026
99 checks passed
@release-clerk

release-clerk Bot commented Aug 28, 2026

Copy link
Copy Markdown

Release Notes Persisted

Fixed crashes when certain app event handlers call back into Electron synchronously.

@jkleinsc
jkleinsc deleted the trop/45-x-y-bp-fix-use-after-free-when-event-handlers-re-enter-chooser-protocol-stream-webauthn-and-local-ai-code-1787911124719 branch August 28, 2026 13:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

45-x-y backport This is a backport PR semver/patch backwards-compatible bug fixes

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

1 participant