Skip to content

Commit 85e2c34

Browse files
ashketchumwasherearcady-lunarg
authored andcommitted
preprocessor: guard against OOB read in handlePragma for #pragma STDGL
When a shader contains '#pragma STDGL' with fewer than 4 tokens, the condition at ParseHelper.cpp:422 accessed tokens[1] and tokens[3] without first checking tokens.size(), causing an out-of-bounds read and a SEGV under AddressSanitizer. Every other tokens[N] access in handlePragma() already has an explicit size check (see lines 340, 366). Apply the same guard here: } else if (spvVersion.spv > 0 && tokens[0].compare("STDGL") == 0 && tokens.size() >= 4 && tokens[1].compare("invariant") == 0 && tokens[3].compare("all") == 0) { Minimal reproducer (15 bytes, requires Vulkan/SPIR-V target): #pragma STDGL Found by libFuzzer + ASan on fuzz_glslang_direct harness. Fixes: SEGV in glslang::TParseContext::handlePragma() (ParseHelper.cpp:422)
1 parent 8bf4087 commit 85e2c34

4 files changed

Lines changed: 27 additions & 0 deletions

File tree

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
spv.pragma.stdgl.oob.vert
2+
// Module Version 10000
3+
// Generated by (magic number): 8000b
4+
// Id's are bound by 6
5+
6+
Capability Shader
7+
1: ExtInstImport "GLSL.std.450"
8+
MemoryModel Logical GLSL450
9+
EntryPoint Vertex 4 "main"
10+
Source GLSL 450
11+
Name 4 "main"
12+
2: TypeVoid
13+
3: TypeFunction 2
14+
4(main): 2 Function None 3
15+
5: Label
16+
Return
17+
FunctionEnd

Test/spv.pragma.stdgl.oob.vert

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#version 450
2+
// Regression test: #pragma STDGL with fewer than 4 tokens must not OOB-read
3+
// tokens[1]/tokens[3] in handlePragma() — fixed by checking tokens.size() >= 4
4+
// before accessing them (ParseHelper.cpp).
5+
#pragma STDGL
6+
#pragma STDGL invariant
7+
#pragma STDGL invariant(
8+
void main() {}

glslang/MachineIndependent/ParseHelper.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -419,6 +419,7 @@ void TParseContext::handlePragma(const TSourceLoc& loc, const TVector<TString>&
419419
} else if (tokens[0].compare("glslang_binary_double_output") == 0) {
420420
intermediate.setBinaryDoubleOutput();
421421
} else if (spvVersion.spv > 0 && tokens[0].compare("STDGL") == 0 &&
422+
tokens.size() >= 4 &&
422423
tokens[1].compare("invariant") == 0 && tokens[3].compare("all") == 0) {
423424
intermediate.setInvariantAll();
424425
// Set all builtin out variables invariant if declared

gtests/Spv.FromFile.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,7 @@ INSTANTIATE_TEST_SUITE_P(
315315
"spv.for-nobody.vert",
316316
"spv.while-continue-break.vert",
317317
"spv.while-simple.vert",
318+
"spv.pragma.stdgl.oob.vert",
318319
// vulkan-specific tests
319320
"rayQuery.rgen",
320321
"rayQuery-no-cse.rgen",

0 commit comments

Comments
 (0)