Skip to content

Fix stack buffer overflows in h5repack parse_filter (fixes #6433)#6434

Open
brtnfld wants to merge 3 commits into
HDFGroup:developfrom
brtnfld:fix/h5repack-parse-stype-overflow
Open

Fix stack buffer overflows in h5repack parse_filter (fixes #6433)#6434
brtnfld wants to merge 3 commits into
HDFGroup:developfrom
brtnfld:fix/h5repack-parse-stype-overflow

Conversation

@brtnfld

@brtnfld brtnfld commented Jun 5, 2026

Copy link
Copy Markdown
Collaborator

Summary

Fixes #6433, three stack buffer overflow vulnerabilities in parse_filter() in tools/src/h5repack/h5repack_parse.c, reported in #6433.

  • All five write sites for the scomp[16], stype[16], and smask[16] parse buffers are now guarded by a PARSE_BUF_WRITE macro that performs a bounds check before each character write.
  • The macro takes an explicit buf_sz argument (passed as sizeof(buf) at every call site) to prevent silent pointer-decay if the buffers are ever refactored to heap allocations.
  • In the SZIP and SOFF inner u loops, the prior code wrote bare smask[l] = c with no bounds check and used i = len - 1 to stop the outer loop without breaking the inner loop. A trailing-garbage input such as -f SZIP=16,NNxxx could therefore write past smask[2]. Both sites now use PARSE_BUF_WRITE and add an explicit break to exit the inner loop as soon as the two-character mask is complete.
  • The redundant if (obj_list_ptr) guard before free() is removed; free(NULL) is a safe no-op per C99 §7.20.3.2.

brtnfld added 2 commits June 5, 2026 17:11
Five sites in parse_filter() wrote to fixed 16-byte stack buffers
(scomp[16], stype[16]) via unbounded loop indices with no prior bounds
check, causing a stack-buffer-overflow on malformed -f arguments:

  Site 1: scomp[k]  - filter name token before '='
  Site 2: stype[m]  - SZIP pixels_per_block digit sequence
  Site 3: stype[m]  - SOFF scale_factor digit sequence
  Site 4: stype[q]  - UD legacy per-field digit sequence
  Site 5: stype[m]  - all-other-filters digit sequence

Replace all five bare array writes with a single PARSE_BUF_WRITE macro
that checks the index against sizeof(buf)-1 before writing, then frees
obj_list and exits with an error message on overflow — consistent with
all other error handling in parse_filter().

Confirmed with AddressSanitizer: overflow is eliminated and invalid
over-long arguments produce a clean diagnostic exit instead of UB.
All five overflow sites in parse_filter() are now protected via a
PARSE_BUF_WRITE macro that takes an explicit buf_sz argument (passed as
sizeof(buf) at every call site) to avoid silent pointer-decay if the
buffers are ever refactored to heap allocations.

In the SZIP and SOFF inner loops the previous code wrote bare
`smask[l] = c` with no bounds check, and relied on `i = len - 1` to
stop the *outer* loop without also breaking the *inner* `u` loop.
That left one additional iteration where `l` could equal 2 and
`smask[2]` would be written by the next outer iteration before the
outer loop condition was re-evaluated.  Both sites now use
PARSE_BUF_WRITE and add an explicit `break` to exit the inner loop
as soon as the two-character mask is complete.

The NULL guard around free(obj_list_ptr) is removed: free(NULL) is a
safe no-op per C99 §7.20.3.2.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: To be triaged

Development

Successfully merging this pull request may close these issues.

h5repack_parse.c: stack buffer overflows in filter string parser (scomp/stype[16] unbounded writes)

1 participant