| Title | wren-lang wren main-branch Heap-based Buffer Overflow |
|---|
| Description | ### Description
We discovered a Heap-buffer-overflow vulnerability in Wren. The crash occurs in the compiler's lexer (peekChar) when parsing a source file containing a malformed sequence of quotes (likely triggering raw string parsing).
The ASAN report indicates a READ violation of size 1, occurring immediately after the allocated source buffer.
### Environment
- OS: Linux x86_64
- Complier: Clang
- Build Configuration: Release mode with ASan enabled.
### Vulnerability Details
- Target: Wren (wren-lang)
- Vulnerability Type: CWE-125: Out-of-bounds Read
- Function: peekChar (called by readRawString)
- Location: src/vm/wren_compiler.c:641
- Root Cause Analysis: The crash happens when the lexer attempts to parse a raw string literal (triple quotes """).
1. The PoC ends with a sequence of many quotes: nt(""""""""".
2. nextToken calls readRawString to handle the string literal.
3. Inside readRawString, the parser consumes characters looking for the closing delimiter.
4. It appears the loop logic inside readRawString (or its usage of peekChar) fails to detect the end of the source buffer (EOF/Null terminator) correctly when faced with incomplete or excessive quotes, causing it to read one byte past the end of the heap-allocated source string.
### Reproduce
1. Build wren and harness with Release optimization and ASAN enabled.
<details>
<summary>harness.c</summary>
```
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "wren.h"
void writeFn(WrenVM* vm, const char* text) {
}
void errorFn(WrenVM* vm, WrenErrorType type, const char* module, int line, const char* message) {
}
int main(int argc, char** argv) {
if (argc < 2) return 1;
FILE* f = fopen(argv[1], "rb");
if (!f) return 1;
fseek(f, 0, SEEK_END);
long length = ftell(f);
fseek(f, 0, SEEK_SET);
char* buffer = (char*)malloc(length + 1);
if (!buffer) {
fclose(f);
return 1;
}
if (fread(buffer, 1, length, f) != (size_t)length) {
free(buffer);
fclose(f);
return 1;
}
buffer[length] = '\0';
fclose(f);
WrenConfiguration config;
wrenInitConfiguration(&config);
config.writeFn = writeFn;
config.errorFn = errorFn;
WrenVM* vm = wrenNewVM(&config);
WrenInterpretResult result = wrenInterpret(vm, "main", buffer);
wrenFreeVM(vm);
free(buffer);
return 0;
}
```
</details>
2. Run with the crashing [file](https://github.com/oneafter/0122/blob/main/i1217/repro):
```
./bin/harness repro
```
<details>
<summary>ASAN report</summary>
```
==71585==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x504000000038 at pc 0x55ef7240e1b4 bp 0x7ffd70a28ab0 sp 0x7ffd70a28aa8
READ of size 1 at 0x504000000038 thread T0
#0 0x55ef7240e1b3 in peekChar /src/wren/projects/make/../../src/vm/wren_compiler.c:641:10
#1 0x55ef7240e1b3 in readRawString /src/wren/projects/make/../../src/vm/wren_compiler.c:911:15
#2 0x55ef7240e1b3 in nextToken /src/wren/projects/make/../../src/vm/wren_compiler.c:1186:11
#3 0x55ef72408325 in consume /src/wren/projects/make/../../src/vm/wren_compiler.c:1269:3
#4 0x55ef72408325 in wrenCompile /src/wren/projects/make/../../src/vm/wren_compiler.c:3820:9
#5 0x55ef723f4aa3 in compileInModule /src/wren/projects/make/../../src/vm/wren_vm.c:484:15
#6 0x55ef723f3f26 in wrenCompileSource /src/wren/projects/make/../../src/vm/wren_vm.c:1538:25
#7 0x55ef723f3f26 in wrenInterpret /src/wren/projects/make/../../src/vm/wren_vm.c:1517:25
#8 0x55ef723e8ca5 in main /src/wren/fuzz_wren.c:51:34
#9 0x7fc0075061c9 (/lib/x86_64-linux-gnu/libc.so.6+0x2a1c9) (BuildId: 274eec488d230825a136fa9c4d85370fed7a0a5e)
#10 0x7fc00750628a in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2a28a) (BuildId: 274eec488d230825a136fa9c4d85370fed7a0a5e)
#11 0x55ef723075c4 in _start (/src/wren/bin/fuzz_wren+0x365c4) (BuildId: 5d78be029a4b6a34067ee0d0f65b83b8780504cc)
0x504000000038 is located 0 bytes after 40-byte region [0x504000000010,0x504000000038)
allocated by thread T0 here:
#0 0x55ef723a73f3 in malloc (/src/wren/bin/fuzz_wren+0xd63f3) (BuildId: 5d78be029a4b6a34067ee0d0f65b83b8780504cc)
#1 0x55ef723e8bb5 in main /src/wren/fuzz_wren.c:26:27
#2 0x7fc0075061c9 (/lib/x86_64-linux-gnu/libc.so.6+0x2a1c9) (BuildId: 274eec488d230825a136fa9c4d85370fed7a0a5e)
#3 0x7fc00750628a in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2a28a) (BuildId: 274eec488d230825a136fa9c4d85370fed7a0a5e)
#4 0x55ef723075c4 in _start (/src/wren/bin/fuzz_wren+0x365c4) (BuildId: 5d78be029a4b6a34067ee0d0f65b83b8780504cc)
SUMMARY: AddressSanitizer: heap-buffer-overflow /src/wren/projects/make/../../src/vm/wren_compiler.c:641:10 in peekChar
Shadow bytes around the buggy address:
0x503ffffffd80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x503ffffffe00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x503ffffffe80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x503fffffff00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x503fffffff80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x504000000000: fa fa 00 00 00 00 00[fa]fa fa 00 00 00 00 00 fa
0x504000000080: fa fa 00 00 00 00 07 fa fa fa 00 00 00 00 07 fa
0x504000000100: fa fa 00 00 00 00 02 fa fa fa 00 00 00 00 06 fa
0x504000000180: fa fa 00 00 00 00 06 fa fa fa 00 00 00 00 06 fa
0x504000000200: fa fa 00 00 00 00 00 01 fa fa 00 00 00 00 05 fa
0x504000000280: fa fa 00 00 00 00 06 fa fa fa 00 00 00 00 06 fa
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
==71585==ABORTING
```
</details> |
|---|
| Source | ⚠️ https://github.com/wren-lang/wren/issues/1217 |
|---|
| User | Oneafter (UID 92781) |
|---|
| Submission | 02/09/2026 06:58 (3 months ago) |
|---|
| Moderation | 02/20/2026 11:49 (11 days later) |
|---|
| Status | Accepted |
|---|
| VulDB entry | 347097 [wren-lang wren up to 0.4.0 Source File Parser src/vm/wren_compiler.c peekChar out-of-bounds] |
|---|
| Points | 20 |
|---|