Skip to content

Commit 04252ec

Browse files
committed
net/http: fix realloc-assign-self leak on shrink failure in net_http_receive_body
The 'response has errored out and is terminal' branch at the top of net_http_receive_body did a classic realloc-to-self assignment: if (response->buflen != response->len) response->data = (char*)realloc(response->data, response->len); If realloc() returns NULL (rare on shrink, not impossible - a shrink can still fail if the allocator needs to split the region or move to a smaller size-class and can't), the original buffer is leaked and response->data becomes NULL. If anything downstream reads response->data (the caller's tear-down that follows could try to decode response body, log it, or copy it), that's a second NULL-deref stacked on the leak. Every other realloc in this file already uses the tmp-pointer pattern - lines 1393, 1409, 1489, 1528, 1544, 1559, 1650. The sibling at line 1528 does the exact same shrink operation (same 'response->buflen != response->len' guard) and correctly keeps the old buffer on failure: char *tmp = (char*)realloc(response->data, response->len); if (!tmp) { state->err = true; return false; } response->data = tmp; Fix: apply the same tmp-pointer pattern to the line 1432 case. Unlike line 1528 which bails out with an error on shrink fail, this site is already in the terminal P_DONE state with state->err effectively set (we entered the branch because 'newlen < 0 || state->err'), so the correct failure behaviour is to just keep the oversized-but-valid buffer and let the return-true upstream mark the state machine done. The buffer will be free()d by net_http_delete once the caller tears the transfer down. Thread-safety: unchanged. net_http_receive_body runs on the thread that owns the http_t state, which is the task queue's processing thread for task-mode usage.
1 parent fe8f7cb commit 04252ec

1 file changed

Lines changed: 13 additions & 1 deletion

File tree

libretro-common/net/net_http.c

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1429,7 +1429,19 @@ static bool net_http_receive_body(struct http_t *state, ssize_t newlen)
14291429
return false;
14301430
response->part = P_DONE;
14311431
if (response->buflen != response->len)
1432-
response->data = (char*)realloc(response->data, response->len);
1432+
{
1433+
/* Shrink response->data from buflen bytes to len bytes.
1434+
* Use a tmp pointer so a realloc() failure (rare on shrink
1435+
* but not impossible) does not overwrite response->data
1436+
* with NULL and leak the original buffer. Sibling shrink
1437+
* path at ~line 1528 already uses this pattern; this was
1438+
* the lone holdout. On failure we keep the oversized-
1439+
* but-valid buffer - this is a terminal state (P_DONE)
1440+
* and the caller tears down shortly afterwards. */
1441+
char *tmp = (char*)realloc(response->data, response->len);
1442+
if (tmp)
1443+
response->data = tmp;
1444+
}
14331445
return true;
14341446
}
14351447

0 commit comments

Comments
 (0)