@@ -333,6 +333,67 @@ BOOL TalkToSvc_Inference(std::string model_name, std::string proc_name, std::str
333333 return false ;
334334 }
335335
336+
337+ // Early validation to avoid VectorToShareMem memcpy crash.
338+ if (inputBuffers.size () != inputSize.size ()) {
339+ QNN_ERR (" TalkToSvc_Inference: inputBuffers/inputSize length mismatch. buffers=%zu size=%zu\n " , inputBuffers.size (), inputSize.size ());
340+ return false ;
341+ }
342+ if (!pShareMemInfo->lpBase || pShareMemInfo->size == 0 ) {
343+ QNN_ERR (" TalkToSvc_Inference: invalid share memory base or size. name=%s lpBase=%p size=%llu\n " , share_memory_name.c_str (), pShareMemInfo->lpBase , (unsigned long long )pShareMemInfo->size );
344+ return false ;
345+ }
346+
347+ // Compute required size according to VectorToShareMem's offset strategy: reserve sizes of in-share buffers + sizes of out-of-share buffers.
348+ {
349+ uint8_t * base = (uint8_t *)pShareMemInfo->lpBase ;
350+ uint8_t * end = base + pShareMemInfo->size ;
351+ size_t reserved = 0 ;
352+ size_t toCopy = 0 ;
353+
354+ for (size_t i = 0 ; i < inputBuffers.size (); ++i) {
355+ uint8_t * buf = inputBuffers[i];
356+ size_t sz = inputSize[i];
357+
358+ if (!buf && sz > 0 ) {
359+ QNN_ERR (" TalkToSvc_Inference: null input buffer at index %zu with non-zero size %llu\n " , i, (unsigned long long )sz);
360+ return false ;
361+ }
362+
363+ // In-share: [base, end)
364+ if (buf >= base && buf < end) {
365+ if (sz > 0 && ((size_t )(end - buf) < sz)) {
366+ QNN_ERR (" TalkToSvc_Inference: in-share input buffer out of bounds. idx=%zu buf=%p size=%llu share=[%p,%p)\n " , i, buf, (unsigned long long )sz, base, end);
367+ return false ;
368+ }
369+ if (std::numeric_limits<size_t >::max () - reserved < sz) {
370+ QNN_ERR (" TalkToSvc_Inference: size_t overflow while accumulating reserved. idx=%zu\n " , i);
371+ return false ;
372+ }
373+ reserved += sz;
374+ } else {
375+ if (std::numeric_limits<size_t >::max () - toCopy < sz) {
376+ QNN_ERR (" TalkToSvc_Inference: size_t overflow while accumulating toCopy. idx=%zu\n " , i);
377+ return false ;
378+ }
379+ toCopy += sz;
380+ }
381+ }
382+
383+ if (std::numeric_limits<size_t >::max () - reserved < toCopy) {
384+ QNN_ERR (" TalkToSvc_Inference: size_t overflow while computing totalNeeded.\n " );
385+ return false ;
386+ }
387+
388+ size_t totalNeeded = reserved + toCopy;
389+ if (totalNeeded > pShareMemInfo->size ) {
390+ QNN_ERR (" TalkToSvc_Inference: share memory too small. required=%llu (reserved=%llu copy=%llu) share_size=%llu name=%s\n " ,
391+ (unsigned long long )totalNeeded, (unsigned long long )reserved, (unsigned long long )toCopy, (unsigned long long )pShareMemInfo->size , share_memory_name.c_str ());
392+ return false ;
393+ }
394+ }
395+
396+
336397 HANDLE hSvcPipeInWrite = pProcInfo->hSvcPipeInWrite ;
337398 HANDLE hSvcPipeOutRead = pProcInfo->hSvcPipeOutRead ;
338399 DWORD dwRead = 0 , dwWrite = 0 ;
0 commit comments