Firefox · Widget
CVE-2026-12327
Memory Corruption in Widget
Overview
Medium
Severity
—
CVSS
No
Exploited ITW
Fixed
Fix Status
Changed Functions
| Function | Change | Notes |
|---|---|---|
switchwidget/WidgetEventImpl.cpp |
modified |
Files Changed
widget/EventForwards.hwidget/WidgetEventImpl.cppwidget/nsGUIEventIPC.h
Patch
diff --git a/widget/EventForwards.h b/widget/EventForwards.h
index 82cba445004..907fccbf945 100644
--- a/widget/EventForwards.h
+++ b/widget/EventForwards.h
@@ -117,6 +117,15 @@ enum EventClassID : uint8_t {
const char* ToChar(EventClassID aEventClassID);
+/**
+ * Return true if aMessage is a valid EventMessage value for aClassID when an
+ * event is read from another process. This is used to reject events whose
+ * mMessage/mClass combination is inconsistent and therefore likely tampered
+ * with by a compromised content process.
+ */
+[[nodiscard]] bool IsValidMessageForIPC(EventMessage aMessage,
+ EventClassID aClassID);
+
typedef uint16_t Modifiers;
#define NS_DEFINE_KEYNAME(aCPPName, aDOMKeyName) KEY_NAME_INDEX_##aCPPName,
diff --git a/widget/WidgetEventImpl.cpp b/widget/WidgetEventImpl.cpp
index e5ee9b94d70..c4d3b451dd7 100644
--- a/widget/WidgetEventImpl.cpp
+++ b/widget/WidgetEventImpl.cpp
@@ -185,6 +185,75 @@ bool IsForbiddenDispatchingToNonElementContent(EventMessage aMessage) {
}
}
+bool IsValidMessageForIPC(EventMessage aMessage, EventClassID aClassID) {
+ switch (aMessage) {
+ case eKeyDown:
+ case eKeyUp:
+ case eKeyPress:
+ return aClassID == eKeyboardEventClass;
+ case eMouseMove:
+ case eMouseUp:
+ case eMouseDown:
+ case eMouseEnterIntoWidget:
+ case eMouseExitFromWidget:
+ case eMouseDoubleClick:
+ case eMouseActivate:
+ case eMouseOver:
+ case eMouseOut:
+ case eMouseHitTest:
+ case eMouseEnter:
+ case eMouseLeave:
+ case eMouseTouchDrag:
+ case eMouseLongTap:
+ case eMouseExploreByTouch:
+ return aClassID == eMouseEventClass;
+ case eWheel:
+ case eWheelOperationStart:
+ case eWheelOperationEnd:
+ return aClassID == eWheelEventClass;
+ case eDragEnter:
+ case eDragOver:
+ case eDragExit:
+ case eDrag:
+ case eDragEnd:
+ case eDragStart:
+ case eDrop:
+ case eDragLeave:
+ return aClassID == eDragEventClass;
+ case ePointerMove:
+ case ePointerUp:
+ case ePointerDown:
+ case ePointerOver:
+ case ePointerOut:
+ case ePointerEnter:
+ case ePointerLeave:
+ case ePointerCancel:
+ case ePointerRawUpdate:
+ case ePointerGotCapture:
+ case ePointerLostCapture:
+ case ePointerClick:
+ case ePointerAuxClick:
+ case eContextMenu:
+ return aClassID == ePointerEventClass;
+ case eTouchStart:
+ case eTouchMove:
+ case eTouchEnd:
+ case eTouchCancel:
+ case eTouchPointerCancel:
+ return aClassID == eTouchEventClass;
+ case eCompositionStart:
+ case eCompositionEnd:
+ case eCompositionChange:
+ case eCompositionCommitAsIs:
+ case eCompositionCommit:
+ return aClassID == eCompositionEventClass;
+ case eSetSelection:
+ return aClassID == eSelectionEventClass;
+ default:
+ return false;
+ }
+}
+
const char* ToChar(EventClassID aEventClassID) {
switch (aEventClassID) {
#define NS_ROOT_EVENT_CLASS(aPrefix, aName) \
diff --git a/widget/nsGUIEventIPC.h b/widget/nsGUIEventIPC.h
index f9f005abac0..baf960fdb59 100644
--- a/widget/nsGUIEventIPC.h
+++ b/widget/nsGUIEventIPC.h
@@ -83,13 +83,15 @@ struct ParamTraits<mozilla::WidgetEvent> {
ToChar(aExpectedEventClassID), ToChar(aResult->mClass),
ToChar(aResult->mMessage))
.c_str());
- if (aResult->mClass == aExpectedEventClassID) [[likely]] {
+ if (aResult->mClass == aExpectedEventClassID &&
+ mozilla::IsValidMessageForIPC(aResult->mMessage, aExpectedEventClassID))
+ [[likely]] {
return true;
}
// Clear mClass value to avoid the assertion failure in the destructor in
// the debug build because it's not a fault in this process.
aResult->mClass = mozilla::eEventClassUninitialized;
- // Don't allow illegal mClass value.
+ // Don't allow illegal mClass/mMessage combination.
return false;
}
Loading diff…
References
On This Page