Skip to content

Commit 64edccd

Browse files
authored
Delete local references to Java-returned result arrays in JNI callbacks (#1016)
Motivation: resultArray in cert_compress.c compress()/decompress() and resultBytes in the SSL_PRIVATE_KEY_METHOD callbacks in sslcontext.c are obtained from CallObjectMethod/GetObjectField but were never deleted on any exit path. These are invoked repeatedly as native callbacks from OpenSSL/BoringSSL (once per certificate needing (de)compression, or per sign/decrypt/complete call), so the leaked local references accumulate and can exhaust the JNI local reference table. Modifications: - cert_compress.c: delete resultArray before every return in compress() and decompress() once it has been obtained. - sslcontext.c: delete resultBytes at the complete: label in tcn_private_key_sign_java and tcn_private_key_decrypt_java, and before every return in tcn_private_key_complete_java. Result: No longer leak local references to compression/private-key callback result arrays.
1 parent bdbc9d9 commit 64edccd

2 files changed

Lines changed: 13 additions & 0 deletions

File tree

‎openssl-dynamic/src/main/c/cert_compress.c‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,14 +53,17 @@ static int compress(jobject compression_algorithm, jmethodID compress_method, SS
5353
int resultLen = (*e)->GetArrayLength(e, resultArray);
5454
uint8_t* outData = NULL;
5555
if (!CBB_reserve(out, &outData, resultLen)) {
56+
NETTY_JNI_UTIL_DELETE_LOCAL(e, resultArray);
5657
return 0; // Unable to reserve space for compressed data
5758
}
5859
jbyte* resultData = (*e)->GetByteArrayElements(e, resultArray, NULL);
5960
if (resultData == NULL) {
61+
NETTY_JNI_UTIL_DELETE_LOCAL(e, resultArray);
6062
return 0;
6163
}
6264
memcpy(outData, resultData, resultLen);
6365
(*e)->ReleaseByteArrayElements(e, resultArray, resultData, JNI_ABORT);
66+
NETTY_JNI_UTIL_DELETE_LOCAL(e, resultArray);
6467
if (!CBB_did_write(out, resultLen)) {
6568
return 0; // Unable to advance bytes written to CBB
6669
}
@@ -102,20 +105,24 @@ static int decompress(jobject compression_algorithm, jmethodID decompress_method
102105

103106
int resultLen = (*e)->GetArrayLength(e, resultArray);
104107
if (uncompressed_len != resultLen) {
108+
NETTY_JNI_UTIL_DELETE_LOCAL(e, resultArray);
105109
return 0; // Unexpected uncompressed length
106110
}
107111
jbyte* resultData = (*e)->GetByteArrayElements(e, resultArray, NULL);
108112
if (resultData == NULL) {
113+
NETTY_JNI_UTIL_DELETE_LOCAL(e, resultArray);
109114
return 0;
110115
}
111116
uint8_t* outData;
112117
if (!((*out) = CRYPTO_BUFFER_alloc(&outData, uncompressed_len))) {
113118
// Unable to allocate certificate decompression buffer
114119
(*e)->ReleaseByteArrayElements(e, resultArray, resultData, JNI_ABORT);
120+
NETTY_JNI_UTIL_DELETE_LOCAL(e, resultArray);
115121
return 0;
116122
}
117123
memcpy(outData, resultData, uncompressed_len);
118124
(*e)->ReleaseByteArrayElements(e, resultArray, resultData, JNI_ABORT);
125+
NETTY_JNI_UTIL_DELETE_LOCAL(e, resultArray);
119126
return 1; // Success
120127
}
121128

‎openssl-dynamic/src/main/c/sslcontext.c‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2281,6 +2281,7 @@ static enum ssl_private_key_result_t tcn_private_key_sign_java(SSL *ssl, uint8_t
22812281
complete:
22822282
// Free up any allocated memory and return.
22832283
NETTY_JNI_UTIL_DELETE_LOCAL(e, inputArray);
2284+
NETTY_JNI_UTIL_DELETE_LOCAL(e, resultBytes);
22842285
NETTY_JNI_UTIL_DELETE_LOCAL(e, sslPrivateKeyMethodSignTask_class);
22852286

22862287
return ret;
@@ -2350,6 +2351,7 @@ static enum ssl_private_key_result_t tcn_private_key_decrypt_java(SSL *ssl, uint
23502351
complete:
23512352
// Delete the local reference as this is executed by a callback.
23522353
NETTY_JNI_UTIL_DELETE_LOCAL(e, inArray);
2354+
NETTY_JNI_UTIL_DELETE_LOCAL(e, resultBytes);
23532355
NETTY_JNI_UTIL_DELETE_LOCAL(e, sslPrivateKeyMethodDecryptTask_class);
23542356
return ret;
23552357
}
@@ -2388,21 +2390,25 @@ static enum ssl_private_key_result_t tcn_private_key_complete_java(SSL *ssl, uin
23882390
state->ssl_task = NULL;
23892391

23902392
if (returnValue != 1 || resultBytes == NULL) {
2393+
NETTY_JNI_UTIL_DELETE_LOCAL(e, resultBytes);
23912394
return ssl_private_key_failure;
23922395
}
23932396

23942397
arrayLen = (*e)->GetArrayLength(e, resultBytes);
23952398
if (max_out < arrayLen) {
23962399
// We need to fail as otherwise we would end up writing into memory which does not
23972400
// belong to us.
2401+
NETTY_JNI_UTIL_DELETE_LOCAL(e, resultBytes);
23982402
return ssl_private_key_failure;
23992403
}
24002404
if ((b = (*e)->GetByteArrayElements(e, resultBytes, NULL)) == NULL) {
2405+
NETTY_JNI_UTIL_DELETE_LOCAL(e, resultBytes);
24012406
return ssl_private_key_failure;
24022407
}
24032408
memcpy(out, b, arrayLen);
24042409
(*e)->ReleaseByteArrayElements(e, resultBytes, b, JNI_ABORT);
24052410
*out_len = arrayLen;
2411+
NETTY_JNI_UTIL_DELETE_LOCAL(e, resultBytes);
24062412
return ssl_private_key_success;
24072413
}
24082414
return ssl_private_key_failure;

0 commit comments

Comments
 (0)