Fix integer overflow in PMF video frame buffer allocation

pmf_init reported stream dimensions without a cap, and PMFView::Draw
allocated width * height * 4 with 32-bit int arithmetic, so a crafted
ICON1.PMF could overflow the allocation to a small buffer while
sws_scale wrote the full frame.

- Reject videos with dimensions outside 1..720x480 in pmf_init (PMFs on
  the PSP never exceed 720x480).
- Use size_t arithmetic for the frame buffer allocation.
This commit is contained in:
Henrik Rydgård committed 2026-08-01 11:57:27 +02:00
1 parent 983068b07a
commit 5d10f281ef
2 files changed
+11 -1

No files matched your search

+8
View File
@@ -141,6 +141,14 @@ int pmf_init(PMFPlayer* ps, const uint8_t* data, size_t size, int* out_w, int* o
AVCodec* codec = avcodec_find_decoder(ps->video_ctx->codec_id);
if (!codec || avcodec_open2(ps->video_ctx, codec, nullptr) < 0) return -1;
// Reject absurd dimensions: PMF video on PSP never exceeds 720x480, and
// larger values could overflow the caller's frame buffer allocation
// (width * height * 4) and drive huge sws_scale writes.
if (ps->video_ctx->width <= 0 || ps->video_ctx->height <= 0 ||
ps->video_ctx->width > 720 || ps->video_ctx->height > 480) {
return -1;
}
ps->frame = av_frame_alloc();
ps->rgb_frame = av_frame_alloc();
ps->last_pts = -1.0;
+3 -1
View File
@@ -113,7 +113,9 @@ public:
Draw::DrawContext *draw = dc.GetDrawContext();
std::vector<u8> frame(width_ * height_ * 4);
// Dimensions are capped by pmf_init, but use size_t arithmetic anyway
// so a regression can't overflow the allocation.
std::vector<u8> frame((size_t)width_ * (size_t)height_ * 4);
if (pmf_update(player_, startTime_.ElapsedSeconds(), frame.data())) {
if (curFrame_) {
curFrame_->Release();