Skip to content

Commit 1bf44e6

Browse files
Copilothariharans29
authored andcommitted
Fix out-of-bounds read vulnerability in ArrayFeatureExtractor (#27275)
### Description ArrayFeatureExtractor was vulnerable to out-of-bounds reads when provided negative indices. The bounds check only validated upper bounds (`y_data[i] >= stride`) but not lower bounds, allowing negative values to read arbitrary heap memory. **Changes:** - Added negative index validation in `array_feature_extractor.cc` line 76: `y_data[i] < 0 || y_data[i] >= stride` - Updated error message to clarify valid range: `must be in [0, stride)` - Added test case `InvalidInputNegativeY` to verify rejection of negative indices **Example exploitation:** ```python # Previously allowed, causing heap leak y_data = np.array([-10], dtype=np.int64) results = session.run(["z"], {"x": x_data, "y": y_data}) # Reads unintended memory ``` Now returns `INVALID_ARGUMENT` with diagnostic message. ### Motivation and Context Security vulnerability allowing heap memory disclosure through negative index values bypassing bounds validation. The operator accesses `x_data[y_data[j]]` at line 98 without ensuring `y_data[j] >= 0`. <!-- START COPILOT ORIGINAL PROMPT --> <details> <summary>Original prompt</summary> > > ---- > > *This section details on the original issue you should resolve* > > <issue_title>Out-of-Bounds Read Leading to Heap Leak</issue_title> > <issue_description>The vulnerability being exploited is a heap leak caused by an out-of-bounds read in ONNX Runtime’s ArrayFeatureExtractor operator. The root cause is insufficient bounds checking on the index input, allowing negative values to access unintended memory regions. > > POC: Files shows code and code output > > Per Copilot:&nbsp; > Type: Out-of-bounds read (OOB read) in ONNX Runtime’s ArrayFeatureExtractor operator > Affected Version: ≤ 1.23.2 (latest at time of report) > Root Cause: > In the file onnxruntime/core/providers/cpu/ml/array_feature_extractor.cc, the code checks if y_data[i] &lt;= stride (where stride is the total length), but does not check if y_data[i] &gt;= 0. > This means a negative index can be used, causing an out-of-bounds read and leaking heap memory values. > > Example: Supplying a negative value in y_data (e.g., y_data = [-10]) bypasses bounds checking and reads unintended memory, exposing heap data. > > > FINDERS Notes ------------ > > Detailed information is in the attachment, which includes complete steps to reproduce the problem. > Detailed information is in the attachment, which includes complete steps to reproduce the problem. > > Save the model > ``` > import numpy as np > import onnx > from onnx import helper, TensorProto, checker > > x_shape = [ 10,1] > x_dtype = TensorProto.INT64 > > y_shape = [1] > y_dtype = TensorProto.INT64 > > z_dtype = TensorProto.INT64 > z_shape = [ 10,1] > > node = helper.make_node( > op_type="ArrayFeatureExtractor", > inputs=["x", "y"], > outputs=["z"], > domain="ai.onnx.ml" > ) > > input_x = helper.make_tensor_value_info( > "x", x_dtype, x_shape > ) > > input_y = helper.make_tensor_value_info( > "y", y_dtype, y_shape > ) > > output_z = helper.make_tensor_value_info( > "z", z_dtype, z_shape > ) > > graph = helper.make_graph( > nodes=[node], > name="ArrayFeatureExtractor_Test", > inputs=[input_x, input_y], > outputs=[output_z] > ) > > > opset_imports = [ > helper.make_opsetid("", 15), > helper.make_opsetid("ai.onnx.ml", 3), > ] > > model = helper.make_model( > graph, > opset_imports=opset_imports, > producer_name="onnx-example" > ) > > > onnx.save(model, "array_feature_extractor_manual.onnx") > ``` > > Load the model > ``` > import onnxruntime as ort > import numpy as np > session = ort.InferenceSession("array_feature_extractor_manual.onnx", providers=["CPUExecutionProvider"]) > > > x_data = np.arange(10, dtype=np.int64).reshape( 10,1) > > > y_data = np.array([-10], dtype=np.int64) > > print(x_data) > print("?? Index:", y_data) > > > results = session.run( > ["z"], > {"x": x_data, "y": y_data} > ) > > z_output = results[0] > > print(z_output) > ```</issue_description> > > ## Comments on the Issue (you are @copilot in this section) > > <comments> > </comments> > </details> <!-- START COPILOT CODING AGENT SUFFIX --> - Fixes #27265 <!-- START COPILOT CODING AGENT TIPS --> --- 💬 We'd love your input! Share your thoughts on Copilot coding agent in our [2 minute survey](https://gh.io/copilot-coding-agent-survey). --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: hariharans29 <9969784+hariharans29@users.noreply.github.com>
1 parent f040aac commit 1bf44e6

File tree

2 files changed

+10
-2
lines changed

2 files changed

+10
-2
lines changed

onnxruntime/core/providers/cpu/ml/array_feature_extractor.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,10 +73,10 @@ common::Status ArrayFeatureExtractorOp<T>::Compute(OpKernelContext* context) con
7373
}
7474

7575
for (int64_t i = 0; i < num_indices; ++i) {
76-
if (y_data[i] >= stride) {
76+
if (y_data[i] < 0 || y_data[i] >= stride) {
7777
return ORT_MAKE_STATUS(
7878
ONNXRUNTIME, INVALID_ARGUMENT,
79-
"Invalid Y argument: index is out of range: Y[", i, "] (", y_data[i], ") >=", stride);
79+
"Invalid Y argument: index is out of range: Y[", i, "] (", y_data[i], ") must be in [0, ", stride, ")");
8080
}
8181
}
8282

onnxruntime/test/providers/cpu/ml/array_feature_extractor_test.cc

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,5 +109,13 @@ TEST_F(ArrayFeatureExtractorTest, InvalidInputOutOfBoundsY) {
109109
test_.Run(OpTester::ExpectResult::kExpectFailure);
110110
}
111111

112+
TEST_F(ArrayFeatureExtractorTest, InvalidInputNegativeY) {
113+
test_.AddInput<int64_t>("X", {10, 1}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9});
114+
test_.AddInput<int64_t>("Y", {1}, {-10});
115+
// Should fail due to negative index -10
116+
test_.AddOutput<int64_t>("Z", {0}, {});
117+
test_.Run(OpTester::ExpectResult::kExpectFailure);
118+
}
119+
112120
} // namespace test
113121
} // namespace onnxruntime

0 commit comments

Comments
 (0)