#5112·PyMuPDF

Stack-based buffer overflow in JM_set_annot_callout_line

Author: k3rn3lbr3ach3rCreated Sep 7, 2026Updated Sep 8, 2026
LabelsFixed in next releasefix developedHas a test

Description of the bug

In src/extra.i (JM_set_annot_callout_line), a fixed stack buffer of 3 points (fz_point points[3]) is indexed up to caller-controlled count. In src/__init__.py:9816–9817, Page.add_freetext_annot(..., callout=...) passes point_count = len(callout) without length bounds validation.MuPDF's pdf_set_annot_callout_line, a callout line (/CL) has either 2 or 3 points. Passing >= 4 points writes past the stack buffer onto the stack frame, causing a SIGBUS crash.

How to reproduce the bug

python
import pymupdf

doc = pymupdf.open()
page = doc.new_page()
rect = pymupdf.Rect(50, 50, 200, 150)
callout = [(10, 10), (20, 20), (30, 30), (40, 40), (50, 50), (60, 60)]
page.add_freetext_annot(rect, "test", callout=callout)

Security Impact

Because each point coordinate corresponds to two IEEE-754 32-bit floats, this out-of-bounds stack write overwrites callee-saved registers (RBX, RBP, R12–R14) and the saved return address (RIP). I have attached a video below demonstrating an end-to-end RCE proof-of-concept.

PoC Demonstration

https://github.com/user-attachments/assets/c68bd669-b10f-412d-b5f5-8878c6c523f4

PyMuPDF version

1.28.2

Operating system

Linux

Python version

3.13