Follow-up from #814 by @shubhamsinnh -- thanks again for that PR!
What
#814 added an exact-size check (width*height*channels == data_size) for VLM images that arrive through the protobuf adapter (core/src/foundation/rac_proto_adapters.cpp). The direct C-struct entry points never got the same check: rac_vlm_component_process (core/src/features/vlm/vlm_module.cpp:434) and rac_vlm_process (core/src/features/vlm/rac_vlm_service.cpp:144) only null-check the image before dispatching, and the llama.cpp backend calls mtmd_bitmap_init(image->width, image->height, image->pixel_data) at engines/llamacpp/rac_vlm_llamacpp.cpp:781-783 without ever consulting data_size.
Why it matters
A native caller that builds a rac_vlm_image_t directly (bypassing the proto path) with a short pixel_data buffer still triggers the same heap over-read #814 just closed for the proto path.
Suggested approach
In rac_vlm_process and rac_vlm_process_stream, reject RGB_PIXELS images unless width and height are positive, pixel_data is non-null, and data_size equals the overflow-checked width*height*3 -- reusing (or duplicating) the checked_raw_image_size logic from rac_proto_adapters.cpp.
Done when
Not blocking #814. @shubhamsinnh, you know this code well now -- you're welcome to take this one if you're interested.
Opened with help from Claude Code and Codex.
Reviewed with help from Claude Code and Codex.
Follow-up from #814 by @shubhamsinnh -- thanks again for that PR!
What
#814 added an exact-size check (
width*height*channels == data_size) for VLM images that arrive through the protobuf adapter (core/src/foundation/rac_proto_adapters.cpp). The direct C-struct entry points never got the same check:rac_vlm_component_process(core/src/features/vlm/vlm_module.cpp:434) andrac_vlm_process(core/src/features/vlm/rac_vlm_service.cpp:144) only null-check the image before dispatching, and the llama.cpp backend callsmtmd_bitmap_init(image->width, image->height, image->pixel_data)at engines/llamacpp/rac_vlm_llamacpp.cpp:781-783 without ever consultingdata_size.Why it matters
A native caller that builds a
rac_vlm_image_tdirectly (bypassing the proto path) with a shortpixel_databuffer still triggers the same heap over-read #814 just closed for the proto path.Suggested approach
In
rac_vlm_processandrac_vlm_process_stream, rejectRGB_PIXELSimages unless width and height are positive,pixel_datais non-null, anddata_sizeequals the overflow-checkedwidth*height*3-- reusing (or duplicating) thechecked_raw_image_sizelogic fromrac_proto_adapters.cpp.Done when
rac_vlm_processrejects aRGB_PIXELSimage whosedata_sizedoesn't matchwidth*height*3.rac_vlm_image_twith a short buffer.Not blocking #814. @shubhamsinnh, you know this code well now -- you're welcome to take this one if you're interested.
Opened with help from Claude Code and Codex.
Reviewed with help from Claude Code and Codex.