CVE-2026-28946
Overview
Background
- Shadow edit element
- DateTimeEditElement renders the editable subfields of date/time inputs and calls back into its owning input type for values and events.
- Type change teardown
- Setting input.type destroys the current InputType object and its shadow subtree, potentially mid-event.
- WeakPtr upgrade to RefPtr
- Converting a weak reference to a RefPtr before use both detects destruction (null) and keeps the object alive for the call.
Root Cause Analysis
This fixes a use-after-free of a date/time input’s edit-control owner when the input’s type changes during an event. DateTimeEditElement (the shadow element hosting editable date fields) referenced its owner (DateTimeEditElementEditControlOwner, implemented by BaseDateAndTimeInputType) through m_editControlOwner as a plain non-owning CanMakeWeakPtr target, and called back into it directly (didReceiveSpaceKeyFromControl, didBlurFromControl, didChangeValueFromControl, value(), placeholderValue(), localeIdentifier(), isFieldOwnerDisabled/ReadOnly, etc.). If author script changes the input’s type while such an event is being handled (e.g. inside an ‘input’ event handler), the BaseDateAndTimeInputType owner is destroyed as the shadow subtree is rebuilt, while the DateTimeEditElement can still invoke m_editControlOwner — dereferencing a freed owner (use-after-free).
The fix makes DateTimeEditElementEditControlOwner derive from AbstractRefCountedAndCanMakeWeakPtr (so it can be ref-counted and weak-tracked), adds ref()/deref() forwarding on BaseDateAndTimeInputType, and changes every call site to upgrade the weak owner to a RefPtr first (if (RefPtr editControlOwner = m_editControlOwner) …), which both null-checks (owner already gone) and keeps the owner alive across the callback. setupDateTimeChooserParameters also converts an ASSERT(element()) into a real null-check returning false.
The restored invariant is that the shadow edit element never calls into an owner that may have been destroyed; it holds a strong reference across each use. The regression test focuses a date input, types digits so an ‘input’ event fires, and in that handler sets input.type=‘text’ (destroying the date input type), expecting no crash.
Attack Path
- Focus a date input Create <input type=date>, focus it, and edit its fields to generate field/input events routed to the DateTimeEditElement.
- Change type mid-event In an input-event handler, set input.type=‘text’, destroying the BaseDateAndTimeInputType owner and rebuilding the shadow subtree.
- Call the freed owner The DateTimeEditElement continues to invoke m_editControlOwner (value()/didChangeValueFromControl/etc.) on the destroyed owner.
- Use-after-free The dangling owner dereference corrupts/crashes the WebContent process.
Impact Assessment
Changed Functions
| Function | Change | Notes |
|---|---|---|
DateTimeEditElement::defaultEventHandler / didBlurFromField / fieldValueChanged / isFieldOwnerDisabled / isFieldOwnerReadOnly / didFieldOwnerTransferFocusToPicker / didSuppressBlurDueToPickerFocusTransfer / localeIdentifier / value / placeholderValueSource/WebCore/html/shadow/DateTimeEditElement.cpp |
modified | Each upgrades m_editControlOwner to a RefPtr (if (RefPtr editControlOwner = m_editControlOwner)) before use, null-checking and keeping the owner alive across the callback. |
DateTimeEditElementEditControlOwnerSource/WebCore/html/shadow/DateTimeEditElement.h |
modified | Now derives from AbstractRefCountedAndCanMakeWeakPtr so the owner can be strongly referenced across callbacks (removing the deprecated raw-weak exception). |
BaseDateAndTimeInputType (ref/deref, setupDateTimeChooserParameters)Source/WebCore/html/BaseDateAndTimeInputType.cpp / .h |
modified | Adds ref()/deref() forwarding to InputType and replaces ASSERT(element()) with a null-check returning false. |
Files Changed
LayoutTests/fast/forms/date/date-editable-components/date-editable-components-change-type-on-input-event-expected.txtLayoutTests/fast/forms/date/date-editable-components/date-editable-components-change-type-on-input-event.htmlSource/WebCore/html/BaseDateAndTimeInputType.cppSource/WebCore/html/BaseDateAndTimeInputType.hSource/WebCore/html/shadow/DateTimeEditElement.cppSource/WebCore/html/shadow/DateTimeEditElement.h
Audit Directions
- Same file: remaining owner usesConfirm every m_editControlOwner dereference in DateTimeEditElement.cpp goes through a RefPtr upgrade, including any picker/chooser paths.
- Shadow owner back-referencesGrep WebCore/html/shadow for members holding an owning InputType/element as raw or CanMakeWeakPtr and dereferenced from event handlers; type changes can free them.