Commit 1efeddc
committed
network/cloud_sync + netplay: fix NULL-deref, OOM crashes, and realloc-to-self leak
Four bugs found in a sweep of network/ alloc sites.
=== network/cloud_sync/s3.c: s3_url_encode / s3_trim_string ===
Both helpers had the same dead-code NULL guard:
static char* s3_url_encode(const char *input)
{
size_t input_len = strlen(input); /* segfaults on NULL */
size_t output_pos = 0;
char *output = malloc(input_len * 3 + 1);
size_t i;
if (!output)
return NULL;
if (!input) /* dead code */
return NULL;
...
The 'if (!input)' check sat after both strlen(input) and the
malloc sized by strlen's result, so a NULL input crashed in
strlen before we ever reached the guard. s3_trim_string at
line 443 had the identical pattern.
Fix: move the NULL-check to run FIRST, then strlen, then malloc
(also NULL-checked). Dropped the dead post-strlen guard.
These callers feed arbitrary header values / URL path components
through these helpers; a malformed S3 response or a malformed
user-supplied bucket/path was one NULL away from crashing the
cloud-sync subsystem.
=== network/cloud_sync/s3.c: s3_build_auth_header ===
Straight OOM NULL-deref:
auth_header = malloc(1024);
snprintf(auth_header, 1024, ...); /* NULL-deref on OOM */
Also leaked 'signature' (heap-allocated just above by
s3_calculate_signature_v4_with_time) on the crash path - the
free at the bottom of the function was unreachable.
Fix: NULL-check the malloc, free signature + return NULL on OOM.
=== network/cloud_sync/google_drive.c: gdrive_do_patch ===
filestream_seek(cb_st->rfile, 0, SEEK_SET);
len = filestream_get_size(cb_st->rfile);
buf = malloc((size_t)(len + 1)); /* unchecked */
filestream_read(cb_st->rfile, buf, len); /* NULL-deref */
...
task_push_http_transfer_with_content(url, "PATCH",
buf, (size_t)len, ...); /* sends NULL */
Two issues folded together:
- malloc not NULL-checked.
- filestream_get_size returns int64_t; on file-not-readable /
error it returns negative. (size_t)(-1 + 1) == 0, so
malloc(0) is either NULL or a valid zero-sized pointer
depending on libc, and the subsequent filestream_read with
a negative size_t-cast len is undefined at best.
Fix: bail early on len <= 0 (the patch is a PUT of the file's
contents, empty or error both mean nothing to upload), then
NULL-check the malloc. Function is void-returning, so on OOM
just silently skip this upload and let the next sync poll
retry.
=== network/netplay/netplay_frontend.c: state-buffer growth ===
When a peer sends a state_size larger than ours, all buffer
entries are grown to match:
netplay->state_size = state_size;
for (i = 0; i < netplay->buffer_size; i++)
{
netplay->buffer[i].state = realloc(netplay->buffer[i].state, netplay->state_size);
if (!netplay->buffer[i].state)
return false;
}
Classic realloc-assign-self leak: on OOM realloc returns NULL
but leaves the prior buffer[i].state allocation intact; the
self-assign overwrites the only pointer to it and leaks the
whole ring entry.
Fix: realloc into a temp, NULL-check, commit to the ivar only on
success. Still return false on OOM; the caller disconnects the
netplay connection on false return, so the partially-grown
buffer (entries 0..i-1 at new size, i..end at old size) is
about to be torn down anyway and the inconsistency is transient.
=== Thread-safety ===
Unchanged. s3 and google_drive cloud-sync helpers run on the
task-queue worker thread; netplay state handling runs on the
netplay thread. No new locks or ordering requirements
introduced.
=== Reachability ===
Cloud-sync helpers fire on every background sync poll
(configurable, default ~5-minute interval). s3_url_encode and
s3_trim_string are called on every request path / header field.
The netplay realloc is hit when a peer with a different-version
core joins and the two sides disagree on save-state size. All
four are reachable in realistic runtime conditions.1 parent 7f745a9 commit 1efeddc
3 files changed
Lines changed: 56 additions & 15 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1342 | 1342 | | |
1343 | 1343 | | |
1344 | 1344 | | |
1345 | | - | |
| 1345 | + | |
| 1346 | + | |
| 1347 | + | |
| 1348 | + | |
| 1349 | + | |
| 1350 | + | |
| 1351 | + | |
| 1352 | + | |
| 1353 | + | |
| 1354 | + | |
| 1355 | + | |
| 1356 | + | |
| 1357 | + | |
1346 | 1358 | | |
1347 | 1359 | | |
1348 | 1360 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
397 | 397 | | |
398 | 398 | | |
399 | 399 | | |
400 | | - | |
| 400 | + | |
401 | 401 | | |
402 | | - | |
403 | | - | |
404 | | - | |
405 | | - | |
| 402 | + | |
406 | 403 | | |
407 | | - | |
408 | | - | |
409 | | - | |
410 | | - | |
| 404 | + | |
| 405 | + | |
| 406 | + | |
| 407 | + | |
| 408 | + | |
| 409 | + | |
411 | 410 | | |
412 | 411 | | |
413 | 412 | | |
| 413 | + | |
| 414 | + | |
| 415 | + | |
| 416 | + | |
| 417 | + | |
414 | 418 | | |
415 | 419 | | |
416 | 420 | | |
| |||
440 | 444 | | |
441 | 445 | | |
442 | 446 | | |
443 | | - | |
| 447 | + | |
444 | 448 | | |
445 | | - | |
| 449 | + | |
446 | 450 | | |
447 | 451 | | |
448 | 452 | | |
| 453 | + | |
| 454 | + | |
| 455 | + | |
| 456 | + | |
449 | 457 | | |
450 | 458 | | |
451 | 459 | | |
| 460 | + | |
| 461 | + | |
| 462 | + | |
452 | 463 | | |
453 | 464 | | |
454 | 465 | | |
| |||
841 | 852 | | |
842 | 853 | | |
843 | 854 | | |
844 | | - | |
| 855 | + | |
| 856 | + | |
| 857 | + | |
| 858 | + | |
| 859 | + | |
| 860 | + | |
| 861 | + | |
| 862 | + | |
| 863 | + | |
845 | 864 | | |
846 | 865 | | |
847 | 866 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
6104 | 6104 | | |
6105 | 6105 | | |
6106 | 6106 | | |
6107 | | - | |
6108 | | - | |
| 6107 | + | |
| 6108 | + | |
| 6109 | + | |
| 6110 | + | |
| 6111 | + | |
| 6112 | + | |
| 6113 | + | |
| 6114 | + | |
| 6115 | + | |
| 6116 | + | |
| 6117 | + | |
6109 | 6118 | | |
| 6119 | + | |
6110 | 6120 | | |
6111 | 6121 | | |
6112 | 6122 | | |
| |||
0 commit comments