Commit 7335b37
committed
Security: heap- and stack-overflow fixes across image, audio, IO and cheevos paths
Fixes eight memory-safety bugs sharing a small set of root causes:
uint32_t multiplications feeding size_t allocations, ftell() and
filestream_get_size() returning -1 silently coerced to size_t,
attacker-controlled filenames used as filesystem paths, and
per-channel-count assumptions in audio decode.
* rjpeg, rpng (formats/jpeg/rjpeg.c, formats/png/rpng.c)
Width*height*sizeof(uint32_t) wraps in uint32 on 32-bit hosts
(3DS, Vita, PSP, Wii, Wii U, older Android, 32-bit Windows),
the malloc returns an undersized buffer, and the per-row decode
writes multi-GiB off the end. Add (size_t) casts at every
pixel-buffer malloc site so the multiplication is overflow-safe
on 64-bit. Add a 0x4000 dimension cap matching rbmp.c, rtga.c
and rwebp.c, gated on 32-bit only -- on 64-bit the size_t
arithmetic plus the existing 4 GiB output guard in
rpng_iterate_image are sufficient, and a hard cap would reject
legitimate large images (IrfanView and friends routinely open
tens-of-thousands-pixel JPEGs and PNGs).
* image_transfer Gekko path (formats/image_transfer.c)
Same uint32 multiplication primitive in the post-decode tile
conversion on Wii. Add (size_t) casts. The 32-bit rpng/rjpeg
cap closes the primitive at the source on Wii, but the casts
are kept for defence in depth.
* audio_mixer FLAC (audio/audio_mixer.c)
audio_mixer_mix_flac asks drflac for AUDIO_MIXER_TEMP_BUFFER/2
frames into a 32 KiB stack buffer. drflac writes
frame_count*channel_count floats, so 8-channel FLAC writes
128 KiB into the 32 KiB buffer -- a 96 KiB stack overflow
reaching saved-RIP territory. Reject non-stereo FLAC at
audio_mixer_play_flac time. Mono was already producing wrong
audio per the existing comment in mix_flac; a proper per-
channel-aware fix is left for a separate change.
* cheevos badge_name (cheevos/cheevos_client.c)
rcheevos_client_download_badge interpolates the server-supplied
badge_name into a filesystem path and writes the HTTP body
there. A malicious or MITM'd retroachievements.org could send
badge_name = "../../../../etc/cron.d/evil" and write attacker-
controlled bytes (with a forced .png suffix) anywhere on disk.
Real badge names are numeric IDs optionally suffixed with
"_lock"; reject anything outside [A-Za-z0-9_-].
* cheevos JSON-override loader (cheevos/cheevos_client.c)
ftell()'s long return was assigned to size_t _len, so an ftell
error (-1) became SIZE_MAX; malloc(_len + 1) wrapped to
malloc(0) and contents[_len] = 0 corrupted the heap. Capture
into long, check for the negative sentinel. Debug-only path
(CHEEVOS_JSON_OVERRIDE).
* rxml (formats/xml/rxml.c)
Same pattern, file-scale: filestream_get_size returns -1 on
error and silently flowed into (size_t)(len + 1) as 0 on 64-bit
(malloc(0) -> tiny block) or as a wrapped value on 32-bit
(undersized buffer). Either way memory_buffer[len] = '\0'
wrote far out of bounds. Reject negative sizes and any size
that wouldn't fit in size_t. Reachable via .xml shader presets
and Logiqx .dat database files.
* filestream_read_file (streams/file_stream.c)
The existing size check was
if ((int64_t)(uint64_t)(size + 1) != (size + 1)) goto error;
-- tautological for any positive int64_t, never trips. On
32-bit hosts any file > ~4 GiB silently truncates through the
size_t cast on the malloc and the subsequent filestream_read
overruns the heap. Replace with an explicit size_t-fit check.
* test/formats/test_rpng.c (new)
Six libcheck cases covering rpng_process_ihdr. The two that
exercise the 0x4000 cap (0x4001 and 30000^2) are gated on 32-
bit hosts only since on 64-bit those dimensions are legitimate
after this change. The remaining four (accept-at-limit,
uint32-max-reject, accept-small, zero-rejected) run on every
platform. Wired into Makefile.test alongside the existing
string/utils/hash/lists/queues suites; builds with -Werror
under the same TEST_UNIT_CFLAGS the other tests use; pulls in
trans_stream*.c + -lz for the zlib backend reference rpng.c
links to.1 parent 90b96a3 commit 7335b37
9 files changed
Lines changed: 177 additions & 14 deletions
File tree
- cheevos
- libretro-common
- audio
- formats
- jpeg
- png
- xml
- streams
- ui/drivers
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
294 | 294 | | |
295 | 295 | | |
296 | 296 | | |
| 297 | + | |
297 | 298 | | |
298 | 299 | | |
299 | 300 | | |
| |||
311 | 312 | | |
312 | 313 | | |
313 | 314 | | |
314 | | - | |
| 315 | + | |
315 | 316 | | |
316 | 317 | | |
| 318 | + | |
| 319 | + | |
| 320 | + | |
| 321 | + | |
| 322 | + | |
| 323 | + | |
| 324 | + | |
| 325 | + | |
| 326 | + | |
| 327 | + | |
| 328 | + | |
| 329 | + | |
| 330 | + | |
| 331 | + | |
317 | 332 | | |
318 | 333 | | |
319 | 334 | | |
| |||
489 | 504 | | |
490 | 505 | | |
491 | 506 | | |
| 507 | + | |
| 508 | + | |
| 509 | + | |
| 510 | + | |
| 511 | + | |
| 512 | + | |
| 513 | + | |
| 514 | + | |
| 515 | + | |
| 516 | + | |
| 517 | + | |
| 518 | + | |
| 519 | + | |
| 520 | + | |
| 521 | + | |
| 522 | + | |
| 523 | + | |
| 524 | + | |
| 525 | + | |
| 526 | + | |
| 527 | + | |
| 528 | + | |
| 529 | + | |
| 530 | + | |
| 531 | + | |
| 532 | + | |
| 533 | + | |
| 534 | + | |
| 535 | + | |
| 536 | + | |
| 537 | + | |
| 538 | + | |
| 539 | + | |
492 | 540 | | |
493 | 541 | | |
494 | 542 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
23 | 23 | | |
24 | 24 | | |
25 | 25 | | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
26 | 32 | | |
27 | 33 | | |
28 | 34 | | |
| |||
45 | 51 | | |
46 | 52 | | |
47 | 53 | | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
48 | 58 | | |
49 | 59 | | |
50 | 60 | | |
51 | 61 | | |
52 | 62 | | |
53 | | - | |
| 63 | + | |
| 64 | + | |
54 | 65 | | |
55 | 66 | | |
56 | 67 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
723 | 723 | | |
724 | 724 | | |
725 | 725 | | |
| 726 | + | |
| 727 | + | |
| 728 | + | |
| 729 | + | |
| 730 | + | |
| 731 | + | |
| 732 | + | |
| 733 | + | |
| 734 | + | |
| 735 | + | |
| 736 | + | |
| 737 | + | |
| 738 | + | |
| 739 | + | |
| 740 | + | |
| 741 | + | |
| 742 | + | |
| 743 | + | |
| 744 | + | |
726 | 745 | | |
727 | 746 | | |
728 | 747 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
299 | 299 | | |
300 | 300 | | |
301 | 301 | | |
302 | | - | |
| 302 | + | |
| 303 | + | |
| 304 | + | |
| 305 | + | |
| 306 | + | |
| 307 | + | |
| 308 | + | |
| 309 | + | |
| 310 | + | |
| 311 | + | |
| 312 | + | |
| 313 | + | |
| 314 | + | |
| 315 | + | |
303 | 316 | | |
304 | 317 | | |
305 | 318 | | |
306 | 319 | | |
307 | | - | |
| 320 | + | |
| 321 | + | |
308 | 322 | | |
309 | 323 | | |
310 | 324 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2583 | 2583 | | |
2584 | 2584 | | |
2585 | 2585 | | |
| 2586 | + | |
| 2587 | + | |
| 2588 | + | |
| 2589 | + | |
| 2590 | + | |
| 2591 | + | |
| 2592 | + | |
| 2593 | + | |
| 2594 | + | |
| 2595 | + | |
| 2596 | + | |
| 2597 | + | |
| 2598 | + | |
| 2599 | + | |
| 2600 | + | |
| 2601 | + | |
| 2602 | + | |
| 2603 | + | |
2586 | 2604 | | |
2587 | 2605 | | |
2588 | 2606 | | |
| |||
4149 | 4167 | | |
4150 | 4168 | | |
4151 | 4169 | | |
4152 | | - | |
| 4170 | + | |
| 4171 | + | |
| 4172 | + | |
| 4173 | + | |
| 4174 | + | |
4153 | 4175 | | |
4154 | 4176 | | |
4155 | 4177 | | |
| |||
4653 | 4675 | | |
4654 | 4676 | | |
4655 | 4677 | | |
4656 | | - | |
| 4678 | + | |
4657 | 4679 | | |
4658 | 4680 | | |
4659 | 4681 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
658 | 658 | | |
659 | 659 | | |
660 | 660 | | |
| 661 | + | |
| 662 | + | |
| 663 | + | |
| 664 | + | |
| 665 | + | |
| 666 | + | |
| 667 | + | |
| 668 | + | |
| 669 | + | |
| 670 | + | |
| 671 | + | |
| 672 | + | |
| 673 | + | |
| 674 | + | |
| 675 | + | |
| 676 | + | |
| 677 | + | |
| 678 | + | |
| 679 | + | |
| 680 | + | |
| 681 | + | |
| 682 | + | |
661 | 683 | | |
662 | 684 | | |
663 | 685 | | |
| |||
696 | 718 | | |
697 | 719 | | |
698 | 720 | | |
| 721 | + | |
| 722 | + | |
| 723 | + | |
| 724 | + | |
| 725 | + | |
| 726 | + | |
| 727 | + | |
| 728 | + | |
| 729 | + | |
699 | 730 | | |
700 | 731 | | |
701 | 732 | | |
| |||
1063 | 1094 | | |
1064 | 1095 | | |
1065 | 1096 | | |
1066 | | - | |
| 1097 | + | |
1067 | 1098 | | |
1068 | 1099 | | |
1069 | 1100 | | |
| |||
1371 | 1402 | | |
1372 | 1403 | | |
1373 | 1404 | | |
1374 | | - | |
1375 | | - | |
| 1405 | + | |
| 1406 | + | |
1376 | 1407 | | |
1377 | | - | |
1378 | | - | |
| 1408 | + | |
| 1409 | + | |
1379 | 1410 | | |
1380 | 1411 | | |
1381 | 1412 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
21 | 21 | | |
22 | 22 | | |
23 | 23 | | |
| 24 | + | |
24 | 25 | | |
25 | 26 | | |
26 | 27 | | |
| |||
101 | 102 | | |
102 | 103 | | |
103 | 104 | | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
104 | 113 | | |
105 | 114 | | |
106 | 115 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
629 | 629 | | |
630 | 630 | | |
631 | 631 | | |
632 | | - | |
| 632 | + | |
| 633 | + | |
| 634 | + | |
| 635 | + | |
| 636 | + | |
| 637 | + | |
| 638 | + | |
| 639 | + | |
633 | 640 | | |
634 | | - | |
| 641 | + | |
| 642 | + | |
635 | 643 | | |
636 | 644 | | |
637 | 645 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
7508 | 7508 | | |
7509 | 7509 | | |
7510 | 7510 | | |
7511 | | - | |
| 7511 | + | |
| 7512 | + | |
7512 | 7513 | | |
7513 | 7514 | | |
7514 | 7515 | | |
| |||
0 commit comments