U-DESKTOP-SPFP6AQ\twistedtechre 7939d92b3e core: ROM loader hardening - reject malformed iNES/UNIF/FDS inputs
Pass 9 audit of the iNES, UNIF, and FDS loaders against malformed ROM
input under AddressSanitizer + UndefinedBehaviorSanitizer. The ROM file
is the entry point for untrusted input, so any out-of-bounds read,
write, integer overflow, or DoS in the parsers is a real attack
surface for anyone who downloads ROMs from third-party sites.

Two pre-existing crash inputs caught by ASAN
============================================

  test_zero_prg.nes  : iNES 2.0 header that decodes to PRGRomSize == 0.
                       Master loads it: uppow2(0) = 0, FCEU_malloc(0)
                       returns an implementation-defined small/null
                       buffer, and the first PRG fetch from the reset
                       vector reads past the heap.
                       =>  heap-buffer-overflow at cart.c:138 CartBR

  test_mapr_huge_unif.unf : UNIF MAPR chunk with declared size 0xFFFFFFFF.
                       Master computes FCEU_malloc(uchead.info + 1)
                       which overflows uint32_t to FCEU_malloc(0); the
                       subsequent fread of 4 GiB then heap-corrupts and
                       boardname[uchead.info] = 0 finally segfaults.
                       =>  SEGV at unif.c:345 SetBoardName

Plus a UNIF CTRL DoS: a CTRL chunk declaring 4 GiB drives the
diagnostic dump loop through 4 billion FCEU_fgetc() calls (and the
loop didn't even break on EOF), printf'ing each byte to the log.

Pass 9 fuzz inputs reject every one of those cleanly. Bit-exact
identical audio + video output to upstream master across nine valid
test ROMs (silent, idle, active gameplay, 5-channel max-volume stress,
and the per-APU-channel test ROMs).

Changes
=======

src/ines.c (iNESLoad):

  * Reject PRGRomSize <= 0. The legacy iNES path already substitutes
    ROM_size = 256 when the byte is zero, but the iNES 2.0 exponent
    encoding can still resolve to zero from a malformed header.

  * Cast PRGRomSize + CHRRomSize to uint64_t before adding. Both fields
    are int with a 0x40000000 cap from iNES_read_header_info, so the
    addition can reach 0x80000000 - signed overflow (UB) that wraps
    negative and then sign-extends bogusly into the uint64_t romSize
    used for size sanity prints.

  * Check the FCEU_fread return value on every read (trainer, PRG,
    CHR, MiscROM) and warn on truncation. The buffers are pre-filled
    with 0xFF (open bus) or zero, so a short read leaves a sane tail,
    but the user got no warning that the file was incomplete.

src/unif.c:

  * FixRomSize: change return type from int to uint32_t. The 0x80000000
    cap was being implicitly converted from signed int (where it is
    INT_MIN) to the uint64_t UNIF_PRGROMSize/CHRROMSize callers, sign-
    extending to 0xFFFFFFFF80000000 - a 16 EiB malloc request.

  * SetBoardName: cap uchead.info at 256 (in addition to the existing
    < 4 reject). Real UNIF board-name strings are < 32 characters.
    Without the upper bound, uchead.info near 0xFFFFFFFF makes
    (uchead.info + 1) wrap to zero and FCEU_malloc returns a tiny
    buffer that the subsequent 4 GiB fread heap-overflows. Also check
    the fread return.

  * DoMirroring / CTRL: cap the diagnostic dump-and-skip path at 16
    bytes and FCEU_fseek past the remainder. Without the cap, a chunk
    declaring info ~ 0xFFFFFFFF would spin 4 billion FCEU_fgetc/printf
    iterations - CPU-bound DoS. The CTRL branch also lacked an EOF
    break, so a truncated stream would keep returning -1 forever.

src/fds.c (SubLoad):

  * Zero-initialise the stack header[16] so partial reads see
    deterministic zeros rather than stack garbage. The fsize >= 16
    guard reduces the chance of a short read but doesn't eliminate
    it (mid-stream IO error etc).

  * Check the FCEU_fread return on the header read and on each
    65500-byte side read; warn on truncation.

Verification
============

ASAN/UBSAN sweep across 18 fuzz inputs:
  * Every case that crashed master now LOAD_REJECTED on pass 9.
  * No new UBSAN/ASAN findings introduced (the pre-existing
    ppu.c:85 left-shift UB shows up identically on both sides).

Bit-exact audio dump regression vs master across 9 valid ROMs at 600
frames each: identical output. No behavioral change for legitimate
input.
2026-05-04 08:12:05 +02:00
2024-09-23 05:55:21 -07:00
2023-01-02 19:47:36 +01:00
2026-04-02 10:14:04 +01:00
Fix
2017-12-21 20:40:28 +09:00
2014-12-23 09:50:29 +01:00
2015-08-06 13:28:43 +02:00
2025-09-03 16:20:50 +02:00
2019-06-28 23:44:06 +02:00

Build Status Build status

FCE Ultra mappers modified

FCEU "mappers modified" is an unofficial build of FCEU Ultra by CaH4e3, which supports a lot of new mappers including some obscure mappers such as one for unlicensed NES ROM's.

Sequential targets Light Guns support added

Support for Sequential targets Light Guns has been added. "Gun Aux A" serves as light sensor logic input.

Description
Pinned internal source mirror of libretro/libretro-fceumm for Supergame releases
Readme 4.3 MiB
Languages
C 97.7%
Python 2%
C++ 0.2%