Submeter #753156: janet-lang janet c43e066 Heap-based Buffer Overflowinformação

Títulojanet-lang janet c43e066 Heap-based Buffer Overflow
Descrição### Description We discovered a Heap-buffer-overflow vulnerability in Janet. The crash occurs in the os_strftime function during runtime execution. The ASAN report indicates a READ violation of size 1, occurring exactly at the boundary (0 bytes after) of a 41-byte allocated region (likely a string buffer). Vendor confirmed and fixed this vulnerability in commit (0f28585 )[https://github.com/janet-lang/janet/commit/0f285855f0e34f9183956be5f16e045f54626bff]. ### Environment - OS: Linux x86_64 - Complier: Clang - Build Configuration: Release mode with ASan enabled. ### Vulnerability Details - Target: Janet (janet-lang) - Vulnerability Type: CWE-125: Out-of-bounds Read - Function: os_strftime - Location: src/core/os.c:1938 - Root Cause Analysis: The function os_strftime processes a format string to generate a date/time string. The ASAN report shows: ``` 0x5040000210f9 is located 0 bytes after 41-byte region READ of size 1 ``` This suggests that os_strftime is iterating over the format string (or an internal buffer) and fails to stop at the null terminator, or calculates an index that is off-by-one, attempting to read the byte immediately following the allocated string. This often happens if the format string contains specific sequences that confuse the length calculation or pointer increment logic. ### Reproduce 1. Build janet and harness with Release optimization and ASAN enabled. <details> <summary>harness.c</summary> ``` #include "janet.h" #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <stdint.h> #include <string.h> int main(int argc, char **argv) { if (argc < 2) { return 1; } janet_init(); JanetTable *env = janet_core_env(NULL); FILE *f = fopen(argv[1], "rb"); if (!f) { janet_deinit(); return 1; } fseek(f, 0, SEEK_END); long len = ftell(f); fseek(f, 0, SEEK_SET); unsigned char *buf = (unsigned char *)malloc(len + 1); if (!buf) { fclose(f); janet_deinit(); return 1; } if (fread(buf, 1, len, f) != len) { free(buf); fclose(f); janet_deinit(); return 1; } fclose(f); buf[len] = '\0'; if (len >= 1) { Janet retval; janet_dostring(env, (const char *)buf, NULL, &retval); janet_gcroot(janet_wrap_nil()); } free(buf); janet_deinit(); return 0; } ``` </details> 2. Run with the crashing [file](https://github.com/oneafter/0123/blob/main/ja3/repro): ``` ./harness repro ``` <details> <summary>ASAN report</summary> ``` ==92243==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x5040000210f9 at pc 0x55cce0daf457 bp 0x7ffcf73785b0 sp 0x7ffcf73785a8 READ of size 1 at 0x5040000210f9 thread T0 #0 0x55cce0daf456 in os_strftime /src/janet/src/core/os.c:1938:12 #1 0x55cce0e1a24b in run_vm /src/janet/src/core/vm.c:1038:25 #2 0x55cce0e26ec7 in janet_continue_no_check /src/janet/src/core/vm.c:1529:15 #3 0x55cce0ddba9a in janet_continue /src/janet/src/core/vm.c:1547:12 #4 0x55cce0ddba9a in janet_dobytes /src/janet/src/core/run.c:56:38 #5 0x55cce0c7c0f3 in main /src/janet/harness.c:44:9 #6 0x7f986fef01c9 (/lib/x86_64-linux-gnu/libc.so.6+0x2a1c9) (BuildId: 274eec488d230825a136fa9c4d85370fed7a0a5e) #7 0x7f986fef028a in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2a28a) (BuildId: 274eec488d230825a136fa9c4d85370fed7a0a5e) #8 0x55cce0b9aa94 in _start (/src/janet/harness_janet+0x54a94) (BuildId: 99073a3a75c69a7f87afa4e4c777fe183943214e) 0x5040000210f9 is located 0 bytes after 41-byte region [0x5040000210d0,0x5040000210f9) allocated by thread T0 here: #0 0x55cce0c3a8c3 in malloc (/src/janet/harness_janet+0xf48c3) (BuildId: 99073a3a75c69a7f87afa4e4c777fe183943214e) #1 0x55cce0c7ccd2 in janet_gcalloc /src/janet/src/core/gc.c:536:11 SUMMARY: AddressSanitizer: heap-buffer-overflow /src/janet/src/core/os.c:1938:12 in os_strftime Shadow bytes around the buggy address: 0x504000020e00: fa fa 00 00 00 00 00 00 fa fa 00 00 00 00 00 00 0x504000020e80: fa fa 00 00 00 00 00 00 fa fa 00 00 00 00 00 00 0x504000020f00: fa fa 00 00 00 00 00 00 fa fa 00 00 00 00 00 00 0x504000020f80: fa fa 00 00 00 00 00 00 fa fa 00 00 00 00 00 00 0x504000021000: fa fa 00 00 00 00 03 fa fa fa 00 00 00 00 00 00 =>0x504000021080: fa fa 00 00 00 00 00 00 fa fa 00 00 00 00 00[01] 0x504000021100: fa fa 00 00 00 00 04 fa fa fa 00 00 00 00 00 00 0x504000021180: fa fa 00 00 00 00 00 00 fa fa 00 00 00 00 00 fa 0x504000021200: fa fa 00 00 00 00 00 00 fa fa 00 00 00 00 00 00 0x504000021280: fa fa fd fd fd fd fd fa fa fa fd fd fd fd fd fa 0x504000021300: fa fa fd fd fd fd fd fd fa fa fd fd fd fd fd fd 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 ==92243==ABORTING ``` </details>
Fonte⚠️ https://github.com/janet-lang/janet/issues/1701
Utilizador Oneafter (UID 92781)
Submissão06/02/2026 04h07 (há 3 meses)
Moderação09/02/2026 10h38 (3 days later)
EstadoAceite
Entrada VulDB344980 [janet-lang janet até 1.40.1 src/core/os.c os_strftime Divulgação de Informação]
Pontos20

Do you want to use VulDB in your project?

Use the official API to access entries easily!