Skip to content

JNI global references leak when native method registration fails #1738

Description

@QiuYucheng2003

Summary

Java_com_sun_jna_Native_registerMethod creates persistent JNI references before several fallible FFI initialization steps.

Affected code:

jna/native/dispatch.c

Lines 3553 to 3587 in d036ad9

data->closure_method = (*env)->NewGlobalRef(env, closure_method);
status = ffi_prep_cif(closure_cif, abi, argc+2, closure_rtype, data->closure_arg_types);
if (ffi_error(env, "Native method mapping", status)) {
goto cleanup;
}
status = ffi_prep_cif(&data->cif, abi, argc, rtype, data->arg_types);
if (ffi_error(env, "Native method setup", status)) {
goto cleanup;
}
closure = ffi_closure_alloc(sizeof(ffi_closure), &code);
if (closure == NULL) {
throwByName(env, EUnsupportedOperation, "Failed to allocate closure");
status = FFI_BAD_ABI;
goto cleanup;
}
status = ffi_prep_closure_loc(closure, closure_cif, dispatch_direct, data, code);
if (status != FFI_OK) {
throwByName(env, EError, "Native method linkage failed");
goto cleanup;
}
{
JNINativeMethod m = { (char*)cname, (char*)sig, code };
(*env)->RegisterNatives(env, cls, &m, 1);
}
cleanup:
if (status != FFI_OK) {
free(data->arg_types);
free(data->flags);
free(data);
data = NULL;

If ffi_prep_cif, ffi_closure_alloc, or ffi_prep_closure_loc fails, execution jumps to cleanup. That path frees data without calling DeleteGlobalRef for data->closure_method.

Because registration did not complete, Native_unregister cannot release this reference later.

Impact

Each failed registration permanently retains the reflected Java Method and potentially its class-loader object graph until JVM shutdown. Repeated failures may cause persistent memory growth.

The same cleanup path also omits some related resources, including weak global references, closure_arg_types, encoding, and an allocated FFI closure.

Suggested fix

Before freeing data on failure:

  • Delete closure_method with DeleteGlobalRef.
  • Delete any from_native and to_native weak global references.
  • Free all allocated arrays, encoding data, and FFI closure memory.

Successful registrations should continue to transfer ownership to Native_unregister.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions