Skip to content

fix: harden query path — hdr_mean overflow + count accessor OOB reads - #147

Open
filipecosta90 wants to merge 2 commits into
mainfrom
fix/mean-and-count-bounds
Open

fix: harden query path — hdr_mean overflow + count accessor OOB reads#147
filipecosta90 wants to merge 2 commits into
mainfrom
fix/mean-and-count-bounds

Conversation

@filipecosta90

Copy link
Copy Markdown
Contributor

Two more fuzzing-surfaced bugs in the query path (found by adversarial review during the ClusterFuzzLite effort).

1. hdr_mean — signed int64 overflow (UBSan), fuzz-reachable

total += iter.count * hdr_median_equivalent_value(...) accumulated in int64. For a histogram holding values near 2^62, a few samples overflow INT64_MAX → signed-overflow UB and a wrapped/negative mean. log_reader_fuzzer calls hdr_mean on every decoded histogram, so a crafted large-range log reaches it. Fix: accumulate in double (exactly what hdr_stddev already does).

2. hdr_count_at_value — out-of-bounds read (ASan)

It indexed counts[] via counts_index_for() with no range check, so querying a value beyond highest_trackable_value read past the array. Fix: mirror hdr_record_values' guard (value range + (uint32_t)index >= (uint32_t)counts_len) and return 0 — an untracked value has count 0.

Verification (local, ASan+UBSan)

  • Before: hdr_meanruntime error: signed integer overflow ... at hdr_histogram.c:832; hdr_count_at_value(h, INT64_MAX) → ASan heap-buffer-overflow READ.
  • After: hdr_mean returns a positive finite value; hdr_count_at_value returns 0. Added regression tests; full suite passes under ASan+UBSan.

The ASan/UBSan ctest CI job that makes these regression tests deterministic guards is added in #145.

🤖 Generated with Claude Code

fcostaoliveira and others added 2 commits July 23, 2026 18:48
Two more issues found by adversarial review during the ClusterFuzzLite effort:

- hdr_mean summed iter.count * hdr_median_equivalent_value in an int64 running
  total. For a histogram holding values near 2^62 this overflows INT64_MAX
  (signed-overflow UB) and yields a garbage/negative mean. Reachable via the
  fuzz surface (log_reader_fuzzer calls hdr_mean on every decoded histogram).
  Accumulate in double, as hdr_stddev already does.

- hdr_count_at_value indexed counts[] via counts_index_for() with no range
  check, so a value beyond highest_trackable_value read out of bounds. Mirror
  hdr_record_values' guard and return 0 for out-of-range values.

Verified under ASan+UBSan: main aborts (UBSan signed overflow in hdr_mean;
ASan OOB read in hdr_count_at_value); both return clean results after the fix.
Added regression tests.

Found-by: adversarial review during the ClusterFuzzLite fuzzing effort
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Adversarial review of the hdr_count_at_value fix flagged its index-based twin
hdr_count_at_index as having the identical unchecked out-of-bounds read (raw
caller index -> counts_get_normalised -> h->counts[index]). Guard it the same
way (return 0 for an out-of-range index; the unsigned compare also catches
negatives). All in-tree callers pass in-range indices.

Also strengthen the regression tests per review: pin hdr_mean to a plausible
magnitude band (not just sign/finiteness), assert in-range and the
value==highest boundary for hdr_count_at_value (catchable without a sanitizer),
and add an out-of-range test for hdr_count_at_index.

(Note: hdr_value_at_index's shift UB at an extreme index is left as a
documented precondition -- it performs no counts[] access and guarding it would
change the internal peek at index==counts_len; tracked separately.)

Found-by: adversarial review during the ClusterFuzzLite fuzzing effort
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@filipecosta90 filipecosta90 changed the title fix: hdr_mean int64 overflow (UBSan) + hdr_count_at_value OOB read (ASan) fix: harden query path — hdr_mean overflow + count accessor OOB reads Jul 23, 2026
@filipecosta90
filipecosta90 requested review from giltene and mikeb01 July 24, 2026 09:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants