Fix stack-buffer-overflow in parseLine() on a face line with >16 vertices#73
Open
ZUENS2020 wants to merge 2 commits into
Open
Fix stack-buffer-overflow in parseLine() on a face line with >16 vertices#73ZUENS2020 wants to merge 2 commits into
ZUENS2020 wants to merge 2 commits into
Conversation
…J_MAX_FACES_PER_F_LINE vertices
parseLine() stored face/line vertices into the fixed-size stack array
`f[TINYOBJ_MAX_FACES_PER_F_LINE]` (16) with no bounds check. An OBJ face is a
legal N-gon with an arbitrary vertex count, so a face line with more than 16
vertices wrote past the end of the array — a stack-buffer-overflow WRITE. The
guarding assert() is compiled out under -DNDEBUG (release), so there was no
runtime protection. With TINYOBJ_FLAG_TRIANGULATE the triangulation loop likewise
wrote command->f[3*n+..] (also size 16) unchecked, overflowing for faces with
more than 7 vertices.
Reachable via the public tinyobj_parse_obj(..., TINYOBJ_FLAG_TRIANGULATE) on a
valid OBJ:
f 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
=> AddressSanitizer: stack-buffer-overflow WRITE in tinyobj_parse_obj
(built -O2 -DNDEBUG so the asserts are absent)
Fix: bound the writes in both the parse loop and the triangulation loop against
TINYOBJ_MAX_FACES_PER_F_LINE (extra vertices are dropped to preserve memory
safety). This is a minimal stop-gap; sizing the buffers for the actual face
(an N-gon triangulates to 3*(N-2) indices) would be the complete fix and is best
done alongside the face/triangulation rework in syoyo#60. Normal triangle/quad parsing
is unchanged (verified with TINYOBJ_FLAG_TRIANGULATE). Found via libFuzzer + ASan.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
github-actions Bot
pushed a commit
to ZUENS2020/Sherpa
that referenced
this pull request
Jun 15, 2026
… + tinyobjloader finding (#473) - S-473 (Shipped): Phase B harness-validity gate + origin-by-crashing-function (PRs #470/#471/#472); resolves O-6. - O-6 (section 3): marked RESOLVED (S-473) for traceability — single-header libs attribute library frames to *_fuzz.c, fixed by function-based classification. - Findings log: tinyobjloader-c parseLine stack-buffer-overflow WRITE (PR syoyo/tinyobjloader-c#73), source-verified, not a dup of #55/#60. Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Owner
|
you should add regression test |
Adds two acutest cases to test/tinyobj_internal_tests.c covering the stack-buffer-overflow this PR fixes: - parseLine_face_overflow: an "f" statement with >TINYOBJ_MAX_FACES_PER_F_LINE vertices (untriangulated and triangulated). - parseLine_line_overflow: an "l" (polyline) statement with >2 vertices. Both reproduce an AddressSanitizer stack-buffer-overflow on the pre-fix code and pass after the fix. Writing the line-statement test exposed a second overflow the original guard missed: the "l" branch keeps two vertices in a size-2 array f[2] but was bounded by TINYOBJ_MAX_FACES_PER_F_LINE (16); the guard is now correctly bounded to 2. Also relaxed two now-incorrect debug asserts that encoded the old (buggy) "the whole n-gon always fits" precondition, which the runtime guards already enforce. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Author
|
Added regression tests in Writing the |
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.
Problem
parseLine()stores face (f) / line (l) vertices into a fixed-size stack arrayf[TINYOBJ_MAX_FACES_PER_F_LINE](= 16) with no bounds check. An OBJ face is a legal N-gon with an arbitrary vertex count, so a face line with more than 16 vertices writes past the end of the array — a stack-buffer-overflow WRITE. The guardingassert()is compiled out under-DNDEBUG(release), so there is no runtime protection. WithTINYOBJ_FLAG_TRIANGULATE, the triangulation loop also writescommand->f[3*n+..](also size 16) unchecked, overflowing for faces with >7 vertices.Reachable via the public
tinyobj_parse_obj(..., TINYOBJ_FLAG_TRIANGULATE)on a valid OBJ:(
-DNDEBUGmatters — it removes the asserts that would otherwise abort in debug.) Found via libFuzzer + ASan; reproduced on a clean clone ofmaster.Fix
Bound the writes in both the parse loop and the triangulation loop against
TINYOBJ_MAX_FACES_PER_F_LINE(extra vertices dropped to preserve memory safety). Minimal memory-safety stop-gap — sizing the buffers for the actual face (an N-gon triangulates to3*(N-2)indices) would be the complete fix and is probably best done alongside the face/triangulation rework in #60. Normal triangle/quad parsing is unchanged (verified withTINYOBJ_FLAG_TRIANGULATE).Note
This repo has issues disabled, so filing as a PR. Not a duplicate of #55 (a different
sscanf("%s")overflow) or #60 (a triangulation indexing correctness bug in the same area, which does not address this unbounded write).