Commit 2f048a4
committed
frontend/drivers: fix OOM bugs in platform startup paths across unix/dos/xdk/emscripten
Seven OOM-related bugs across four frontend/drivers/ files,
plus two pre-existing cleanup leaks uncovered during the
audit. All on platform-startup or user-exec code paths.
=== platform_unix.c: android_app_create ===
Three issues in the Android platform driver's main
bootstrap function (runs from ANativeActivity_onCreate on
every app launch):
1. slock_new() / scond_new() return values unchecked.
slock_new and scond_new can return NULL on OOM. A NULL
mutex would silently make every slock_lock/unlock a
no-op (slock_lock NULL-tolerates by design), giving a
race-prone android_app that 'works' but has subtle
concurrency bugs. A NULL cond would NULL-deref on the
scond_wait at the bottom of the function
(pthread_cond_wait(&NULL->cond, ...)).
2. sthread_create() return value unchecked. If the worker
thread fails to spawn, nothing will set android_app->
running=true, and the 'while (!running) scond_wait(...)'
loop at the end of the function will block forever.
3. Pre-existing leak (not caused by this series): the
pipe(msgpipe) failure path at line 470 freed savedState
and android_app itself but leaked the already-created
mutex and cond. Fixed in the same pass.
Fix for all three: guard each init step, and on any failure
fully unwind everything allocated so far (mutex/cond free,
savedState free, pipe fds close, android_app free), then
return NULL. The caller (ANativeActivity_onCreate at line
500ish) does handle NULL cleanly.
=== platform_unix.c: frontend_unix_exec ===
Two issues in the exec path used when restarting RetroArch
with a different core:
newargv[0] = (char*)malloc(_len); /* _len = strlen(path) */
strlcpy(newargv[0], path, _len);
* malloc unchecked, strlcpy NULL-derefs on OOM.
* strlcpy wants n bytes to write n-1 chars plus a NUL, so
with _len == strlen(path) the final character of path
was silently truncated. Pre-existing off-by-one.
Fix: _len = strlen(path) + 1, NULL-check malloc, return on
OOM. The exec call on the next line uses path directly (not
newargv[0]) so exec behaviour isn't affected by the old
truncation, but logging and downstream argv consumers see
corrupted path.
=== platform_unix.c: accessibility_speak_unix ===
char* voice_out = (char*)malloc(3 + strlen(language));
char* speed_out = (char*)malloc(3 + 3);
...
voice_out[0] = '-'; /* NULL-deref on OOM */
speed_out[0] = '-';
Fix: NULL-check both, goto the existing 'end:' label which
already does NULL-tolerant free()s. The function's contract
is always-true return so accessibility speak is silently
dropped on OOM (non-critical feature degradation rather than
a user-visible error).
=== platform_dos.c: frontend_dos_exec ===
Same pattern as frontend_unix_exec but the _len=strlen+1 was
already correct in this file. Just needs the NULL-check.
=== platform_xdk.c: frontend_xdk_get_environment_settings (Xbox 360) ===
char *extracted_path = (char*)calloc(dwLaunchDataSize, sizeof(char));
BYTE* pLaunchData = (BYTE*)calloc(dwLaunchDataSize, sizeof(BYTE));
XGetLaunchData(pLaunchData, dwLaunchDataSize); /* NULL-deref */
memset(extracted_path, 0, dwLaunchDataSize); /* NULL-deref */
strlcpy(extracted_path, pLaunchData, ...); /* NULL-deref */
Two unchecked callocs feeding three immediate NULL-derefs on
OOM, plus a pre-existing leak: the cleanup at the bottom of
the block freed pLaunchData but not extracted_path.
Fix: joint NULL-check; on success both get freed; on failure
both get freed (free(NULL) is a no-op so no extra guards).
=== platform_emscripten.c: main ===
emscripten_platform_data = (...)calloc(1, sizeof(...));
...
emscripten_platform_data->browser = host_browser; /* NULL-deref */
This is main() at process entry for the web build. On OOM
we can't meaningfully continue - return 1 so the browser
shim surfaces the failure.
=== Not a bug, verified clean ===
* platform_ps2.c lines 453/460/467: intentional memory-
probing loop (allocate max, halve on failure). The
'while (s0 && (p=malloc(s0)) == NULL)' pattern with
short-circuit && correctly leaves p at its last-assigned
NULL when s0 hits 0, so the subsequent 'if (p) free(p)'
is safe.
* platform_darwin.m lines 949, 956, 1030: all three
already NULL-checked (prior commits in this series).
* platform_switch.c lines 487, 555: NULL-checked with
realloc-to-tmp for the realloc site.
* platform_wii.c:218, platform_ctr.c:329: NULL-checked.
* platform_emscripten.c:862: line alloc fed to getline
which per POSIX handles NULL line gracefully (allocates
its own buffer).
* platform_ps3/psp/uwp/win32/orbis/qnx/wiiu/gx: zero raw
alloc sites.
* frontend/ top-level .c files: zero raw alloc sites.
=== Thread-safety ===
android_app_create is called from the Android glue thread
during ANativeActivity_onCreate, single-threaded at that
point. The new teardown paths happen before the worker
thread is spawned (or immediately after its failed spawn),
so no concurrent access concerns.
frontend_unix_exec, frontend_dos_exec, accessibility_speak_
unix, frontend_xdk_get_environment_settings and main() all
run single-threaded on the main thread.
=== Reachability ===
Every fix here is on a startup or user-action path:
* android_app_create: every Android app launch / restore.
* frontend_unix_exec / frontend_dos_exec: every 'restart
with a different core' user action.
* accessibility_speak_unix: every accessibility-enabled
menu navigation event.
* platform_xdk: every Xbox 360 content launch (auto-start
game from dashboard).
* platform_emscripten main: every web-build page load.
OOM during platform startup is most realistic on low-memory
embedded targets (Android handhelds, Xbox 360, web tabs with
memory pressure from other sites).1 parent 8c78693 commit 2f048a4
4 files changed
Lines changed: 104 additions & 9 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
121 | 121 | | |
122 | 122 | | |
123 | 123 | | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
124 | 133 | | |
125 | 134 | | |
126 | 135 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
998 | 998 | | |
999 | 999 | | |
1000 | 1000 | | |
1001 | | - | |
| 1001 | + | |
| 1002 | + | |
1002 | 1003 | | |
| 1004 | + | |
| 1005 | + | |
| 1006 | + | |
| 1007 | + | |
| 1008 | + | |
| 1009 | + | |
| 1010 | + | |
| 1011 | + | |
1003 | 1012 | | |
1004 | 1013 | | |
1005 | 1014 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
449 | 449 | | |
450 | 450 | | |
451 | 451 | | |
| 452 | + | |
| 453 | + | |
| 454 | + | |
| 455 | + | |
| 456 | + | |
| 457 | + | |
| 458 | + | |
| 459 | + | |
| 460 | + | |
| 461 | + | |
| 462 | + | |
| 463 | + | |
| 464 | + | |
| 465 | + | |
| 466 | + | |
| 467 | + | |
| 468 | + | |
| 469 | + | |
452 | 470 | | |
453 | 471 | | |
454 | 472 | | |
| |||
471 | 489 | | |
472 | 490 | | |
473 | 491 | | |
| 492 | + | |
| 493 | + | |
474 | 494 | | |
475 | 495 | | |
476 | 496 | | |
| |||
479 | 499 | | |
480 | 500 | | |
481 | 501 | | |
| 502 | + | |
| 503 | + | |
| 504 | + | |
| 505 | + | |
| 506 | + | |
| 507 | + | |
| 508 | + | |
| 509 | + | |
| 510 | + | |
| 511 | + | |
| 512 | + | |
| 513 | + | |
| 514 | + | |
| 515 | + | |
| 516 | + | |
| 517 | + | |
| 518 | + | |
482 | 519 | | |
483 | 520 | | |
484 | 521 | | |
| |||
2691 | 2728 | | |
2692 | 2729 | | |
2693 | 2730 | | |
2694 | | - | |
| 2731 | + | |
2695 | 2732 | | |
2696 | 2733 | | |
2697 | 2734 | | |
| 2735 | + | |
| 2736 | + | |
| 2737 | + | |
| 2738 | + | |
| 2739 | + | |
| 2740 | + | |
| 2741 | + | |
| 2742 | + | |
| 2743 | + | |
| 2744 | + | |
| 2745 | + | |
| 2746 | + | |
| 2747 | + | |
| 2748 | + | |
2698 | 2749 | | |
2699 | 2750 | | |
2700 | 2751 | | |
| |||
3267 | 3318 | | |
3268 | 3319 | | |
3269 | 3320 | | |
| 3321 | + | |
| 3322 | + | |
| 3323 | + | |
| 3324 | + | |
| 3325 | + | |
| 3326 | + | |
| 3327 | + | |
| 3328 | + | |
| 3329 | + | |
| 3330 | + | |
3270 | 3331 | | |
3271 | 3332 | | |
3272 | 3333 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
185 | 185 | | |
186 | 186 | | |
187 | 187 | | |
188 | | - | |
189 | | - | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
| 203 | + | |
| 204 | + | |
190 | 205 | | |
191 | | - | |
| 206 | + | |
192 | 207 | | |
193 | | - | |
194 | | - | |
195 | | - | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
196 | 211 | | |
197 | | - | |
198 | 212 | | |
| 213 | + | |
| 214 | + | |
199 | 215 | | |
200 | 216 | | |
201 | 217 | | |
| |||
0 commit comments