validate event type bounds in windowFunnel state deserialization - #107412
Conversation
|
Workflow [PR], commit [ea2e95b] Summary: ✅
AI ReviewSummaryThis PR hardens Final VerdictStatus: ✅ Approve |
The arm_tidy build failed with cppcoreguidelines-init-variables because event_type was declared without an initializer before the if constexpr branches assign it.
The validation deliberately keeps event type 0 valid under strict_order because existing serialized states use it as the no-event sentinel. Add positive finalizeAggregation cases for windowFunnel(1, 'strict_order') and windowFunnel(1, 'strict_order', 'strict_once') so a regression that moves min_event back to 1 would reject valid stored states and fail.
|
Also fixed the |
…alize-event-bounds
LLVM Coverage Report
Changed lines: Changed C/C++ lines covered by tests: 12/12 (100.00%) | Lost baseline coverage (was covered on master, now uncovered in this PR): 1 line(s) · Uncovered code |
Cherry pick #107412 to 25.8: validate event type bounds in windowFunnel state deserialization
…state deserialization
Cherry pick #107412 to 26.3: validate event type bounds in windowFunnel state deserialization
…state deserialization
Cherry pick #107412 to 26.4: validate event type bounds in windowFunnel state deserialization
…state deserialization
Cherry pick #107412 to 26.5: validate event type bounds in windowFunnel state deserialization
…state deserialization
Backport #107412 to 26.5: validate event type bounds in windowFunnel state deserialization
Backport #107412 to 26.3: validate event type bounds in windowFunnel state deserialization
Backport #107412 to 25.8: validate event type bounds in windowFunnel state deserialization
Backport #107412 to 26.4: validate event type bounds in windowFunnel state deserialization
AddressSanitizer,
getEventLevelNonStrictOnceon a crafted state whose single event byte is 255:windowFunnelreads each event's condition index from the serialized state without a range check, thengetEventLevelNonStrictOnce/getEventLevelStrictOnceuseevent - 1to indexevents_timestamp/event_sequences(both sizedevents_size, the number of conditions, at most 32) and astd::array<UInt64, 32>. An event byte of 255 indexes about 250 elements past the buffer (out-of-bounds read, then a write atevents_timestamp[event - 1]); an event byte of 0 withstrict_orderoff indexes before it. The legitimateaddpath only produces events in[0, events_size], so deserialize is the only place such values enter. Reachable by any user:Before: out-of-range event types from a deserialized state reach the indexing loops.
After: deserialize rejects any event outside
[1, events_size](0only withstrict_order, the no-event sentinel) withINCORRECT_DATA; both the default andstrict_oncestate layouts are covered.The check is one linear pass over the deserialized events, negligible next to the deserialization itself.
Changelog category (leave one):
Changelog entry (a user-readable short description of the changes that goes into CHANGELOG.md):
Fixed a heap buffer overflow (server crash) in
windowFunnelwhen finalizing a crafted aggregate-function state with an out-of-range event type, reachable by any user with a singleSELECT.Version info
26.5.4.9,26.4.5.81,26.3.16.4,25.8.25.33