Commit 4e5f06b
committed
core_info: gate string_split on strdup success in CCJSONStringHandler
CCJSONStringHandler in core_info.c had an unchecked strdup
whose result fed directly into string_split, which
NULL-derefs on NULL input:
*pCtx->current_string_val = strdup(pValue);
if (pCtx->current_string_list_val)
{
if (*pCtx->current_string_list_val)
string_list_free(*pCtx->current_string_list_val);
*pCtx->current_string_list_val =
string_split(*pCtx->current_string_val, "|");
}
On strdup OOM, *current_string_val = NULL. string_split
in libretro-common/lists/string_list.c does:
struct string_list *string_split(const char *str, const char *delim)
{
const char *p = str;
struct string_list *list = string_list_new();
if (!list)
return NULL;
while (*p) /* NULL-deref on str == NULL */
{
...
There's no NULL-check on str before dereferencing via p. So
strdup OOM -> string_split segfault.
Fix: gate the entire string_split block on
'*pCtx->current_string_val' being non-NULL. Consequence on
OOM: the string_list for this field is not updated
(*current_string_list_val retains its previous value, which
could be NULL if it was never set or a valid list if this
field has been parsed before - either is fine for downstream
consumers, which already NULL-guard the list per the deep-
copy pattern in core_info_copy).
=== Swept-clean in the same pass across small modules ===
- camera/drivers/video4linux2.c (3 sites), pipewire.c (2
sites), ffmpeg.c (1), android.c (1): all NULL-checked.
- record/record_driver.c (1 site) and record/drivers/
record_wav.c / record_ffmpeg.c (1 each): all NULL-checked.
- location/drivers/android.c (1 site): NULL-checked.
- bluetooth/drivers/bluez.c / bluetoothctl.c (1 each):
return calloc() directly without NULL-check, but the caller
in bluetooth/bluetooth_driver.c does
bt_st->data = bt_st->drv->init();
if (!bt_st->data)
bt_st->active = false;
so the NULL return is handled - these driver init functions
are intentionally minimal.
- disk_control.c: zero alloc sites.
- disk_index_file.c (1 site): strdup in DCifJSONStringHandler,
but downstream readers NULL-guard
context.image_path, so strdup failure produces empty
image_path - graceful degradation, not a crash.
- core_info.c other 44 sites: all NULL-checked. Includes the
deep-copy strdups in core_info_copy which use the conditional
'? strdup(src->x) : NULL' pattern (strdup failure produces
NULL, downstream tolerates). core_info_cache_list_new has a
two-stage alloc with proper cleanup. core_info_path_list_
new has bulk NULL-check after four parallel callocs.
- core_updater_list.c (14 sites): all NULL-checked, proper
tmp-pattern reallocs for each remote/local path buffer.
- core_backup.c (4 sites): all NULL-checked.
Reachability: strdup OOM in JSON parsing is rare but possible.
This code path fires during core info parsing at startup - a
failure here would previously crash the core scanner silently
on memory-starved devices; post-patch the scanner continues
with a missing list field.
Thread-safety: core info parsing runs on the core scanner
task thread, single-threaded per scan. No concurrency
concerns.1 parent 8fd7aa4 commit 4e5f06b
1 file changed
Lines changed: 9 additions & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
307 | 307 | | |
308 | 308 | | |
309 | 309 | | |
310 | | - | |
| 310 | + | |
| 311 | + | |
| 312 | + | |
| 313 | + | |
| 314 | + | |
| 315 | + | |
| 316 | + | |
| 317 | + | |
| 318 | + | |
311 | 319 | | |
312 | 320 | | |
313 | 321 | | |
| |||
0 commit comments