Mpeg: Check memory access range on GetPointer().
This commit is contained in:
parent
fb0ed6e165
commit
c44d787df4
3 changed files with 59 additions and 48 deletions
|
@ -974,7 +974,9 @@ static bool decodePmpVideo(PSPPointer<SceMpegRingBuffer> ringbuffer, u32 pmpctxA
|
||||||
for (int i = 0; i < pmp_nBlocks; i++){
|
for (int i = 0; i < pmp_nBlocks; i++){
|
||||||
auto lli = PSPPointer<SceMpegLLI>::Create(pmp_videoSource);
|
auto lli = PSPPointer<SceMpegLLI>::Create(pmp_videoSource);
|
||||||
// add source block into pmpframes
|
// add source block into pmpframes
|
||||||
pmpframes->add(Memory::GetPointerWrite(lli->pSrc), lli->iSize);
|
const uint8_t *ptr = Memory::GetPointerRange(lli->pSrc, lli->iSize);
|
||||||
|
if (ptr)
|
||||||
|
pmpframes->add(ptr, lli->iSize);
|
||||||
// get next block
|
// get next block
|
||||||
pmp_videoSource += sizeof(SceMpegLLI);
|
pmp_videoSource += sizeof(SceMpegLLI);
|
||||||
}
|
}
|
||||||
|
@ -1502,7 +1504,6 @@ void PostPutAction::run(MipsCall &call) {
|
||||||
|
|
||||||
MpegContext *ctx = getMpegCtx(ringbuffer->mpeg);
|
MpegContext *ctx = getMpegCtx(ringbuffer->mpeg);
|
||||||
int writeOffset = ringbuffer->packetsWritePos % (s32)ringbuffer->packets;
|
int writeOffset = ringbuffer->packetsWritePos % (s32)ringbuffer->packets;
|
||||||
const u8 *data = Memory::GetPointer(ringbuffer->data + writeOffset * 2048);
|
|
||||||
|
|
||||||
int packetsAddedThisRound = currentMIPS->r[MIPS_REG_V0];
|
int packetsAddedThisRound = currentMIPS->r[MIPS_REG_V0];
|
||||||
if (packetsAddedThisRound > 0) {
|
if (packetsAddedThisRound > 0) {
|
||||||
|
@ -1514,9 +1515,10 @@ void PostPutAction::run(MipsCall &call) {
|
||||||
// TODO: Faster / less wasteful validation.
|
// TODO: Faster / less wasteful validation.
|
||||||
std::unique_ptr<MpegDemux> demuxer(new MpegDemux(packetsAddedThisRound * 2048, 0));
|
std::unique_ptr<MpegDemux> demuxer(new MpegDemux(packetsAddedThisRound * 2048, 0));
|
||||||
int readOffset = ringbuffer->packetsRead % (s32)ringbuffer->packets;
|
int readOffset = ringbuffer->packetsRead % (s32)ringbuffer->packets;
|
||||||
|
uint32_t bufSize = Memory::ValidSize(ringbuffer->data + readOffset * 2048, packetsAddedThisRound * 2048);
|
||||||
const u8 *buf = Memory::GetPointer(ringbuffer->data + readOffset * 2048);
|
const u8 *buf = Memory::GetPointer(ringbuffer->data + readOffset * 2048);
|
||||||
bool invalid = false;
|
bool invalid = false;
|
||||||
for (int i = 0; i < packetsAddedThisRound; ++i) {
|
for (uint32_t i = 0; i < bufSize / 2048; ++i) {
|
||||||
demuxer->addStreamData(buf, 2048);
|
demuxer->addStreamData(buf, 2048);
|
||||||
buf += 2048;
|
buf += 2048;
|
||||||
|
|
||||||
|
@ -1548,7 +1550,9 @@ void PostPutAction::run(MipsCall &call) {
|
||||||
WARN_LOG(ME, "sceMpegRingbufferPut clamping packetsAdded old=%i new=%i", packetsAddedThisRound, ringbuffer->packets - ringbuffer->packetsAvail);
|
WARN_LOG(ME, "sceMpegRingbufferPut clamping packetsAdded old=%i new=%i", packetsAddedThisRound, ringbuffer->packets - ringbuffer->packetsAvail);
|
||||||
packetsAddedThisRound = ringbuffer->packets - ringbuffer->packetsAvail;
|
packetsAddedThisRound = ringbuffer->packets - ringbuffer->packetsAvail;
|
||||||
}
|
}
|
||||||
int actuallyAdded = ctx->mediaengine == NULL ? 8 : ctx->mediaengine->addStreamData(data, packetsAddedThisRound * 2048) / 2048;
|
const u8 *data = Memory::GetPointer(ringbuffer->data + writeOffset * 2048);
|
||||||
|
uint32_t dataSize = Memory::ValidSize(ringbuffer->data + writeOffset * 2048, packetsAddedThisRound * 2048);
|
||||||
|
int actuallyAdded = ctx->mediaengine == NULL ? 8 : ctx->mediaengine->addStreamData(data, dataSize) / 2048;
|
||||||
if (actuallyAdded != packetsAddedThisRound) {
|
if (actuallyAdded != packetsAddedThisRound) {
|
||||||
WARN_LOG_REPORT(ME, "sceMpegRingbufferPut(): unable to enqueue all added packets, going to overwrite some frames.");
|
WARN_LOG_REPORT(ME, "sceMpegRingbufferPut(): unable to enqueue all added packets, going to overwrite some frames.");
|
||||||
}
|
}
|
||||||
|
@ -2175,10 +2179,13 @@ static int __MpegAvcConvertToYuv420(const void *data, u32 bufferOutputAddr, int
|
||||||
u32 *imageBuffer = (u32*)data;
|
u32 *imageBuffer = (u32*)data;
|
||||||
int sizeY = width * height;
|
int sizeY = width * height;
|
||||||
int sizeCb = sizeY >> 2;
|
int sizeCb = sizeY >> 2;
|
||||||
u8 *Y = (u8*)Memory::GetPointer(bufferOutputAddr);
|
u8 *Y = Memory::GetPointerWriteRange(bufferOutputAddr, sizeY + sizeCb + sizeCb);
|
||||||
u8 *Cb = Y + sizeY;
|
u8 *Cb = Y + sizeY;
|
||||||
u8 *Cr = Cb + sizeCb;
|
u8 *Cr = Cb + sizeCb;
|
||||||
|
|
||||||
|
if (!Y)
|
||||||
|
return hleLogError(ME, 0, "Bad output buffer pointer for yuv conv: %08x", bufferOutputAddr);
|
||||||
|
|
||||||
for (int y = 0; y < height; y += 2) {
|
for (int y = 0; y < height; y += 2) {
|
||||||
for (int x = 0; x < width; x += 2) {
|
for (int x = 0; x < width; x += 2) {
|
||||||
u32 abgr0 = imageBuffer[width * (y + 0) + x + 0];
|
u32 abgr0 = imageBuffer[width * (y + 0) + x + 0];
|
||||||
|
|
|
@ -777,24 +777,6 @@ inline void writeVideoLineABGR4444(void *destp, const void *srcp, int width) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int MediaEngine::writeVideoImage(u32 bufferPtr, int frameWidth, int videoPixelMode) {
|
int MediaEngine::writeVideoImage(u32 bufferPtr, int frameWidth, int videoPixelMode) {
|
||||||
if (!Memory::IsValidAddress(bufferPtr) || frameWidth > 2048) {
|
|
||||||
// Clearly invalid values. Let's just not.
|
|
||||||
ERROR_LOG_REPORT(ME, "Ignoring invalid video decode address %08x/%x", bufferPtr, frameWidth);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
u8 *buffer = Memory::GetPointerWrite(bufferPtr);
|
|
||||||
|
|
||||||
#ifdef USE_FFMPEG
|
|
||||||
if (!m_pFrame || !m_pFrameRGB)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
// lock the image size
|
|
||||||
int height = m_desHeight;
|
|
||||||
int width = m_desWidth;
|
|
||||||
u8 *imgbuf = buffer;
|
|
||||||
const u8 *data = m_pFrameRGB->data[0];
|
|
||||||
|
|
||||||
int videoLineSize = 0;
|
int videoLineSize = 0;
|
||||||
switch (videoPixelMode) {
|
switch (videoPixelMode) {
|
||||||
case GE_CMODE_32BIT_ABGR8888:
|
case GE_CMODE_32BIT_ABGR8888:
|
||||||
|
@ -807,7 +789,25 @@ int MediaEngine::writeVideoImage(u32 bufferPtr, int frameWidth, int videoPixelMo
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
int videoImageSize = videoLineSize * height;
|
int videoImageSize = videoLineSize * m_desHeight;
|
||||||
|
|
||||||
|
if (!Memory::IsValidRange(bufferPtr, videoImageSize) || frameWidth > 2048) {
|
||||||
|
// Clearly invalid values. Let's just not.
|
||||||
|
ERROR_LOG_REPORT(ME, "Ignoring invalid video decode address %08x/%x", bufferPtr, frameWidth);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
u8 *buffer = Memory::GetPointerWriteUnchecked(bufferPtr);
|
||||||
|
|
||||||
|
#ifdef USE_FFMPEG
|
||||||
|
if (!m_pFrame || !m_pFrameRGB)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// lock the image size
|
||||||
|
int height = m_desHeight;
|
||||||
|
int width = m_desWidth;
|
||||||
|
u8 *imgbuf = buffer;
|
||||||
|
const u8 *data = m_pFrameRGB->data[0];
|
||||||
|
|
||||||
bool swizzle = Memory::IsVRAMAddress(bufferPtr) && (bufferPtr & 0x00200000) == 0x00200000;
|
bool swizzle = Memory::IsVRAMAddress(bufferPtr) && (bufferPtr & 0x00200000) == 0x00200000;
|
||||||
if (swizzle) {
|
if (swizzle) {
|
||||||
|
@ -867,22 +867,6 @@ int MediaEngine::writeVideoImage(u32 bufferPtr, int frameWidth, int videoPixelMo
|
||||||
|
|
||||||
int MediaEngine::writeVideoImageWithRange(u32 bufferPtr, int frameWidth, int videoPixelMode,
|
int MediaEngine::writeVideoImageWithRange(u32 bufferPtr, int frameWidth, int videoPixelMode,
|
||||||
int xpos, int ypos, int width, int height) {
|
int xpos, int ypos, int width, int height) {
|
||||||
if (!Memory::IsValidAddress(bufferPtr) || frameWidth > 2048) {
|
|
||||||
// Clearly invalid values. Let's just not.
|
|
||||||
ERROR_LOG_REPORT(ME, "Ignoring invalid video decode address %08x/%x", bufferPtr, frameWidth);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
u8 *buffer = Memory::GetPointerWrite(bufferPtr);
|
|
||||||
|
|
||||||
#ifdef USE_FFMPEG
|
|
||||||
if (!m_pFrame || !m_pFrameRGB)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
// lock the image size
|
|
||||||
u8 *imgbuf = buffer;
|
|
||||||
const u8 *data = m_pFrameRGB->data[0];
|
|
||||||
|
|
||||||
int videoLineSize = 0;
|
int videoLineSize = 0;
|
||||||
switch (videoPixelMode) {
|
switch (videoPixelMode) {
|
||||||
case GE_CMODE_32BIT_ABGR8888:
|
case GE_CMODE_32BIT_ABGR8888:
|
||||||
|
@ -894,8 +878,24 @@ int MediaEngine::writeVideoImageWithRange(u32 bufferPtr, int frameWidth, int vid
|
||||||
videoLineSize = frameWidth * sizeof(u16);
|
videoLineSize = frameWidth * sizeof(u16);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
int videoImageSize = videoLineSize * height;
|
int videoImageSize = videoLineSize * height;
|
||||||
|
|
||||||
|
if (!Memory::IsValidRange(bufferPtr, videoImageSize) || frameWidth > 2048) {
|
||||||
|
// Clearly invalid values. Let's just not.
|
||||||
|
ERROR_LOG_REPORT(ME, "Ignoring invalid video decode address %08x/%x", bufferPtr, frameWidth);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
u8 *buffer = Memory::GetPointerWriteUnchecked(bufferPtr);
|
||||||
|
|
||||||
|
#ifdef USE_FFMPEG
|
||||||
|
if (!m_pFrame || !m_pFrameRGB)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// lock the image size
|
||||||
|
u8 *imgbuf = buffer;
|
||||||
|
const u8 *data = m_pFrameRGB->data[0];
|
||||||
|
|
||||||
bool swizzle = Memory::IsVRAMAddress(bufferPtr) && (bufferPtr & 0x00200000) == 0x00200000;
|
bool swizzle = Memory::IsVRAMAddress(bufferPtr) && (bufferPtr & 0x00200000) == 0x00200000;
|
||||||
if (swizzle) {
|
if (swizzle) {
|
||||||
imgbuf = new u8[videoImageSize];
|
imgbuf = new u8[videoImageSize];
|
||||||
|
@ -1006,11 +1006,10 @@ int MediaEngine::getNextAudioFrame(u8 **buf, int *headerCode1, int *headerCode2)
|
||||||
}
|
}
|
||||||
|
|
||||||
int MediaEngine::getAudioSamples(u32 bufferPtr) {
|
int MediaEngine::getAudioSamples(u32 bufferPtr) {
|
||||||
if (!Memory::IsValidAddress(bufferPtr)) {
|
u8 *buffer = Memory::GetPointerWriteRange(bufferPtr, 8192);
|
||||||
|
if (buffer == nullptr) {
|
||||||
ERROR_LOG_REPORT(ME, "Ignoring bad audio decode address %08x during video playback", bufferPtr);
|
ERROR_LOG_REPORT(ME, "Ignoring bad audio decode address %08x during video playback", bufferPtr);
|
||||||
}
|
}
|
||||||
|
|
||||||
u8 *buffer = Memory::GetPointerWrite(bufferPtr);
|
|
||||||
if (!m_demux) {
|
if (!m_demux) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -252,7 +252,10 @@ bool SimpleAudio::Decode(const uint8_t *inbuf, int inbytes, uint8_t *outbuf, int
|
||||||
}
|
}
|
||||||
|
|
||||||
// convert audio to AV_SAMPLE_FMT_S16
|
// convert audio to AV_SAMPLE_FMT_S16
|
||||||
int swrRet = swr_convert(swrCtx_, &outbuf, frame_->nb_samples, (const u8 **)frame_->extended_data, frame_->nb_samples);
|
int swrRet = 0;
|
||||||
|
if (outbuf != nullptr) {
|
||||||
|
swrRet = swr_convert(swrCtx_, &outbuf, frame_->nb_samples, (const u8 **)frame_->extended_data, frame_->nb_samples);
|
||||||
|
}
|
||||||
if (swrRet < 0) {
|
if (swrRet < 0) {
|
||||||
ERROR_LOG(ME, "swr_convert: Error while converting: %d", swrRet);
|
ERROR_LOG(ME, "swr_convert: Error while converting: %d", swrRet);
|
||||||
return false;
|
return false;
|
||||||
|
@ -338,7 +341,7 @@ size_t AuCtx::FindNextMp3Sync() {
|
||||||
// return output pcm size, <0 error
|
// return output pcm size, <0 error
|
||||||
u32 AuCtx::AuDecode(u32 pcmAddr) {
|
u32 AuCtx::AuDecode(u32 pcmAddr) {
|
||||||
u32 outptr = PCMBuf + nextOutputHalf * PCMBufSize / 2;
|
u32 outptr = PCMBuf + nextOutputHalf * PCMBufSize / 2;
|
||||||
auto outbuf = Memory::GetPointerWrite(outptr);
|
auto outbuf = Memory::GetPointerWriteRange(outptr, PCMBufSize / 2);
|
||||||
int outpcmbufsize = 0;
|
int outpcmbufsize = 0;
|
||||||
|
|
||||||
if (pcmAddr)
|
if (pcmAddr)
|
||||||
|
@ -380,10 +383,12 @@ u32 AuCtx::AuDecode(u32 pcmAddr) {
|
||||||
if (outpcmbufsize == 0 && !end) {
|
if (outpcmbufsize == 0 && !end) {
|
||||||
// If we didn't decode anything, we fill this half of the buffer with zeros.
|
// If we didn't decode anything, we fill this half of the buffer with zeros.
|
||||||
outpcmbufsize = PCMBufSize / 2;
|
outpcmbufsize = PCMBufSize / 2;
|
||||||
memset(outbuf, 0, outpcmbufsize);
|
if (outbuf != nullptr)
|
||||||
|
memset(outbuf, 0, outpcmbufsize);
|
||||||
} else if ((u32)outpcmbufsize < PCMBufSize) {
|
} else if ((u32)outpcmbufsize < PCMBufSize) {
|
||||||
// TODO: Not sure it actually zeros this out.
|
// TODO: Not sure it actually zeros this out.
|
||||||
memset(outbuf + outpcmbufsize, 0, PCMBufSize / 2 - outpcmbufsize);
|
if (outbuf != nullptr)
|
||||||
|
memset(outbuf + outpcmbufsize, 0, PCMBufSize / 2 - outpcmbufsize);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (outpcmbufsize != 0)
|
if (outpcmbufsize != 0)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue