Skip to content

dma: bound Ch2 and PVR DMA lengths to RAM and VRAM - #2548

Open
JoeMatt wants to merge 1 commit into
flyinghead:masterfrom
Provenance-Emu:fix/dma-length-bounds
Open

JoeMatt wants to merge 1 commit into
flyinghead:masterfrom
Provenance-Emu:fix/dma-length-bounds

Conversation

@JoeMatt

@JoeMatt JoeMatt commented Oct 13, 2026

Copy link
Copy Markdown
Contributor

SB_C2DLEN and SB_PDLEN are set by the game, and nothing checks them
against the memory they cover:

  • Ch2 to the TA: after the split at the end of RAM, the rest of the
    source can still be invalid (longer than RAM, or src stepped from the
    last area 3 mirror into area 4). GetMemPtr() then returns null and
    TAWrite() dereferences it. Skip the transfer and complete the DMA as
    usual.
  • Ch2 64-bit texture path: the RAM read is split at the end of RAM but
    the VRAM write isn't, so a long transfer copies past the end of VRAM.
  • PVR DMA: WriteMemBlock_nommu_dma() copies len bytes between RAM and
    VRAM with no bound on either side.

Clamp the length to the end of the region. A valid transfer already
fits, so only out-of-range lengths change.

Testing: compiles in the libretro core and the standalone build (macOS arm64). Not run on content.

🤖 Generated with Claude Code

Copilot AI balanced review requested due to automatic review settings October 13, 2026 21:59

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

SB_C2DLEN and SB_PDLEN are set by the game, and nothing checks them
against the memory they cover:

- Ch2 to the TA: after the split at the end of RAM, the rest of the
  source can still be invalid (longer than RAM, or src stepped from the
  last area 3 mirror into area 4). GetMemPtr() then returns null and
  TAWrite() dereferences it. Skip the transfer and complete the DMA as
  usual.
- Ch2 64-bit texture path: the RAM read is split at the end of RAM but
  the VRAM write isn't, so a long transfer copies past the end of VRAM.
- PVR DMA: WriteMemBlock_nommu_dma() copies len bytes between RAM and
  VRAM with no bound on either side.

Clamp the length to the end of the region. A valid transfer already
fits, so only out-of-range lengths change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@JoeMatt
JoeMatt force-pushed the fix/dma-length-bounds branch from 58ec0e3 to a85b404 Compare October 13, 2026 22:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants