Fix negative bodysize leading to heap overflow in ogg_stream_pagein#102
Open
MH1983-web wants to merge 1 commit into
Open
Fix negative bodysize leading to heap overflow in ogg_stream_pagein#102MH1983-web wants to merge 1 commit into
MH1983-web wants to merge 1 commit into
Conversation
A page whose segment table is inconsistent with body_len can drive bodysize negative. Passing a negative long to memcpy's size_t parameter would request an enormous copy and overflow the body buffer. Add a defensive check: if (bodysize < 0) return -1.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this changes
Adds a single defensive check in
ogg_stream_pagein()(src/framing.c) toreject a page whose computed
bodysizeis negative before it reachesmemcpy().Why
bodysizestarts asog->body_len(along). In the continued-packet branch itis decremented by each skipped leading segment value taken from the page's lacing
table:
If a page's
body_lenis smaller than the sum of those skipped segment values,bodysizeunderflows below zero. It is then passed tomemcpy(), whose thirdparameter is
size_t, so a negativelongis reinterpreted as a very largeunsigned length and overflows
os->body_data._os_body_expand()does not catchthis: it also takes a
long neededand its overflow guard only checks againstLONG_MAX, not for negative values.Reachability / severity
This is low severity and, as far as I can tell, not reachable through libogg's
normal data flow. Pages produced by
ogg_sync_pageseek()/ogg_sync_pageout()derive
body_lenfrom the same segment table this code re-reads, so the invariantholds and the subtraction cannot go negative.
libvorbisfileonly obtains pagesthrough that path.
It is reachable only when a caller hands
ogg_stream_pagein()a page whosebody_lenis inconsistent with its own segment table — e.g. a struct built ormutated outside the sync layer. The change is therefore proposed as defensive
hardening: the function currently trusts a precondition it does not enforce, and
this makes the contract explicit.
return -1is the function's existing errorconvention (already used for serial mismatch, version mismatch, and allocation
failure), so callers need no changes.
Testing
-fsanitize=address,undefinedand exercisedogg_stream_pagein()via a libFuzzer harness that constructs pages directly.
segments of 255 and a smaller
body_len) triggers:AddressSanitizer: negative-size-param: (size=-5100)at thememcpyinogg_stream_pagein.-1cleanly; valid pages still decode; afollow-up fuzzing run (1.3M+ executions) showed no crashes and no regression.
I'm happy to share the libFuzzer harness and the 48-byte reproducer on request.
Patch is against commit
06a5e0262cdc28aa4ae6797627a783b5010440f0.