Commit eb86df0
committed
libretro-common/net: Priority B hardening in net_http.c
Follow-up to commit 66155ff. Seven additional fixes in
net_http.c covering the remaining unchecked-allocation sites
and the chunked-encoding body parser. One of them (the
Content-Length/chunked collision) is a real OOB read driven by
a hostile server response; the rest are OOM hardening and a
code-quality cleanup.
net_http: reset response->len when entering T_CHUNK body
A hostile server that sends BOTH "Content-Length: N" and
"Transfer-Encoding: chunked" headers leaves response->len set
to N (from the Content-Length pass) while the body parser
switches to T_CHUNK mode. The chunked path uses
response->len as the *position* of the current chunklen line
and reads:
memchr(response->data + response->len + 2, ...,
response->pos - response->len - 2);
With len=N and pos=0 (fresh after header processing), the
subtraction "pos - len" is an unsigned wrap to a huge size_t
and memchr() does a wild OOB read at "data + N + 2" for
roughly SIZE_MAX bytes.
Fix: when the blank line ends the header block and we
transition to P_BODY_CHUNKLEN, explicitly set
response->len = 0 to match the chunked-path contract.
net_http: cap chunked chunklen at NET_HTTP_MAX_CONTENT_LENGTH
strtoul(hex) accepts arbitrarily large values. A hostile
server advertising a chunklen of ffffffffffffffff keeps the
client in a receive loop indefinitely (each
net_http_update() tick decrements a tiny amount from
response->len, never reaching zero). Bandwidth / time DoS.
Fix: reuse the existing NET_HTTP_MAX_CONTENT_LENGTH cap
(256 MiB) for chunks too; oversized chunklen sets state->err
and the dispatch loop tears down the transfer cleanly.
net_http: realloc NULL checks in chunked body parser
Three realloc() calls in net_http_receive_body (end-of-body
shrink, end-of-transfer shrink, mid-parse grow) ignored their
return values. On OOM the original buffer leaked AND
response->data became NULL, which the rest of the function
(and subsequent update ticks) dereference.
Fix: tmp pointer pattern + state->err + return false to abort
cleanly, matching the fix for the header-side reallocs from
commit 66155ff.
net_http: redirect path hardening
net_http_redirect had four unchecked allocations:
* strdup(new_url->domain) and strdup(new_url->path)
(absolute redirect path)
* strdup(location) (relative redirect, absolute path)
* malloc(PATH_MAX_LENGTH) (relative redirect, relative path)
* realloc(response->data, 64*1024) (response buffer reset)
Each failure left a later strlen()/memcpy()/... target NULL
or overwrote state->request.path with NULL. Fix: check each
allocation, on failure set state->err and return true so the
dispatch loop treats the transfer as finished-with-error and
tears it down via the normal path.
net_http: connection_done malloc NULL check
The urlcopy expansion branch (hit when a URL has query parms
but no port and no path separator, e.g. "site.com?x=1") did
an unchecked malloc followed by two memcpys. On OOM the
memcpys would NULL-deref.
Fix: check the malloc and return false; caller treats false
as a malformed URL and frees the partially-initialised
connection via net_http_connection_free.
net_http: connection_set_content malloc NULL check
The postdata malloc was unchecked before the memcpy. Fix:
if malloc fails, leave postdata NULL and reset contentlength
to 0 so net_http_send_request does not advertise a
Content-Length it cannot honour.
net_http: urlencode malloc NULL check
net_http_urlencode's output buffer malloc was unchecked and
the encoding loop then wrote to the NULL pointer. Fix:
leave *dest NULL and return on malloc failure. Callers who
need to distinguish success/failure already check *dest
against NULL (the typical URL-builder pattern).
net_http: stack buffer for Content-Length digit string
net_http_send_request allocated a small buffer via malloc to
hold the decimal representation of request->contentlength,
then snprintf'd into it. Pre-patch the malloc was unchecked
and snprintf-into-NULL would crash. The value is at most
20 digits (UINT64_MAX + NUL), so switch to a 32-byte stack
buffer and drop the malloc entirely. Also replace the
subsequent strlen() with the snprintf return length.
Reachability:
* The Content-Length/chunked collision is remotely triggerable
by a malicious server response; ~every HTTP/1.1 server
distinguishes between the two body framings but a malicious
one is free to send both.
* The chunklen cap closes a bandwidth/time DoS on the same
attack surface.
* The remaining OOM fixes are crash avoidance on constrained
devices.
VC6 compatibility: the file is compiled on all platforms. The
fix uses only size_t / ssize_t / int and standard comparisons;
no new headers. The 32-byte stack buffer for the
Content-Length string replaces the malloc path on both MSVC
(_WIN32) and non-MSVC branches.
Regression test: NONE, for the same reasons as the parent
patch (net_http.c internals are static and exercised by
net_http_update which dispatches to sockets). Compile-verified
under -Wall -Werror for both -DHAVE_THREADS and no-threads
configs. Full libretro-common samples CI dry-run:
Built: 14 Ran: 14 Failed: 0
(the existing http_parse_test in that allowlist passes unchanged)1 parent 8596a03 commit eb86df0
1 file changed
Lines changed: 141 additions & 26 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
250 | 250 | | |
251 | 251 | | |
252 | 252 | | |
| 253 | + | |
| 254 | + | |
| 255 | + | |
| 256 | + | |
| 257 | + | |
| 258 | + | |
| 259 | + | |
253 | 260 | | |
254 | 261 | | |
255 | 262 | | |
| |||
453 | 460 | | |
454 | 461 | | |
455 | 462 | | |
| 463 | + | |
| 464 | + | |
| 465 | + | |
| 466 | + | |
| 467 | + | |
| 468 | + | |
456 | 469 | | |
457 | 470 | | |
458 | 471 | | |
| |||
530 | 543 | | |
531 | 544 | | |
532 | 545 | | |
533 | | - | |
| 546 | + | |
| 547 | + | |
| 548 | + | |
| 549 | + | |
| 550 | + | |
| 551 | + | |
| 552 | + | |
| 553 | + | |
| 554 | + | |
534 | 555 | | |
535 | 556 | | |
536 | 557 | | |
| |||
1114 | 1135 | | |
1115 | 1136 | | |
1116 | 1137 | | |
1117 | | - | |
1118 | | - | |
| 1138 | + | |
| 1139 | + | |
1119 | 1140 | | |
1120 | 1141 | | |
1121 | 1142 | | |
| |||
1130 | 1151 | | |
1131 | 1152 | | |
1132 | 1153 | | |
| 1154 | + | |
| 1155 | + | |
| 1156 | + | |
| 1157 | + | |
| 1158 | + | |
| 1159 | + | |
| 1160 | + | |
1133 | 1161 | | |
1134 | | - | |
1135 | | - | |
1136 | | - | |
| 1162 | + | |
1137 | 1163 | | |
1138 | | - | |
1139 | | - | |
1140 | | - | |
| 1164 | + | |
| 1165 | + | |
1141 | 1166 | | |
1142 | | - | |
1143 | | - | |
| 1167 | + | |
| 1168 | + | |
| 1169 | + | |
| 1170 | + | |
| 1171 | + | |
| 1172 | + | |
| 1173 | + | |
1144 | 1174 | | |
1145 | | - | |
1146 | 1175 | | |
1147 | 1176 | | |
1148 | 1177 | | |
| |||
1241 | 1270 | | |
1242 | 1271 | | |
1243 | 1272 | | |
| 1273 | + | |
1244 | 1274 | | |
| 1275 | + | |
| 1276 | + | |
| 1277 | + | |
| 1278 | + | |
| 1279 | + | |
| 1280 | + | |
| 1281 | + | |
| 1282 | + | |
| 1283 | + | |
| 1284 | + | |
| 1285 | + | |
| 1286 | + | |
| 1287 | + | |
1245 | 1288 | | |
1246 | 1289 | | |
1247 | 1290 | | |
| |||
1396 | 1439 | | |
1397 | 1440 | | |
1398 | 1441 | | |
| 1442 | + | |
| 1443 | + | |
| 1444 | + | |
| 1445 | + | |
| 1446 | + | |
| 1447 | + | |
| 1448 | + | |
| 1449 | + | |
| 1450 | + | |
| 1451 | + | |
| 1452 | + | |
| 1453 | + | |
1399 | 1454 | | |
1400 | 1455 | | |
1401 | 1456 | | |
| |||
1413 | 1468 | | |
1414 | 1469 | | |
1415 | 1470 | | |
| 1471 | + | |
1416 | 1472 | | |
1417 | 1473 | | |
1418 | | - | |
| 1474 | + | |
| 1475 | + | |
| 1476 | + | |
| 1477 | + | |
| 1478 | + | |
| 1479 | + | |
| 1480 | + | |
| 1481 | + | |
1419 | 1482 | | |
1420 | 1483 | | |
1421 | 1484 | | |
| |||
1446 | 1509 | | |
1447 | 1510 | | |
1448 | 1511 | | |
1449 | | - | |
| 1512 | + | |
| 1513 | + | |
| 1514 | + | |
| 1515 | + | |
| 1516 | + | |
| 1517 | + | |
| 1518 | + | |
| 1519 | + | |
| 1520 | + | |
1450 | 1521 | | |
1451 | 1522 | | |
1452 | 1523 | | |
1453 | 1524 | | |
1454 | 1525 | | |
1455 | 1526 | | |
| 1527 | + | |
1456 | 1528 | | |
1457 | | - | |
| 1529 | + | |
| 1530 | + | |
| 1531 | + | |
| 1532 | + | |
| 1533 | + | |
| 1534 | + | |
| 1535 | + | |
1458 | 1536 | | |
1459 | 1537 | | |
1460 | 1538 | | |
1461 | 1539 | | |
1462 | 1540 | | |
1463 | 1541 | | |
1464 | | - | |
| 1542 | + | |
| 1543 | + | |
| 1544 | + | |
| 1545 | + | |
| 1546 | + | |
1465 | 1547 | | |
1466 | 1548 | | |
| 1549 | + | |
| 1550 | + | |
| 1551 | + | |
1467 | 1552 | | |
1468 | 1553 | | |
1469 | 1554 | | |
| |||
1476 | 1561 | | |
1477 | 1562 | | |
1478 | 1563 | | |
| 1564 | + | |
1479 | 1565 | | |
1480 | 1566 | | |
1481 | | - | |
| 1567 | + | |
| 1568 | + | |
| 1569 | + | |
| 1570 | + | |
| 1571 | + | |
| 1572 | + | |
| 1573 | + | |
| 1574 | + | |
| 1575 | + | |
| 1576 | + | |
| 1577 | + | |
| 1578 | + | |
1482 | 1579 | | |
1483 | 1580 | | |
1484 | | - | |
1485 | | - | |
| 1581 | + | |
1486 | 1582 | | |
1487 | 1583 | | |
1488 | | - | |
| 1584 | + | |
1489 | 1585 | | |
1490 | 1586 | | |
1491 | 1587 | | |
1492 | 1588 | | |
1493 | 1589 | | |
1494 | 1590 | | |
| 1591 | + | |
| 1592 | + | |
| 1593 | + | |
| 1594 | + | |
| 1595 | + | |
| 1596 | + | |
1495 | 1597 | | |
1496 | 1598 | | |
1497 | | - | |
| 1599 | + | |
1498 | 1600 | | |
1499 | 1601 | | |
1500 | 1602 | | |
1501 | | - | |
1502 | | - | |
| 1603 | + | |
| 1604 | + | |
| 1605 | + | |
| 1606 | + | |
| 1607 | + | |
| 1608 | + | |
| 1609 | + | |
1503 | 1610 | | |
1504 | 1611 | | |
1505 | | - | |
| 1612 | + | |
1506 | 1613 | | |
1507 | 1614 | | |
1508 | 1615 | | |
1509 | 1616 | | |
1510 | 1617 | | |
1511 | 1618 | | |
1512 | 1619 | | |
1513 | | - | |
1514 | | - | |
| 1620 | + | |
| 1621 | + | |
| 1622 | + | |
| 1623 | + | |
| 1624 | + | |
| 1625 | + | |
| 1626 | + | |
| 1627 | + | |
| 1628 | + | |
| 1629 | + | |
1515 | 1630 | | |
1516 | 1631 | | |
1517 | 1632 | | |
| |||
0 commit comments