You need to agree to share your contact information to access this model

This repository is publicly accessible, but you have to accept the conditions to access its files and content.

Log in or Sign Up to review the conditions and access this model content.

YAML Metadata Warning:empty or missing yaml metadata in repo card

Check out the documentation for more information.

MLeap PCA tensor-shape integer-overflow native OOB read PoC

Summary

MLeap 0.25.1 accepts a PCA .mleap archive whose declared Bundle.ML tensor dimensions are 8192 by 524289 while its serialized double array contains only 8192 elements. The mathematical product is 4,294,975,488, but signed 32-bit multiplication wraps this to 8192. Consequently the tensor-size check accepts the short array and the PCA bundle loader constructs a Spark DenseMatrix with a logical shape far larger than its backing double array.

The supplied malicious .mleap file is a real 1,053-byte MLeap Bundle.ML archive. It loads successfully through BundleFile.loadMleapBundle(). During normal PCA inference, PcaModel applies principalComponents.transpose.multiply(vector). On Linux with the stock native BLAS backend, the call reaches dgemv with the logical 8192 by 524289 dimensions while the JNI-pinned Java double array has length 8192. The process terminates with SIGSEGV in libblas dgemv because native BLAS reads beyond the array.

This is CPU-only native memory corruption. The PoC demonstrates an out-of-bounds read and process crash; it deliberately does not attempt exploitation beyond the observed boundary violation.

Tested against MLeap 0.25.1, release commit bc677e6d7688570f987bb1b57dfbcb61035a061b, which pins Apache Spark 4.1.1.

Files

  • malicious_pca_shape_overflow.mleap: required malicious MLeap model file.
  • control_pca.mleap: valid one-element PCA model for comparison.
  • PcaBundleOverflowAudit.scala: creates, loads, and invokes both bundles.
  • verify_bundle.py: static archive verifier using only Python standard-library modules.
  • build_and_verify.sh and run_in_docker.sh: reproducible CPU-only Linux verification.

Static verification

Run:

python verify_bundle.py --report verify_report.json

The verifier checks that the malicious archive contains a PCA tensor with dimensions 8192 and 524289, exactly 8192 serialized doubles, and a wrapped signed 32-bit product of 8192. It also checks the uploaded payload hash:

85361F6C2E57F685D5DFFB16DC263D51BE577AFAB81D69B6385A2C2B5DA2FEE8

Dynamic reproduction

Docker Desktop or Docker Engine is required. The script downloads the released MLeap 0.25.1 dependency graph into a disposable container, compiles the included harness, then performs:

  1. BundleFile.loadMleapBundle() for the malicious .mleap archive.
  2. A successful transform of control_pca.mleap, printing OUTPUT_LENGTH=1 and OUTPUT_PREFIX=2.0.
  3. A transform of malicious_pca_shape_overflow.mleap.

Run:

bash build_and_verify.sh

From Windows PowerShell, run the equivalent command from this directory:

docker run --rm --name mleap-pca-shape-overflow-poc -v "$PWD:/poc:rw" -w /poc sbtscala/scala-sbt:eclipse-temurin-17.0.15_6_1.10.11_2.13.16 bash /poc/run_in_docker.sh

Expected malicious result on Linux x86_64 with libblas3:

LOADED=/poc/malicious_pca_shape_overflow.mleap
SIGSEGV in libblas.so.3 dgemv_

The JVM writes an hs_err_pid log in the PoC directory. The observed native chain is dgemv_ -> JNIBLAS -> Spark BLAS/Matrix.multiply -> PcaModel.apply.

Root cause

Bundle tensor deserialization calls TensorSerializer.fromProto(), which passes the attacker-controlled shape and array into Tensor.create(). Tensor.normalizeDimensions() compares normalizedDimensions.product with the array size using signed Int arithmetic. For 8192 by 524289, the product wraps to 8192 and validation succeeds.

PcaOp.load() then constructs a DenseMatrix from the untrusted dimensions and array. PcaModel.apply() calls transpose.multiply() during ordinary PCA inference. Spark's matrix validation and the native BLAS bridge likewise operate on the wrapped logical dimensions, causing the native dgemv operation to use the oversized logical matrix against the short backing array.

Recommended fix

Validate all tensor dimensions as positive bounded values and compute their product with checked 64-bit arithmetic before converting to Int. Reject tensors when the exact product does not equal the decoded value count, before PcaOp constructs a DenseMatrix. Spark-side matrix constructors and BLAS wrappers should likewise reject overflowed dimensions instead of relying on signed Int products.

Downloads last month

-

Downloads are not tracked for this model. How to track
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support