Отправить #753165: albertodemichelis squirrel master-branch Heap-based Buffer OverflowИнформация

Названиеalbertodemichelis squirrel master-branch Heap-based Buffer Overflow
Описание### Description We discovered a Heap-buffer-overflow vulnerability in the Squirrel VM. The crash occurs when the VM enters an infinite recursion loop involving metamethod calls (_set/_get), leading to stack exhaustion or corruption. The ASAN report shows a very deep call stack of Execute -> Call -> FallBackSet, eventually causing a memory access violation 8 bytes past the end of a 16KB allocated region (likely the VM's internal stack sqvector). ### 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 / CWE-122: Heap-based Buffer Overflow - Function: SQObjectPtr::operator= - Location: squirrel/sqobject.h:269 - Root Cause Analysis: The crash is triggered by infinite recursion in the script execution. 1. The stack trace shows repeated calls to FallBackSet -> Set -> Execute, implying a property assignment that triggers a _set metamethod, which in turn triggers another assignment recursively. 2. The memory allocation trace shows sqvector<SQObjectPtr>::_realloc, suggesting this heap buffer is the VM's execution stack. 3. As the recursion deepens, the stack grows. The crash occurs at 0x529000004208, which is 8 bytes past the allocated chunk [...00004200). 4. This suggests that either the VM failed to check the stack limit properly, or a pointer to a stack element became invalid/out-of-bounds during the realloc process or subsequent access. ### Reproduce 1. Build squirrel with Release optimization and ASAN enabled. 2. Run with the crashing [file](https://github.com/oneafter/0122/blob/main/i310/repro): ``` ./build/bin/sq repro ``` <details> <summary>ASAN report</summary> ``` ==45933==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x529000004208 at pc 0x7ff6dd660676 bp 0x7ffcbda3d170 sp 0x7ffcbda3d168 READ of size 8 at 0x529000004208 thread T0 #0 0x7ff6dd660675 in SQObjectPtr::operator=(SQObjectPtr const&) /src/squirrel/squirrel/sqobject.h:269:16 #1 0x7ff6dd660675 in SQVM::Return(long long, long long, SQObjectPtr&) /src/squirrel/squirrel/sqvm.cpp:475:19 #2 0x7ff6dd660675 in SQVM::StartCall(SQClosure*, long long, long long, long long, bool) /src/squirrel/squirrel/sqvm.cpp:446:9 #3 0x7ff6dd670cc0 in SQVM::Execute(SQObjectPtr&, long long, long long, SQObjectPtr&, unsigned long long, SQVM::ExecutionType) /src/squirrel/squirrel/sqvm.cpp:709:17 #4 0x7ff6dd66e96f in SQVM::Call(SQObjectPtr&, long long, long long, SQObjectPtr&, unsigned long long) /src/squirrel/squirrel/sqvm.cpp:1610:16 #5 0x7ff6dd69366e in SQVM::FallBackGet(SQObjectPtr const&, SQObjectPtr const&, SQObjectPtr&) /src/squirrel/squirrel/sqvm.cpp:1361:16 #6 0x7ff6dd666974 in SQVM::Get(SQObjectPtr const&, SQObjectPtr const&, SQObjectPtr&, unsigned long long, long long) /src/squirrel/squirrel/sqvm.cpp:1299:16 #7 0x7ff6dd6730ec in SQVM::Execute(SQObjectPtr&, long long, long long, SQObjectPtr&, unsigned long long, SQVM::ExecutionType) /src/squirrel/squirrel/sqvm.cpp:853:22 #8 0x7ff6dd66e96f in SQVM::Call(SQObjectPtr&, long long, long long, SQObjectPtr&, unsigned long long) /src/squirrel/squirrel/sqvm.cpp:1610:16 #9 0x7ff6dd695526 in SQVM::FallBackSet(SQObjectPtr const&, SQObjectPtr const&, SQObjectPtr const&) /src/squirrel/squirrel/sqvm.cpp:1431:16 #10 0x7ff6dd667c84 in SQVM::Set(SQObjectPtr const&, SQObjectPtr const&, SQObjectPtr const&, long long) /src/squirrel/squirrel/sqvm.cpp:1402:12 #11 0x7ff6dd674149 in SQVM::Execute(SQObjectPtr&, long long, long long, SQObjectPtr&, unsigned long long, SQVM::ExecutionType) /src/squirrel/squirrel/sqvm.cpp:863:22 #12 0x7ff6dd66e96f in SQVM::Call(SQObjectPtr&, long long, long long, SQObjectPtr&, unsigned long long) /src/squirrel/squirrel/sqvm.cpp:1610:16 #13 0x7ff6dd695526 in SQVM::FallBackSet(SQObjectPtr const&, SQObjectPtr const&, SQObjectPtr const&) /src/squirrel/squirrel/sqvm.cpp:1431:16 #14 0x7ff6dd667c84 in SQVM::Set(SQObjectPtr const&, SQObjectPtr const&, SQObjectPtr const&, long long) /src/squirrel/squirrel/sqvm.cpp:1402:12 #15 0x7ff6dd674149 in SQVM::Execute(SQObjectPtr&, long long, long long, SQObjectPtr&, unsigned long long, SQVM::ExecutionType) /src/squirrel/squirrel/sqvm.cpp:863:22 #16 0x7ff6dd66e96f in SQVM::Call(SQObjectPtr&, long long, long long, SQObjectPtr&, unsigned long long) /src/squirrel/squirrel/sqvm.cpp:1610:16 #17 0x7ff6dd695526 in SQVM::FallBackSet(SQObjectPtr const&, SQObjectPtr const&, SQObjectPtr const&) /src/squirrel/squirrel/sqvm.cpp:1431:16 #18 0x7ff6dd667c84 in SQVM::Set(SQObjectPtr const&, SQObjectPtr const&, SQObjectPtr const&, long long) /src/squirrel/squirrel/sqvm.cpp:1402:12 #19 0x7ff6dd674149 in SQVM::Execute(SQObjectPtr&, long long, long long, SQObjectPtr&, unsigned long long, SQVM::ExecutionType) /src/squirrel/squirrel/sqvm.cpp:863:22 #20 0x7ff6dd66e96f in SQVM::Call(SQObjectPtr&, long long, long long, SQObjectPtr&, unsigned long long) /src/squirrel/squirrel/sqvm.cpp:1610:16 #21 0x7ff6dd695526 in SQVM::FallBackSet(SQObjectPtr const&, SQObjectPtr const&, SQObjectPtr const&) /src/squirrel/squirrel/sqvm.cpp:1431:16 #22 0x7ff6dd667c84 in SQVM::Set(SQObjectPtr const&, SQObjectPtr const&, SQObjectPtr const&, long long) /src/squirrel/squirrel/sqvm.cpp:1402:12 #23 0x7ff6dd674149 in SQVM::Execute(SQObjectPtr&, long long, long long, SQObjectPtr&, unsigned long long, SQVM::ExecutionType) /src/squirrel/squirrel/sqvm.cpp:863:22 #24 0x7ff6dd66e96f in SQVM::Call(SQObjectPtr&, long long, long long, SQObjectPtr&, unsigned long long) /src/squirrel/squirrel/sqvm.cpp:1610:16 #25 0x7ff6dd695526 in SQVM::FallBackSet(SQObjectPtr const&, SQObjectPtr const&, SQObjectPtr const&) /src/squirrel/squirrel/sqvm.cpp:1431:16 #26 0x7ff6dd667c84 in SQVM::Set(SQObjectPtr const&, SQObjectPtr const&, SQObjectPtr const&, long long) /src/squirrel/squirrel/sqvm.cpp:1402:12 #27 0x7ff6dd674149 in SQVM::Execute(SQObjectPtr&, long long, long long, SQObjectPtr&, unsigned long long, SQVM::ExecutionType) /src/squirrel/squirrel/sqvm.cpp:863:22 #28 0x7ff6dd66e96f in SQVM::Call(SQObjectPtr&, long long, long long, SQObjectPtr&, unsigned long long) /src/squirrel/squirrel/sqvm.cpp:1610:16 #29 0x7ff6dd695526 in SQVM::FallBackSet(SQObjectPtr const&, SQObjectPtr const&, SQObjectPtr const&) /src/squirrel/squirrel/sqvm.cpp:1431:16 #30 0x7ff6dd667c84 in SQVM::Set(SQObjectPtr const&, SQObjectPtr const&, SQObjectPtr const&, long long) /src/squirrel/squirrel/sqvm.cpp:1402:12 #31 0x7ff6dd674149 in SQVM::Execute(SQObjectPtr&, long long, long long, SQObjectPtr&, unsigned long long, SQVM::ExecutionType) /src/squirrel/squirrel/sqvm.cpp:863:22 #32 0x7ff6dd66e96f in SQVM::Call(SQObjectPtr&, long long, long long, SQObjectPtr&, unsigned long long) /src/squirrel/squirrel/sqvm.cpp:1610:16 #33 0x7ff6dd695526 in SQVM::FallBackSet(SQObjectPtr const&, SQObjectPtr const&, SQObjectPtr const&) /src/squirrel/squirrel/sqvm.cpp:1431:16 #34 0x7ff6dd667c84 in SQVM::Set(SQObjectPtr const&, SQObjectPtr const&, SQObjectPtr const&, long long) /src/squirrel/squirrel/sqvm.cpp:1402:12 #35 0x7ff6dd674149 in SQVM::Execute(SQObjectPtr&, long long, long long, SQObjectPtr&, unsigned long long, SQVM::ExecutionType) /src/squirrel/squirrel/sqvm.cpp:863:22 #36 0x7ff6dd66e96f in SQVM::Call(SQObjectPtr&, long long, long long, SQObjectPtr&, unsigned long long) /src/squirrel/squirrel/sqvm.cpp:1610:16 #37 0x7ff6dd695526 in SQVM::FallBackSet(SQObjectPtr const&, SQObjectPtr const&, SQObjectPtr const&) /src/squirrel/squirrel/sqvm.cpp:1431:16 #38 0x7ff6dd667c84 in SQVM::Set(SQObjectPtr const&, SQObjectPtr const&, SQObjectPtr const&, long long) /src/squirrel/squirrel/sqvm.cpp:1402:12 #39 0x7ff6dd674149 in SQVM::Execute(SQObjectPtr&, long long, long long, SQObjectPtr&, unsigned long long, SQVM::ExecutionType) /src/squirrel/squirrel/sqvm.cpp:863:22 #40 0x7ff6dd66e96f in SQVM::Call(SQObjectPtr&, long long, long long, SQObjectPtr&, unsigned long long) /src/squirrel/squirrel/sqvm.cpp:1610:16 #41 0x7ff6dd695526 in SQVM::FallBackSet(SQObjectPtr const&, SQObjectPtr const&, SQObjectPtr const&) /src/squirrel/squirrel/sqvm.cpp:1431:16 #42 0x7ff6dd667c84 in SQVM::Set(SQObjectPtr const&, SQObjectPtr const&, SQObjectPtr const&, long long) /src/squirrel/squirrel/sqvm.cpp:1402:12 #43 0x7ff6dd674149 in SQVM::Execute(SQObjectPtr&, long long, long long, SQObjectPtr&, unsigned long long, SQVM::ExecutionType) /src/squirrel/squirrel/sqvm.cpp:863:22 #44 0x7ff6dd66e96f in SQVM::Call(SQObjectPtr&, long long, long long, SQObjectPtr&, unsigned long long) /src/squirrel/squirrel/sqvm.cpp:1610:16 #45 0x7ff6dd695526 in SQVM::FallBackSet(SQObjectPtr const&, SQObjectPtr const&, SQObjectPtr const&) /src/squirrel/squirrel/sqvm.cpp:1431:16 #46 0x7ff6dd667c84 in SQVM::Set(SQObjectPtr const&, SQObjectPtr const&, SQObjectPtr const&, long long) /src/squirrel/squirrel/sqvm.cpp:1402:12 #47 0x7ff6dd674149 in SQVM::Execute(SQObjectPtr&, long long, long long, SQObjectPtr&, unsigned long long, SQVM::ExecutionType) /src/squirrel/squirrel/sqvm.cpp:863:22 #48 0x7ff6dd66e96f in SQVM::Call(SQObjectPtr&, long long, long long, SQObjectPtr&, unsigned long long) /src/squirrel/squirrel/sqvm.cpp:1610:16 #49 0x7ff6dd695526 in SQVM::FallBackSet(SQObjectPtr const&, SQObjectPtr const&, SQObjectPtr const&) /src/squirrel/squirrel/sqvm.cpp:1431:16 #50 0x7ff6dd667c84 in SQVM::Set(SQObjectPtr const&, SQObjectPtr const&, SQObjectPtr const&, long long) /src/squirrel/squirrel/sqvm.cpp:1402:12 #51 0x7ff6dd674149 in SQVM::Execute(SQObjectPtr&, long long, long long, SQObjectPtr&, unsigned long long, SQVM::ExecutionType) /src/squirrel/squirrel/sqvm.cpp:863:22 #52 0x7ff6dd66e96f in SQVM::Call(SQObjectPtr&, long long, long long, SQObjectPtr&, unsigned long long) /src/squirrel/squirrel/sqvm.cpp:1610:16
Источник⚠️ https://github.com/albertodemichelis/squirrel/issues/310
Пользователь Oneafter (UID 92781)
Представление06.02.2026 04:32 (4 месяцы назад)
Модерация18.02.2026 08:31 (12 days later)
Статуспринято
Запись VulDB346459 [Squirrel до 3.2 squirrel/sqobject.h SQObjectPtr::operator повреждение памяти]
Баллы20

Do you want to use VulDB in your project?

Use the official API to access entries easily!