From 342eb2f25a58a790359f1b19b57525d5e44c0a9f Mon Sep 17 00:00:00 2001 From: Chris Conlon Date: Wed, 30 Apr 2025 14:20:31 -0600 Subject: [PATCH] JNI: add additional error checks to JNI WolfSSLSession.read(ByteBuffer) function --- native/com_wolfssl_WolfSSLSession.c | 68 +++++++++++++++++++---------- 1 file changed, 45 insertions(+), 23 deletions(-) diff --git a/native/com_wolfssl_WolfSSLSession.c b/native/com_wolfssl_WolfSSLSession.c index fe4a81f..b7c3019 100644 --- a/native/com_wolfssl_WolfSSLSession.c +++ b/native/com_wolfssl_WolfSSLSession.c @@ -1384,13 +1384,15 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_read__JLjava_nio_ByteBuff if (length > 0) { /* Get ByteBuffer position */ position = (*jenv)->CallIntMethod(jenv, buf, g_bufferPositionMethodId); + if ((*jenv)->ExceptionCheck(jenv)) { + return SSL_FAILURE; + } /* Get ByteBuffer limit */ limit = (*jenv)->CallIntMethod(jenv, buf, g_bufferLimitMethodId); - - /* Get and call ByteBuffer.hasArray() before calling array() */ - hasArray = (*jenv)->CallBooleanMethod(jenv, buf, - g_bufferHasArrayMethodId); + if ((*jenv)->ExceptionCheck(jenv)) { + return SSL_FAILURE; + } /* Only read up to maximum space we have in this ByteBuffer */ maxOutputSz = (limit - position); @@ -1398,10 +1400,24 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_read__JLjava_nio_ByteBuff outSz = maxOutputSz; } + if (outSz <= 0) { + return BAD_FUNC_ARG; + } + + /* Get and call ByteBuffer.hasArray() before calling array() */ + hasArray = (*jenv)->CallBooleanMethod(jenv, buf, + g_bufferHasArrayMethodId); + if ((*jenv)->ExceptionCheck(jenv)) { + return SSL_FAILURE; + } + if (hasArray) { /* Get reference to underlying byte[] from ByteBuffer */ bufArr = (jbyteArray)(*jenv)->CallObjectMethod(jenv, buf, g_bufferArrayMethodId); + if ((*jenv)->ExceptionCheck(jenv)) { + return SSL_FAILURE; + } /* Get array elements */ data = (byte *)(*jenv)->GetByteArrayElements(jenv, bufArr, NULL); @@ -1412,6 +1428,12 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_read__JLjava_nio_ByteBuff "Exception when calling ByteBuffer.array() in native read()"); return -1; } + + if (data == NULL) { + throwWolfSSLJNIException(jenv, + "Failed to get byte[] from ByteBuffer in native read()"); + return BAD_FUNC_ARG; + } } else { data = (byte *)(*jenv)->GetDirectBufferAddress(jenv, buf); @@ -1422,28 +1444,28 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_read__JLjava_nio_ByteBuff } } - if (data != NULL) { - size = SSLReadNonblockingWithSelectPoll(ssl, data + position, - maxOutputSz, (int)timeout); + size = SSLReadNonblockingWithSelectPoll(ssl, data + position, + maxOutputSz, (int)timeout); - /* Relase array elements */ - if (hasArray) { - if (size < 0) { - (*jenv)->ReleaseByteArrayElements(jenv, bufArr, - (jbyte *)data, JNI_ABORT); - } - else { - (*jenv)->ReleaseByteArrayElements(jenv, bufArr, - (jbyte *)data, 0); - } + /* Release array elements if using array-backed buffer. + * Note: DirectByteBuffer doesn't need releasing data */ + if (hasArray) { + if (size < 0) { + (*jenv)->ReleaseByteArrayElements(jenv, bufArr, + (jbyte *)data, JNI_ABORT); } + else { + (*jenv)->ReleaseByteArrayElements(jenv, bufArr, + (jbyte *)data, 0); + } + } - /* Note: DirectByteBuffer doesn't need releasing data */ - - if (size > 0) { - /* Update ByteBuffer position() based on bytes written */ - (*jenv)->CallVoidMethod(jenv, buf, g_bufferSetPositionMethodId, - position + size); + /* Update ByteBuffer position() based on bytes written, on success */ + if (size > 0) { + (*jenv)->CallVoidMethod(jenv, buf, g_bufferSetPositionMethodId, + position + size); + if ((*jenv)->ExceptionCheck(jenv)) { + return SSL_FAILURE; } } }