From e8cade558784ae8a7bf92ab0273f32f2aff2b93f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Bl=C3=A4sing?= Date: Sun, 21 Apr 2024 09:59:35 +0200 Subject: [PATCH] Ensure callback,method_data and thread_storage are initialized to zero malloc does not clear the memory it allocates and thus random data can be present. It was observed, that cleanup routines assume, that fields not holding NULL need to be freed for example. That is not true if the field was not cleared on allocation. One such example was callback->arg_classes in free_callback. --- native/callback.c | 23 ++++++++++++++++------- native/dispatch.c | 10 +++++----- 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/native/callback.c b/native/callback.c index 464703ad7e..7872693315 100644 --- a/native/callback.c +++ b/native/callback.c @@ -133,19 +133,19 @@ create_callback(JNIEnv* env, jobject obj, jobject method, } argc = (*env)->GetArrayLength(env, arg_classes); - cb = (callback *)malloc(sizeof(callback)); + cb = (callback *)calloc(1, sizeof(callback)); cb->closure = ffi_closure_alloc(sizeof(ffi_closure), &cb->x_closure); cb->saved_x_closure = cb->x_closure; cb->object = (*env)->NewWeakGlobalRef(env, obj); cb->methodID = (*env)->FromReflectedMethod(env, method); cb->vm = vm; - cb->arg_types = (ffi_type**)malloc(sizeof(ffi_type*) * argc); - cb->java_arg_types = (ffi_type**)malloc(sizeof(ffi_type*) * (argc + 3)); - cb->arg_jtypes = (char*)malloc(sizeof(char) * argc); - cb->conversion_flags = (int *)malloc(sizeof(int) * argc); + cb->arg_types = (ffi_type**)calloc(argc, sizeof(ffi_type*)); + cb->java_arg_types = (ffi_type**)calloc(argc + 3, sizeof(ffi_type*)); + cb->arg_jtypes = (char*)calloc(argc, sizeof(char)); + cb->conversion_flags = (int *)calloc(argc, sizeof(int)); cb->rflag = CVT_DEFAULT; - cb->arg_classes = (jobject*)malloc(sizeof(jobject) * argc); + cb->arg_classes = (jobject*)calloc(argc, sizeof(jobject)); cb->direct = direct; cb->java_arg_types[0] = cb->java_arg_types[1] = cb->java_arg_types[2] = &ffi_type_pointer; @@ -163,6 +163,9 @@ create_callback(JNIEnv* env, jobject obj, jobject method, } jtype = get_java_type(env, cls); + if((*env)->ExceptionCheck(env)) { + goto failure_cleanup; + } if (jtype == -1) { snprintf(msg, sizeof(msg), "Unsupported callback argument at index %d", i); throw_type = EIllegalArgument; @@ -179,7 +182,13 @@ create_callback(JNIEnv* env, jobject obj, jobject method, || cb->conversion_flags[i] == CVT_INTEGER_TYPE) { jclass ncls; ncls = getNativeType(env, cls); + if((*env)->ExceptionCheck(env)) { + goto failure_cleanup; + } jtype = get_java_type(env, ncls); + if((*env)->ExceptionCheck(env)) { + goto failure_cleanup; + } if (jtype == -1) { snprintf(msg, sizeof(msg), "Unsupported NativeMapped callback argument native type at argument %d", i); throw_type = EIllegalArgument; @@ -560,7 +569,7 @@ static TLS_KEY_T tls_thread_data_key; static thread_storage* get_thread_storage(JNIEnv* env) { thread_storage* tls = (thread_storage *)TLS_GET(tls_thread_data_key); if (tls == NULL) { - tls = (thread_storage*)malloc(sizeof(thread_storage)); + tls = (thread_storage*)calloc(1, sizeof(thread_storage)); if (!tls) { throwByName(env, EOutOfMemory, "JNA: Can't allocate thread storage"); } diff --git a/native/dispatch.c b/native/dispatch.c index 9a87d4841e..8a03a643b9 100644 --- a/native/dispatch.c +++ b/native/dispatch.c @@ -3497,7 +3497,7 @@ Java_com_sun_jna_Native_registerMethod(JNIEnv *env, jclass UNUSED(ncls), const char* sig = newCStringUTF8(env, signature); void *code; void *closure; - method_data* data = malloc(sizeof(method_data)); + method_data* data = calloc(1, sizeof(method_data)); ffi_cif* closure_cif = &data->closure_cif; int status; int i; @@ -3519,12 +3519,12 @@ Java_com_sun_jna_Native_registerMethod(JNIEnv *env, jclass UNUSED(ncls), } data->throw_last_error = throw_last_error; - data->arg_types = malloc(sizeof(ffi_type*) * argc); - data->closure_arg_types = malloc(sizeof(ffi_type*) * (argc + 2)); + data->arg_types = calloc(argc, sizeof(ffi_type*)); + data->closure_arg_types = calloc(argc + 2, sizeof(ffi_type*)); data->closure_arg_types[0] = &ffi_type_pointer; data->closure_arg_types[1] = &ffi_type_pointer; data->closure_method = NULL; - data->flags = cvts ? malloc(sizeof(jint)*argc) : NULL; + data->flags = cvts ? calloc(argc, sizeof(jint)) : NULL; data->rflag = rconversion; data->to_native = NULL; data->from_native = from_native ? (*env)->NewWeakGlobalRef(env, from_native) : NULL; @@ -3612,7 +3612,7 @@ Java_com_sun_jna_Native_ffi_1prep_1cif(JNIEnv *env, jclass UNUSED(cls), jint abi JNIEXPORT jlong JNICALL Java_com_sun_jna_Native_ffi_1prep_1closure(JNIEnv *env, jclass UNUSED(cls), jlong cif, jobject obj) { - callback* cb = (callback *)malloc(sizeof(callback)); + callback* cb = (callback *)calloc(1, sizeof(callback)); ffi_status s; if ((*env)->GetJavaVM(env, &cb->vm) != JNI_OK) {