-
Notifications
You must be signed in to change notification settings - Fork 2.5k
Closed
Description
Hi, currently it seems like SDL_GlobStorageDirectory is broken when used with a SDL_Storage created with SDL_OpenFileStorage(NULL).
SDL_OpenFileStorage constructs a new file storage with an optional base path, passing null is explicitly allowed:
SDL/include/SDL3/SDL_storage.h
Lines 388 to 389 in 9f721e8
| * \param path the base path prepended to all storage paths, or NULL for no | |
| * base path. |
SDL_GlobStorageDirectory is used to search through a given storage, and as far as I can tell is not restricted from being called on such a storage object. However, currently it unconditionally assumes base_path is non-null, leading to a segmentation fault if that is violated.
Tested on c39d772a
(found via automated fuzzing)
The following testcase demonstrates the issue:
testcase.cpp
#include <SDL3/SDL.h>
#include <SDL3/SDL_storage.h>
int main() {
// Open storage with a NULL base path (explicitly allowed by the API docs).
SDL_Storage *st = SDL_OpenFileStorage(NULL);
if (!st) return 0; // backend unavailable => exit cleanly
// Storage is usually immediately ready in the generic backend.
for (int i = 0; i < 3 && !SDL_StorageReady(st); i++) {}
if (!SDL_StorageReady(st)) return 0;
// Trigger enumeration; any simple relative path string suffices.
int count = 0;
char **list = SDL_GlobStorageDirectory(st, "test", NULL, 0, &count);
if (list) SDL_free(list);
return 0;
}crash report
{
"Date": "2025-09-27T01:22:42.775429+00:00",
"Uname": "Linux 90f16fa39b0b 5.15.0-140-generic #150-Ubuntu SMP Sat Apr 12 06:00:09 UTC 2025 x86_64 x86_64 x86_64 GNU/Linux",
"OS": "Ubuntu",
"OSRelease": "22.04",
"Architecture": "amd64",
"ExecutablePath": "/tmp/tmp3ahg4kxq/reproducer",
"ProcEnviron": [
"LIBAFL_EDGES_MAP_SIZE=800000",
"PWD=/fuzz/workspace",
"GRAPHFUZZ_USE_ASAN=1",
"HOME=/root",
"ASAN_OPTIONS=hard_rss_limit_mb=1024:detect_leaks=0",
"TERM=xterm-256color",
"SHLVL=1",
"LD_LIBRARY_PATH=/fuzz/install/lib",
"PATH=/root/.cargo/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"DEBIAN_FRONTEND=noninteractive",
"OLDPWD=/fuzz/src",
"_=/usr/local/bin/agfi"
],
"ProcCmdline": "/tmp/tmp3ahg4kxq/reproducer",
"Stdin": "",
"ProcStatus": [],
"ProcMaps": [],
"ProcFiles": [],
"NetworkConnections": [],
"CrashSeverity": {
"Type": "NOT_EXPLOITABLE",
"ShortDescription": "SourceAvNearNull",
"Description": "Access violation near NULL on source operand",
"Explanation": "The target crashed on an access violation at an address matching the source operand of the current instruction. This likely indicates a read access violation, which may mean the application crashed on a simple NULL dereference to data structure that has no immediate effect on control of the processor."
},
"Stacktrace": [
" #0 0x7ffff7bf60bc string/../sysdeps/x86_64/multiarch/strlen-evex.S:77",
" #1 0x5555555f77fa in strlen (/tmp/tmp3ahg4kxq/reproducer+0xa37fa) (BuildId: 2de8c80dfdceb67bec1fba978f75ecbbe15ea7ea)",
" #2 0x555555906bb0 in GENERIC_EnumerateStorageDirectory /fuzz/src/src/storage/generic/SDL_genericstorage.c:82:30",
" #3 0x55555570a886 in SDL_InternalGlobDirectory /fuzz/src/src/filesystem/SDL_filesystem.c:432:9",
" #4 0x5555557f20c1 in SDL_GlobStorageDirectory_REAL /fuzz/src/src/storage/SDL_storage.c:440:12",
" #5 0x5555556bccb3 in main /tmp/tmp3ahg4kxq/reproducer.cpp:15:19",
" #6 0x7ffff7a6dd8f in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16",
" #7 0x7ffff7a6de3f in __libc_start_main csu/../csu/libc-start.c:392:3",
" #8 0x5555555e1a04 in _start (/tmp/tmp3ahg4kxq/reproducer+0x8da04) (BuildId: 2de8c80dfdceb67bec1fba978f75ecbbe15ea7ea)"
],
"Registers": {},
"Disassembly": [],
"Package": "",
"PackageVersion": "",
"PackageArchitecture": "",
"PackageDescription": "",
"AsanReport": [
"==155==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x7ffff7bf60bc bp 0x7fffffffe8d0 sp 0x7fffffffe088 T0)",
"==155==The signal is caused by a READ memory access.",
"==155==Hint: address points to the zero page.",
" #0 0x7ffff7bf60bc string/../sysdeps/x86_64/multiarch/strlen-evex.S:77",
" #1 0x5555555f77fa in strlen (/tmp/tmp3ahg4kxq/reproducer+0xa37fa) (BuildId: 2de8c80dfdceb67bec1fba978f75ecbbe15ea7ea)",
" #2 0x555555906bb0 in GENERIC_EnumerateStorageDirectory /fuzz/src/src/storage/generic/SDL_genericstorage.c:82:30",
" #3 0x55555570a886 in SDL_InternalGlobDirectory /fuzz/src/src/filesystem/SDL_filesystem.c:432:9",
" #4 0x5555557f20c1 in SDL_GlobStorageDirectory_REAL /fuzz/src/src/storage/SDL_storage.c:440:12",
" #5 0x5555556bccb3 in main /tmp/tmp3ahg4kxq/reproducer.cpp:15:19",
" #6 0x7ffff7a6dd8f in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16",
" #7 0x7ffff7a6de3f in __libc_start_main csu/../csu/libc-start.c:392:3",
" #8 0x5555555e1a04 in _start (/tmp/tmp3ahg4kxq/reproducer+0x8da04) (BuildId: 2de8c80dfdceb67bec1fba978f75ecbbe15ea7ea)",
"",
"AddressSanitizer can not provide additional info.",
"SUMMARY: AddressSanitizer: SEGV string/../sysdeps/x86_64/multiarch/strlen-evex.S:77",
"==155==ABORTING"
],
"MsanReport": [],
"UbsanReport": [],
"LuaReport": [],
"PythonReport": [],
"GoReport": [],
"JavaReport": [],
"RustReport": [],
"JsReport": [],
"CSharpReport": [],
"CrashLine": "/fuzz/src/src/storage/generic/SDL_genericstorage.c:82:30",
"Source": [
" 78 GenericEnumerateData wrap_data;",
" 79 ",
" 80 char *fullpath = GENERIC_INTERNAL_CreateFullPath((char *)userdata, path);",
" 81 if (fullpath) {",
"--->82 wrap_data.base_len = SDL_strlen((char *)userdata);",
" 83 wrap_data.real_callback = callback;",
" 84 wrap_data.real_userdata = callback_userdata;",
" 85 ",
" 86 result = SDL_EnumerateDirectory(fullpath, GENERIC_EnumerateDirectory, &wrap_data);",
" 87 "
]
}Metadata
Metadata
Assignees
Labels
No labels