Submit #761314: albertodemichelis squirrel master-branch Uncontrolled Recursioninfo

Titlealbertodemichelis squirrel master-branch Uncontrolled Recursion
Description### Description We discovered a Stack-overflow vulnerability in the Squirrel compiler. The crash occurs when parsing a script containing a deeply nested sequence of unary operators (e.g., !!!!!!...). The ASAN report shows an extremely deep recursion chain involving Factor, PrefixedExpr, and UnaryOP, eventually exhausting the stack and triggering a crash in SQLexer::Lex. ### Environment - OS: Linux x86_64 - Complier: Clang - Build Configuration: Release mode with ASan enabled. ### Vulnerability Details - Target: Squirrel (squirrel-lang) - Vulnerability Type: CWE-674: Uncontrolled Recursion - Function: SQCompiler::Factor / SQCompiler::UnaryOP - Location: squirrel/sqcompiler.cpp:863 (recurses to PrefixedExpr) - Root Cause Analysis: The parser handles unary operators recursively. ``` // Example logic in sqcompiler.cpp void SQCompiler::Factor() { if (IsUnaryOp(token)) { UnaryOP(op); // UnaryOP calls PrefixedExpr, which calls Factor again } ... } ``` The PoC likely contains a long chain of unary operators (e.g., logical NOT ! or negation -). The compiler recurses for each operator without a depth limit check, leading to stack exhaustion. ### Reproduce 1. Build squirrel with Release optimization and ASAN enabled. 2. Run with the crashing [file](https://github.com/oneafter/0122/blob/main/i312/repro): ``` ./build/bin/sq repro ``` <details> <summary>ASAN report</summary> ``` ==77839==ERROR: AddressSanitizer: stack-overflow on address 0x7fff82031f60 (pc 0x7f6744d053a8 bp 0x7fff82032390 sp 0x7fff82031f60 T0) #0 0x7f6744d053a8 in SQCompiler::Factor() /src/squirrel/squirrel/sqcompiler.cpp:718 #1 0x7f6744d03a0b in SQCompiler::PrefixedExpr() /src/squirrel/squirrel/sqcompiler.cpp:618:25 #2 0x7f6744d0bbec in SQCompiler::UnaryOP(SQOpcode) /src/squirrel/squirrel/sqcompiler.cpp:907:9 #3 0x7f6744d06a5a in SQCompiler::Factor() /src/squirrel/squirrel/sqcompiler.cpp:863:13 #4 0x7f6744d03a0b in SQCompiler::PrefixedExpr() /src/squirrel/squirrel/sqcompiler.cpp:618:25 #5 0x7f6744d0bbec in SQCompiler::UnaryOP(SQOpcode) /src/squirrel/squirrel/sqcompiler.cpp:907:9 #6 0x7f6744d06a5a in SQCompiler::Factor() /src/squirrel/squirrel/sqcompiler.cpp:863:13 #7 0x7f6744d03a0b in SQCompiler::PrefixedExpr() /src/squirrel/squirrel/sqcompiler.cpp:618:25 #8 0x7f6744d0bbec in SQCompiler::UnaryOP(SQOpcode) /src/squirrel/squirrel/sqcompiler.cpp:907:9 #9 0x7f6744d06a5a in SQCompiler::Factor() /src/squirrel/squirrel/sqcompiler.cpp:863:13 #10 0x7f6744d03a0b in SQCompiler::PrefixedExpr() /src/squirrel/squirrel/sqcompiler.cpp:618:25 #11 0x7f6744d0bbec in SQCompiler::UnaryOP(SQOpcode) /src/squirrel/squirrel/sqcompiler.cpp:907:9 #12 0x7f6744d06a5a in SQCompiler::Factor() /src/squirrel/squirrel/sqcompiler.cpp:863:13 #13 0x7f6744d03a0b in SQCompiler::PrefixedExpr() /src/squirrel/squirrel/sqcompiler.cpp:618:25 #14 0x7f6744d0bbec in SQCompiler::UnaryOP(SQOpcode) /src/squirrel/squirrel/sqcompiler.cpp:907:9 #15 0x7f6744d06a5a in SQCompiler::Factor() /src/squirrel/squirrel/sqcompiler.cpp:863:13 #16 0x7f6744d03a0b in SQCompiler::PrefixedExpr() /src/squirrel/squirrel/sqcompiler.cpp:618:25 #17 0x7f6744d0bbec in SQCompiler::UnaryOP(SQOpcode) /src/squirrel/squirrel/sqcompiler.cpp:907:9 #18 0x7f6744d06a5a in SQCompiler::Factor() /src/squirrel/squirrel/sqcompiler.cpp:863:13 #19 0x7f6744d03a0b in SQCompiler::PrefixedExpr() /src/squirrel/squirrel/sqcompiler.cpp:618:25 #20 0x7f6744d0bbec in SQCompiler::UnaryOP(SQOpcode) /src/squirrel/squirrel/sqcompiler.cpp:907:9 #21 0x7f6744d06a5a in SQCompiler::Factor() /src/squirrel/squirrel/sqcompiler.cpp:863:13 #22 0x7f6744d03a0b in SQCompiler::PrefixedExpr() /src/squirrel/squirrel/sqcompiler.cpp:618:25 #23 0x7f6744d0bbec in SQCompiler::UnaryOP(SQOpcode) /src/squirrel/squirrel/sqcompiler.cpp:907:9 #24 0x7f6744d06a5a in SQCompiler::Factor() /src/squirrel/squirrel/sqcompiler.cpp:863:13 #25 0x7f6744d03a0b in SQCompiler::PrefixedExpr() /src/squirrel/squirrel/sqcompiler.cpp:618:25 #26 0x7f6744d0bbec in SQCompiler::UnaryOP(SQOpcode) /src/squirrel/squirrel/sqcompiler.cpp:907:9 #27 0x7f6744d06a5a in SQCompiler::Factor() /src/squirrel/squirrel/sqcompiler.cpp:863:13 #28 0x7f6744d03a0b in SQCompiler::PrefixedExpr() /src/squirrel/squirrel/sqcompiler.cpp:618:25 #29 0x7f6744d0bbec in SQCompiler::UnaryOP(SQOpcode) /src/squirrel/squirrel/sqcompiler.cpp:907:9 #30 0x7f6744d06a5a in SQCompiler::Factor() /src/squirrel/squirrel/sqcompiler.cpp:863:13 #31 0x7f6744d03a0b in SQCompiler::PrefixedExpr() /src/squirrel/squirrel/sqcompiler.cpp:618:25 #32 0x7f6744d0bbec in SQCompiler::UnaryOP(SQOpcode) /src/squirrel/squirrel/sqcompiler.cpp:907:9 #33 0x7f6744d06a5a in SQCompiler::Factor() /src/squirrel/squirrel/sqcompiler.cpp:863:13 #34 0x7f6744d03a0b in SQCompiler::PrefixedExpr() /src/squirrel/squirrel/sqcompiler.cpp:618:25 #35 0x7f6744d0bbec in SQCompiler::UnaryOP(SQOpcode) /src/squirrel/squirrel/sqcompiler.cpp:907:9 #36 0x7f6744d06a5a in SQCompiler::Factor() /src/squirrel/squirrel/sqcompiler.cpp:863:13 #37 0x7f6744d03a0b in SQCompiler::PrefixedExpr() /src/squirrel/squirrel/sqcompiler.cpp:618:25 #38 0x7f6744d0bbec in SQCompiler::UnaryOP(SQOpcode) /src/squirrel/squirrel/sqcompiler.cpp:907:9 #39 0x7f6744d06a5a in SQCompiler::Factor() /src/squirrel/squirrel/sqcompiler.cpp:863:13 #40 0x7f6744d03a0b in SQCompiler::PrefixedExpr() /src/squirrel/squirrel/sqcompiler.cpp:618:25 #41 0x7f6744d0bbec in SQCompiler::UnaryOP(SQOpcode) /src/squirrel/squirrel/sqcompiler.cpp:907:9 #42 0x7f6744d06a5a in SQCompiler::Factor() /src/squirrel/squirrel/sqcompiler.cpp:863:13 #43 0x7f6744d03a0b in SQCompiler::PrefixedExpr() /src/squirrel/squirrel/sqcompiler.cpp:618:25 #44 0x7f6744d0bbec in SQCompiler::UnaryOP(SQOpcode) /src/squirrel/squirrel/sqcompiler.cpp:907:9 #45 0x7f6744d06a5a in SQCompiler::Factor() /src/squirrel/squirrel/sqcompiler.cpp:863:13 #46 0x7f6744d03a0b in SQCompiler::PrefixedExpr() /src/squirrel/squirrel/sqcompiler.cpp:618:25 #47 0x7f6744d0bbec in SQCompiler::UnaryOP(SQOpcode) /src/squirrel/squirrel/sqcompiler.cpp:907:9 #48 0x7f6744d06a5a in SQCompiler::Factor() /src/squirrel/squirrel/sqcompiler.cpp:863:13 #49 0x7f6744d03a0b in SQCompiler::PrefixedExpr() /src/squirrel/squirrel/sqcompiler.cpp:618:25 #50 0x7f6744d0bbec in SQCompiler::UnaryOP(SQOpcode) /src/squirrel/squirrel/sqcompiler.cpp:907:9 #51 0x7f6744d06a5a in SQCompiler::Factor() /src/squirrel/squirrel/sqcompiler.cpp:863:13 #52 0x7f6744d03a0b in SQCompiler::PrefixedExpr() /src/squirrel/squirrel/sqcompiler.cpp:618:25 #53 0x7f6744d0bbec in SQCompiler::UnaryOP(SQOpcode) /src/squirrel/squirrel/sqcompiler.cpp:907:9 #54 0x7f6744d06a5a in SQCompiler::Factor() /src/squirrel/squirrel/sqcompiler.cpp:863:13 #55 0x7f6744d03a0b in SQCompiler::PrefixedExpr() /src/squirrel/squirrel/sqcompiler.cpp:618:25 #56 0x7f6744d0bbec in SQCompiler::UnaryOP(SQOpcode) /src/squirrel/squirrel/sqcompiler.cpp:907:9 #57 0x7f6744d06a5a in SQCompiler::Factor() /src/squirrel/squirrel/sqcompiler.cpp:863:13 #58 0x7f6744d03a0b in SQCompiler::PrefixedExpr() /src/squirrel/squirrel/sqcompiler.cpp:618:25 #59 0x7f6744d0bbec in SQCompiler::UnaryOP(SQOpcode) /src/squirrel/squirrel/sqcompiler.cpp:907:9 #60 0x7f6744d06a5a in SQCompiler::Factor() /src/squirrel/squirrel/sqcompiler.cpp:863:13 #61 0x7f6744d03a0b in SQCompiler::PrefixedExpr() /src/squirrel/squirrel/sqcompiler.cpp:618:25 #62 0x7f6744d0bbec in SQCompiler::UnaryOP(SQOpcode) /src/squirrel/squirrel/sqcompiler.cpp:907:9 #63 0x7f6744d06a5a in SQCompiler::Factor() /src/squirrel/squirrel/sqcompiler.cpp:863:13 #64 0x7f6744d03a0b in SQCompiler::PrefixedExpr() /src/squirrel/squirrel/sqcompiler.cpp:618:25 #65 0x7f6744d0bbec in SQCompiler::UnaryOP(SQOpcode) /src/squirrel/squirrel/sqcompiler.cpp:907:9 #66 0x7f6744d06a5a in SQCompiler::Factor() /src/squirrel/squirrel/sqcompiler.cpp:863:13 #67 0x7f6744d03a0b in SQCompiler::PrefixedExpr() /src/squirrel/squirrel/sqcompiler.cpp:618:25 #68 0x7f6744d0bbec in SQCompiler::UnaryOP(SQOpcode) /src/squirrel/squirrel/sqcompiler.cpp:907:9 #69 0x7f6744d06a5a in SQCompiler::Factor() /src/squirrel/squirrel/sqcompiler.cpp:863:13 #70 0x7f6744d03a0b in SQCompiler::PrefixedExpr() /src/squirrel/squirrel/sqcompiler.cpp:618:25 #71 0x7f6744d0bbec in SQCompiler::UnaryOP(SQOpcode) /src/squirrel/squirrel/sqcompiler.cpp:907:9 #72 0x7f6744d06a5a in SQCompiler::Factor() /src/squirrel/squirrel/sqcompiler.cpp:863:13 #73 0x7f6744d03a0b in SQCompiler::PrefixedExpr() /src/squirrel/squirrel/sqcompiler.cpp:618:25 #74 0x7f6744d0bbec in SQCompiler::UnaryOP(SQOpcode) /src/squirrel/squirrel/sqcompiler.cpp:907:9 #75 0x7f6744d06a5a in SQCompiler::Factor() /src/squirrel/squirrel/sqcompiler.cpp:863:13 #76 0x7f6744d03a0b in SQCompiler::PrefixedExpr() /src/squirrel/squirrel/sqcompiler.cpp:618:25 #77 0x7f6744d0bbec in SQCompiler::UnaryOP(SQOpcode) /src/squirrel/squirrel/sqcompiler.cpp:907:9 #78 0x7f6744d06a5a in SQCompiler::Factor() /src/squirrel/squirrel/sqcompiler.cpp:863:13 #79 0x7f6744d03a0b in SQCompiler::PrefixedExpr() /src/squirrel/squirrel/sqcompiler.cpp:618:25 #80 0x7f6744d0bbec in SQCompiler::UnaryOP(SQOpcode) /src/squirrel/squirrel/sqcompiler.cpp:907:9 #81 0x7f6744d06a5a in SQCompiler::Factor() /src/squirrel/squirrel/sqcompiler.cpp:863:13 #82 0x7f6744d03a0b in SQCompiler::PrefixedExpr() /src/squirrel/squirrel/sqcompiler.cpp:618:25 #83 0x7f6744d0bbec in SQCompiler::UnaryOP(SQOpcode) /src/squirrel/squirrel/sqcompiler.cpp:907:9 #84 0x7f6744d06a5a in SQCompiler::Factor() /src/squirrel/squirrel/sqcompiler.cpp:863:13 #85 0x7f6744d03a0b in SQCompiler::PrefixedExpr() /src/squirrel/squirrel/sqcompiler.cpp:618:25 #86 0x7f6744d0bbec
Source⚠️ https://github.com/albertodemichelis/squirrel/issues/312
User Oneafter (UID 92781)
Submission02/18/2026 14:49 (2 months ago)
Moderation02/28/2026 15:53 (10 days later)
StatusAccepted
VulDB entry348274 [Squirrel up to 3.2 squirrel/sqcompiler.cpp UnaryOP recursion]
Points20

Interested in the pricing of exploits?

See the underground prices here!