mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-08-31 09:45:24 +02:00
The block table read from an NPDRM PBP's PSAR blob is only reversibly XOR-scrambled, not otherwise validated, so a crafted file fully controls table_[block].size/offset and the header's LBA/block-size fields. Several of these were used without checks: - table_[block].size could exceed blockSize_, causing ReadAt and the KIRK cipher update to write past the end of blockBuf_/tempBuf_ (both allocated as exactly blockSize_ bytes) - a heap buffer overflow. - The block index derived from blockNumber (which can come from an attacker-influenced /sce_lbn.../_size... raw sector open) was never bounds-checked against numBlocks_ before indexing table_[]. - blockLBAs_ could be 0, dividing by zero both when computing numBlocks_ and when computing the block index in ReadBlock. - lbaSize_ could underflow if lbaEnd < lbaStart, and tableSize_ (numBlocks_ * sizeof(table_info)) was computed in 32-bit, so a large numBlocks_ could wrap it to a small value - passing the "did we read the whole table" check while only actually reading (and descrambling) a small prefix, leaving the rest of the table_ array as untouched, uninitialized heap memory that ReadBlock() would later trust. Reject all of these instead.