Firefox · Core
CVE-2026-2807
Memory Corruption in Core
Overview
High
Severity
—
CVSS
No
Exploited ITW
Fixed
Fix Status
Changed Functions
| Function | Change | Notes |
|---|---|---|
ifmobile/shared/actors/ContentDelegateChild.sys.mjs |
modified | |
actorCreatedmobile/shared/actors/GeckoViewContentChild.sys.mjs |
modified | |
switchmobile/shared/actors/GeckoViewContentParent.sys.mjs |
modified | |
restoreStatemobile/shared/actors/GeckoViewContentParent.sys.mjs |
modified | |
ifmobile/shared/actors/GeckoViewContentParent.sys.mjs |
modified | |
getMediaPermissionmobile/shared/actors/GeckoViewPermissionChild.sys.mjs |
modified | |
mediaRecordingStatusChangedmobile/shared/actors/GeckoViewPermissionChild.sys.mjs |
modified | |
dismissPromptmobile/shared/actors/GeckoViewPrompterChild.sys.mjs |
modified | |
updatePromptmobile/shared/actors/GeckoViewPrompterChild.sys.mjs |
modified | |
switchmobile/shared/actors/LoadURIDelegateParent.sys.mjs |
modified | |
ifmobile/shared/actors/MediaControlDelegateChild.sys.mjs |
modified | |
switchmobile/shared/actors/MediaControlDelegateParent.sys.mjs |
modified |
Files Changed
mobile/shared/actors/ContentDelegateChild.sys.mjsmobile/shared/actors/ContentDelegateParent.sys.mjsmobile/shared/actors/GeckoViewContentChild.sys.mjsmobile/shared/actors/GeckoViewContentParent.sys.mjsmobile/shared/actors/GeckoViewPermissionChild.sys.mjsmobile/shared/actors/GeckoViewPermissionParent.sys.mjsmobile/shared/actors/GeckoViewPrompterChild.sys.mjsmobile/shared/actors/GeckoViewPrompterParent.sys.mjsmobile/shared/actors/LoadURIDelegateChild.sys.mjsmobile/shared/actors/LoadURIDelegateParent.sys.mjsmobile/shared/actors/MediaControlDelegateChild.sys.mjsmobile/shared/actors/MediaControlDelegateParent.sys.mjsmobile/shared/actors/ScrollDelegateChild.sys.mjsmobile/shared/actors/ScrollDelegateParent.sys.mjsmobile/shared/actors/SelectionActionDelegateChild.sys.mjsmobile/shared/actors/SelectionActionDelegateParent.sys.mjsmobile/shared/modules/geckoview/GeckoViewActorChild.sys.mjsmobile/shared/modules/geckoview/GeckoViewActorParent.sys.mjsmobile/shared/modules/geckoview/LoadURIDelegate.sys.mjsmobile/shared/modules/geckoview/Messaging.sys.mjs
Patch
diff --git a/mobile/shared/actors/ContentDelegateChild.sys.mjs b/mobile/shared/actors/ContentDelegateChild.sys.mjs
index 5269fe3fd9b..f5a30687b2c 100644
--- a/mobile/shared/actors/ContentDelegateChild.sys.mjs
+++ b/mobile/shared/actors/ContentDelegateChild.sys.mjs
@@ -27,10 +27,7 @@ export class ContentDelegateChild extends GeckoViewActorChild {
return;
}
this.lastViewportFit = viewportFit;
- this.eventDispatcher.sendRequest({
- type: "GeckoView:DOMMetaViewportFit",
- viewportfit: viewportFit,
- });
+ this.sendAsyncMessage("GeckoView:DOMMetaViewportFit", viewportFit);
}
);
}
@@ -179,7 +176,6 @@ export class ContentDelegateChild extends GeckoViewActorChild {
if (uri || isImage || isMedia) {
const msg = {
- type: "GeckoView:ContextMenu",
// We don't have full zoom on Android, so using CSS coordinates
// here is fine, since the CSS coordinate spaces match between the
// child and parent processes.
@@ -200,13 +196,13 @@ export class ContentDelegateChild extends GeckoViewActorChild {
null,
};
- this.eventDispatcher.sendRequest(msg);
+ this.sendAsyncMessage("GeckoView:ContextMenu", msg);
aEvent.preventDefault();
}
break;
}
case "MozDOMFullscreen:Request": {
- this.sendAsyncMessage("GeckoView:DOMFullscreenRequest", {});
+ this.sendAsyncMessage("GeckoView:DOMFullscreenRequest");
break;
}
case "MozDOMFullscreen:Entered":
@@ -219,7 +215,7 @@ export class ContentDelegateChild extends GeckoViewActorChild {
}
// fall-through
case "MozDOMFullscreen:Exit":
- this.sendAsyncMessage("GeckoView:DOMFullscreenExit", {});
+ this.sendAsyncMessage("GeckoView:DOMFullscreenExit");
break;
case "DOMMetaViewportFitChanged":
if (aEvent.originalTarget.ownerGlobal == this.contentWindow) {
@@ -241,24 +237,17 @@ export class ContentDelegateChild extends GeckoViewActorChild {
this.contentWindow
);
if (manifest) {
- this.eventDispatcher.sendRequest({
- type: "GeckoView:WebAppManifest",
- manifest,
- });
+ this.sendAsyncMessage("GeckoView:WebAppManifest", manifest);
}
});
break;
}
case "MozFirstContentfulPaint": {
- this.eventDispatcher.sendRequest({
- type: "GeckoView:FirstContentfulPaint",
- });
+ this.sendAsyncMessage("GeckoView:FirstContentfulPaint");
break;
}
case "MozPaintStatusReset": {
- this.eventDispatcher.sendRequest({
- type: "GeckoView:PaintStatusReset",
- });
+ this.sendAsyncMessage("GeckoView:PaintStatusReset");
break;
}
}
diff --git a/mobile/shared/actors/ContentDelegateParent.sys.mjs b/mobile/shared/actors/ContentDelegateParent.sys.mjs
index d621c801047..f11fde38f52 100644
--- a/mobile/shared/actors/ContentDelegateParent.sys.mjs
+++ b/mobile/shared/actors/ContentDelegateParent.sys.mjs
@@ -29,6 +29,39 @@ export class ContentDelegateParent extends GeckoViewActorParent {
this.window.windowUtils.remoteFrameFullscreenChanged(this.browser);
return null;
}
+
+ case "GeckoView:DOMMetaViewportFit": {
+ return this.eventDispatcher.sendRequest({
+ viewportfit: aMsg.data,
+ type: "GeckoView:DOMMetaViewportFit",
+ });
+ }
+
+ case "GeckoView:ContextMenu": {
+ return this.eventDispatcher.sendRequest({
+ ...aMsg.data,
+ type: "GeckoView:ContextMenu",
+ });
+ }
+
+ case "GeckoView:WebAppManifest": {
+ return this.eventDispatcher.sendRequest({
+ manifest: aMsg.data,
+ type: "GeckoView:WebAppManifest",
+ });
+ }
+
+ case "GeckoView:FirstContentfulPaint": {
+ return this.eventDispatcher.sendRequest({
+ type: "GeckoView:FirstContentfulPaint",
+ });
+ }
+
+ case "GeckoView:PaintStatusReset": {
+ return this.eventDispatcher.sendRequest({
+ type: "GeckoView:PaintStatusReset",
+ });
+ }
}
return super.receiveMessage(aMsg);
diff --git a/mobile/shared/actors/GeckoViewContentChild.sys.mjs b/mobile/shared/actors/GeckoViewContentChild.sys.mjs
index 23cfc73de50..cef3910b568 100644
--- a/mobile/shared/actors/GeckoViewContentChild.sys.mjs
+++ b/mobile/shared/actors/GeckoViewContentChild.sys.mjs
@@ -32,8 +32,6 @@ export class GeckoViewContentChild extends GeckoViewActorChild {
}
actorCreated() {
- super.actorCreated();
-
this.pageShow = new Promise(resolve => {
this.receivedPageShow = resolve;
});
@@ -335,8 +333,7 @@ export class GeckoViewContentChild extends GeckoViewActorChild {
aEvent.reason === "presscaret" ||
aEvent.reason === "releasecaret"
) {
- this.eventDispatcher.sendRequest({
- type: "GeckoView:PinOnScreen",
+ this.sendAsyncMessage("GeckoView:PinOnScreen", {
pinned: aEvent.reason === "presscaret",
});
}
diff --git a/mobile/shared/actors/GeckoViewContentParent.sys.mjs b/mobile/shared/actors/GeckoViewContentParent.sys.mjs
index 069894ba967..8f61cfaf64c 100644
--- a/mobile/shared/actors/GeckoViewContentParent.sys.mjs
+++ b/mobile/shared/actors/GeckoViewContentParent.sys.mjs
@@ -28,6 +28,20 @@ export class GeckoViewContentParent extends GeckoViewActorParent {
return this.sendQuery("ContainsFormData");
}
+ async receiveMessage(aMsg) {
+ switch (aMsg.name) {
+ case "GeckoView:PinOnScreen": {
+ return this.eventDispatcher.sendRequest({
+ ...aMsg.data,
+ type: "GeckoView:PinOnScreen",
+ });
+ }
+ default: {
+ return super.receiveMessage(aMsg);
+ }
+ }
+ }
+
restoreState({ history, switchId, formdata, scrolldata }) {
if (Services.appinfo.sessionHistoryInParent) {
const { browsingContext } = this.browser;
diff --git a/mobile/shared/actors/GeckoViewPermissionChild.sys.mjs b/mobile/shared/actors/GeckoViewPermissionChild.sys.mjs
index bbe9457cc5e..d454250bb56 100644
--- a/mobile/shared/actors/GeckoViewPermissionChild.sys.mjs
+++ b/mobile/shared/actors/GeckoViewPermissionChild.sys.mjs
@@ -20,8 +20,7 @@ const MAPPED_TO_EXTENSION_PERMISSIONS = [
export class GeckoViewPermissionChild extends GeckoViewActorChild {
getMediaPermission(aPermission) {
- return this.eventDispatcher.sendRequestForResult({
- type: "GeckoView:MediaPermission",
+ return this.sendQuery("GeckoView:MediaPermission", {
...aPermission,
});
}
@@ -35,8 +34,7 @@ export class GeckoViewPermissionChild extends GeckoViewActorChild {
}
mediaRecordingStatusChanged(aDevices) {
- return this.eventDispatcher.sendRequest({
- type: "GeckoView:MediaRecordingStatusChanged",
+ return this.sendAsyncMessage("GeckoView:MediaRecordingStatusChanged", {
devices: aDevices,
});
}
@@ -132,8 +130,7 @@ export class GeckoViewPermissionChild extends GeckoViewActorChild {
let allowOrDeny;
try {
- allowOrDeny = await this.eventDispatcher.sendRequestForResult({
- type: "GeckoView:ContentPermission",
+ allowOrDeny = await this.sendQuery("GeckoView:ContentPermission", {
uri: principal.URI.displaySpec,
thirdPartyOrigin: aRequest.principal.origin,
principal: lazy.E10SUtils.serializePrincipal(principal),
diff --git a/mobile/shared/actors/GeckoViewPermissionParent.sys.mjs b/mobile/shared/actors/GeckoViewPermissionParent.sys.mjs
index c4a5cf56cf0..867fc31bdbd 100644
--- a/mobile/shared/actors/GeckoViewPermissionParent.sys.mjs
+++ b/mobile/shared/actors/GeckoViewPermissionParent.sys.mjs
@@ -56,6 +56,24 @@ export class GeckoViewPermissionParent extends GeckoViewActorParent {
case "AddCameraPermission": {
return this.addCameraPermission();
}
+ case "GeckoView:MediaPermission": {
+ return this.eventDispatcher.sendRequestForResult({
+ ...aMessage.data,
+ type: "GeckoView:MediaPermission",
+ });
+ }
+ case "GeckoView:MediaRecordingStatusChanged": {
+ return this.eventDispatcher.sendRequest({
+ ...aMessage.data,
+ type: "GeckoView:MediaRecordingStatusChanged",
+ });
+ }
+ case "GeckoView:ContentPermission": {
+ return this.eventDispatcher.sendRequestForResult({
+ ...aMessage.data,
+ type: "GeckoView:ContentPermission",
+ });
+ }
}
return super.receiveMessage(aMessage);
diff --git a/mobile/shared/actors/GeckoViewPrompterChild.sys.mjs b/mobile/shared/actors/GeckoViewPrompterChild.sys.mjs
index bb8c4fbcff5..dd84f554cc1 100644
--- a/mobile/shared/actors/GeckoViewPrompterChild.sys.mjs
+++ b/mobile/shared/actors/GeckoViewPrompterChild.sys.mjs
@@ -11,16 +11,14 @@ export class GeckoViewPrompterChild extends GeckoViewActorChild {
}
dismissPrompt(prompt) {
- this.eventDispatcher.sendRequest({
- type: "GeckoView:Prompt:Dismiss",
+ this.sendAsyncMessage("GeckoView:Prompt:Dismiss", {
id: prompt.id,
});
this.unregisterPrompt(prompt);
}
updatePrompt(message) {
- this.eventDispatcher.sendRequest({
- type: "GeckoView:Prompt:Update",
+ this.sendAsyncMessage("GeckoView:Prompt:Update", {
prompt: message,
});
}
@@ -41,8 +39,7 @@ export class GeckoViewPrompterChild extends GeckoViewActorChild {
// We intentionally do not await here as we want to fire NotifyPromptShow
// immediately rather than waiting until the user accepts/dismisses the
// prompt.
- const result = this.eventDispatcher.sendRequestForResult({
- type: "GeckoView:Prompt",
+ const result = this.sendQuery("GeckoView:Prompt", {
prompt: message,
});
this.sendAsyncMessage("NotifyPromptShow", {
diff --git a/mobile/shared/actors/GeckoViewPrompterParent.sys.mjs b/mobile/shared/actors/GeckoViewPrompterParent.sys.mjs
index 24b763b114b..6f4d0f76f11 100644
--- a/mobile/shared/actors/GeckoViewPrompterParent.sys.mjs
+++ b/mobile/shared/actors/GeckoViewPrompterParent.sys.mjs
@@ -122,6 +122,26 @@ export class GeckoViewPrompterParent extends GeckoViewActorParent {
this.rootActor.notifyPromptShow(data.id);
break;
}
+ case "GeckoView:Prompt:Dismiss": {
+ return this.eventDispatcher.sendRequest({
+ ...data,
+ type: "GeckoView:Prompt:Dismiss",
+ });
+ break;
+ }
+ case "GeckoView:Prompt:Update": {
+ this.eventDispatcher.sendRequest({
+ ...data,
+ type: "GeckoView:Prompt:Update",
+ });
+ break;
+ }
+ case "GeckoView:Prompt": {
+ return this.eventDispatcher.sendRequestForResult({
+ ...data,
+ type: "GeckoView:Prompt",
+ });
+ }
default: {
return super.receiveMessage({ name, data });
}
diff --git a/mobile/shared/actors/LoadURIDelegateChild.sys.mjs b/mobile/shared/actors/LoadURIDelegateChild.sys.mjs
index 80ab0db0bc1..8a22300f297 100644
--- a/mobile/shared/actors/LoadURIDelegateChild.sys.mjs
+++ b/mobile/shared/actors/LoadURIDelegateChild.sys.mjs
@@ -17,13 +17,26 @@ export class LoadURIDelegateChild extends GeckoViewActorChild {
debug`handleLoadError: uri=${aUri && aUri.spec}
displaySpec=${aUri && aUri.displaySpec}
error=${aError}`;
+ let errorClass = 0;
+ try {
+ const nssErrorsService = Cc[
+ "@mozilla.org/nss_errors_service;1"
+ ].getService(Ci.nsINSSErrorsService);
+ errorClass = nssErrorsService.getErrorClass(aError);
+ } catch (e) {}
+
+ const msg = {
+ uri: aUri && aUri.spec,
+ error: aError,
+ errorModule: aErrorModule,
+ errorClass,
+ };
+
+ let errorPagePromise = this.sendQuery("GeckoView:OnLoadError", msg);
return lazy.LoadURIDelegate.handleLoadError(
this.contentWindow,
- this.eventDispatcher,
- aUri,
- aError,
- aErrorModule
+ errorPagePromise
);
}
}
diff --git a/mobile/shared/actors/LoadURIDelegateParent.sys.mjs b/mobile/shared/actors/LoadURIDelegateParent.sys.mjs
index 0446d7d88a4..ead98dc1130 100644
--- a/mobile/shared/actors/LoadURIDelegateParent.sys.mjs
+++ b/mobile/shared/actors/LoadURIDelegateParent.sys.mjs
@@ -4,5 +4,18 @@
import { GeckoViewActorParent } from "resource://gre/modules/GeckoViewActorParent.sys.mjs";
-// For this.eventDispatcher in the child
-export class LoadURIDelegateParent extends GeckoViewActorParent {}
+export class LoadURIDelegateParent extends GeckoViewActorParent {
+ async receiveMessage({ name, data }) {
+ switch (name) {
+ case "GeckoView:OnLoadError": {
+ return this.eventDispatcher.sendRequestForResult({
+ ...data,
+ type: "GeckoView:OnLoadError",
+ });
+ }
+ default: {
+ return super.receiveMessage({ name, data });
+ }
+ }
+ }
+}
diff --git a/mobile/shared/actors/MediaControlDelegateChild.sys.mjs b/mobile/shared/actors/MediaControlDelegateChild.sys.mjs
index 1db32b33f05..0fa1daabd47 100644
--- a/mobile/shared/actors/MediaControlDelegateChild.sys.mjs
+++ b/mobile/shared/actors/MediaControlDelegateChild.sys.mjs
@@ -34,11 +34,13 @@ export class MediaControlDelegateChild extends GeckoViewActorChild {
debug`No fullscreen media element found.`;
}
- const activated = await this.eventDispatcher.sendRequestForResult({
- type: "GeckoView:MediaSession:Fullscreen",
- metadata: lazy.MediaUtils.getMetadata(mediaElement) ?? {},
- enabled: !!element,
- });
+ const activated = await this.sendQuery(
+ "GeckoView:MediaSession:Fullscreen",
+ {
+ metadata: lazy.MediaUtils.getMetadata(mediaElement) ?? {},
+ enabled: !!element,
+ }
+ );
if (activated) {
return;
}
diff --git a/mobile/shared/actors/MediaControlDelegateParent.sys.mjs b/mobile/shared/actors/MediaControlDelegateParent.sys.mjs
index f0c3f479846..ad19dcf9f23 100644
--- a/mobile/shared/actors/MediaControlDelegateParent.sys.mjs
+++ b/mobile/shared/actors/MediaControlDelegateParent.sys.mjs
@@ -4,5 +4,18 @@
import { GeckoViewActorParent } from "resource://gre/modules/GeckoViewActorParent.sys.mjs";
-// For this.eventDispatcher in the child
-export class MediaControlDelegateParent extends GeckoViewActorParent {}
+export class MediaControlDelegateParent extends GeckoViewActorParent {
+ async receiveMessage({ name, data }) {
+ switch (name) {
+ case "GeckoView:MediaSession:Fullscreen": {
+ return this.eventDispatcher.sendRequestForResult({
+ ...data,
+ type: "GeckoView:MediaSession:Fullscreen",
+ });
+ }
+ default: {
+ return super.receiveMessage({ name, data });
... (file diff truncated)
Loading diff…
References
On This Page