From 044378b6c2de118a4128f9a6938da0bc3349901e Mon Sep 17 00:00:00 2001 From: Sang Woo Kim Date: Fri, 17 Jul 2026 00:36:30 +0900 Subject: [PATCH] NDPluginROIStat: return after rank-guard to prevent heap OOB on 3-D arrays The "number of array dimensions must be 1 or 2" guard in processCallbacks() only printed a warning and fell through to the geometry loop: for (dim=0; dimndims; dim++) { pROI->offset[dim] = ...; pROI->size[dim] = ...; pROI->arraySize[dim] = ...; } NDROI_t sizes offset[], size[] and arraySize[] to two elements each, so for any array with ndims == 3 -- which includes every NDColorModeRGB1/2/3 frame -- dim reaches 2 and the loop writes index 2 of each 2-element array. arraySize is the struct's last member, so arraySize[2] is written 8 bytes past the NDROI object, and for the last ROI past the new NDROI[maxROIs_] allocation: a heap out-of-bounds write reachable from an ordinary colour-detector configuration, with corrupted stats and a likely crash in the delete[] that follows. Bail out of processCallbacks() (releasing the pROIs allocation and leaving the mutex locked, as the exit contract requires) instead of merely warning, matching the identical guard in NDPluginTimeSeries which already returns. Verified with an AddressSanitizer proof driver mirroring the NDROI_t layout and the dim loop: a 3-D array triggers a heap-buffer-overflow WRITE of size 8 without the return, and returns cleanly with it. --- ADApp/pluginSrc/NDPluginROIStat.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/ADApp/pluginSrc/NDPluginROIStat.cpp b/ADApp/pluginSrc/NDPluginROIStat.cpp index 15cfef20f..701a7952c 100644 --- a/ADApp/pluginSrc/NDPluginROIStat.cpp +++ b/ADApp/pluginSrc/NDPluginROIStat.cpp @@ -212,11 +212,16 @@ void NDPluginROIStat::processCallbacks(NDArray *pArray) /* Call the base class method */ NDPluginDriver::beginProcessCallbacks(pArray); - // This plugin only works with 1-D or 2-D arrays + // This plugin only works with 1-D or 2-D arrays. NDROI_t sizes offset[], + // size[] and arraySize[] to 2 elements, so a higher-rank array (e.g. any + // RGB1/2/3 colour frame, ndims==3) would drive the dim loop below past the + // end of those arrays. Bail out here instead of merely warning. if ((pArray->ndims < 1) || (pArray->ndims > 2)) { asynPrint(pasynUserSelf, ASYN_TRACE_ERROR, "%s: error, number of array dimensions must be 1 or 2\n", functionName); + delete[] pROIs; + return; } //Set NDArraySize params to the input pArray, because this plugin doesn't change them