#1444·magika

Possible memory leak: model path C.CString is never freed in NewOnnx

Author: OvOhaoCreated Sep 7, 2026Updated Sep 11, 2026

Possible memory leak: model path C.CString is never freed in NewOnnx

NewOnnx passes the model path to CreateSession as an inline C.CString. The allocation is not bound to a variable, so there is no name available to free it afterwards.

go/onnx/onnx_runtime.go:21

go
	if err := C.CreateSession(ort.api, C.CString(modelPath), &ort.session, &ort.memory); err != nil {
		return nil, fmt.Errorf("create session: %v", C.GoString(C.GetErrorMessage(err)))
	}

go/onnx/onnx_runtime.h:15

c
OrtStatus *CreateSession(const OrtApi *ort, const char *model, OrtSession **session, OrtMemoryInfo **memory_info) {
	...
	RETURN_ON_ERROR(ort->CreateSession(env, model, options, session));

model is taken as const char * and handed to OrtApi::CreateSession, which copies the path. Nothing takes ownership of the buffer, and CreateSession does not free it, so the string leaks on every call, on both the success and the error path.

Fix:

go
	cPath := C.CString(modelPath)
	defer C.free(unsafe.Pointer(cPath))
	if err := C.CreateSession(ort.api, cPath, &ort.session, &ort.memory); err != nil {

with #include <stdlib.h> in the preamble.

Separately, RETURN_ON_ERROR in CreateSession returns before releasing env and options, and the OrtStatus returned to Go is never passed to ReleaseStatus.

If you could credit me as a reporter for my contributions to security advisory I will be thankful.