Created attachment 38265 [details] hs_err_pid Hello, we are switching from APR+OpenSSL to NIO(2)+OpenSSL connector configuration and we are facing SIGSEGV error. Tested multiple Java+tomcat-native+OpenSSL combinations, nothing helped. Tested also with Oracle JDK 11.0.15, openssl 1.1.1n, latest tomcat-native.... fyi. Our APR+OpenSSL configuration is rock solid. Best Regards Michal Josifek # # A fatal error has been detected by the Java Runtime Environment: # # SIGSEGV (0xb) at pc=0x00007f13f860fbe5, pid=36351, tid=36401 # # JRE version: OpenJDK Runtime Environment Corretto-11.0.14.9.1 (11.0.14+9) (build 11.0.14+9-LTS) # Java VM: OpenJDK 64-Bit Server VM Corretto-11.0.14.9.1 (11.0.14+9-LTS, mixed mode, tiered, compressed oops, g1 gc, linux-amd64) # Problematic frame: # C [libssl.so.1.0.0+0x49be5] SSL_SESSION_get_id+0x5 # # Core dump will be written. Default location: //core.36351 # # An error report file with more information is saved as: # /tmp/hs_err_pid36351.log Compiled method (nm) 2514776 22100 n 0 org.apache.tomcat.jni.SSL::getSessionId (native) total in heap [0x00007f143d67ef10,0x00007f143d67f350] = 1088 relocation [0x00007f143d67f088,0x00007f143d67f0c0] = 56 main code [0x00007f143d67f0c0,0x00007f143d67f348] = 648 oops [0x00007f143d67f348,0x00007f143d67f350] = 8 Compiled method (nm) 2514781 22100 n 0 org.apache.tomcat.jni.SSL::getSessionId (native) total in heap [0x00007f143d67ef10,0x00007f143d67f350] = 1088 relocation [0x00007f143d67f088,0x00007f143d67f0c0] = 56 main code [0x00007f143d67f0c0,0x00007f143d67f348] = 648 oops [0x00007f143d67f348,0x00007f143d67f350] = 8 # # If you would like to submit a bug report, please visit: # https://github.com/corretto/corretto-11/issues/ # The crash happened outside the Java Virtual Machine in native code. # See problematic frame for where to report the bug. #
The handshake failed and the session id is accessed through your access logging pattern. Looking at the Panama code there could be an optimistic use of the SSL_get_session call (it would return NULL if there's no session because handshake failed). The native code seems to have the same problem, since it does: UNREFERENCED(o); session = SSL_get_session(ssl_); session_id = SSL_SESSION_get_id(session, &len); While other places do: session = SSL_get_session(ssl_); if (session) { return SSL_get_time(session); } else { tcn_ThrowException(e, "ssl session is null"); return 0; }
Proposed patch for tcnative: diff --git a/native/src/ssl.c b/native/src/ssl.c index d59246ea3..5329a93da 100644 --- a/native/src/ssl.c +++ b/native/src/ssl.c @@ -2001,8 +2001,12 @@ TCN_IMPLEMENT_CALL(jbyteArray, SSL, getSessionId)(TCN_STDARGS, jlong ssl) } UNREFERENCED(o); session = SSL_get_session(ssl_); - session_id = SSL_SESSION_get_id(session, &len); + if (NULL == session) { + tcn_ThrowException(e, "ssl session is null"); + return NULL; + } + session_id = SSL_SESSION_get_id(session, &len); if (len == 0 || session_id == NULL) { return NULL; } diff --git a/native/src/sslnetwork.c b/native/src/sslnetwork.c index 6e5960f91..46b253ec8 100644 --- a/native/src/sslnetwork.c +++ b/native/src/sslnetwork.c @@ -689,7 +689,7 @@ TCN_IMPLEMENT_CALL(jint, SSLSocket, renegotiate)(TCN_STDARGS, #if defined(SSL_OP_NO_TLSv1_3) session = SSL_get_session(con->ssl); - if (SSL_SESSION_get_protocol_version(session) == TLS1_3_VERSION) { + if (NULL != session && SSL_SESSION_get_protocol_version(session) == TLS1_3_VERSION) { // TLS 1.3 renegotiation retVal = SSL_verify_client_post_handshake(con->ssl); if (retVal <= 0) {
JF seems to think simply return NULL; is enough (I agree this is not an error). I left the bug open since it has not been addressed. I don't maintain the native code and I am more likely to inadvertently break something. Also the second check may not be needed, on renegotiate there would be a session I suppose.
in openssl: ./ssl/ssl_sess.c { if (len) *len = (unsigned int)s->session_id_length; return s->session_id; } So +1 for testing for NULL. I am curious how you manage to get error, I don't see how the jakarta.servlet.request.ssl_session_id could be read with a failed handshake...
(In reply to Remy Maucherat from comment #3) > JF seems to think simply return NULL; is enough (I agree this is not an > error). Aha, so simply return NULL instead of throwing an exception? > Also the second check may not be needed, on renegotiate there would be a > session I suppose. I just figured an extra check is better than a crash... just in case :)
Thanks all for the report, proposed patch and review. Variation of patch applied to 1.2.x for 1.2.33 onwards.