From 824604776a1d77284c16c03be6f93d9d49b0f2e2 Mon Sep 17 00:00:00 2001 From: Chenjp Date: Mon, 26 Jan 2026 11:03:38 +0800 Subject: [PATCH] Centralize cleanup Avoid sslconf mem-leak with tcn_throw ex, which is unlikely to happen in real world. --- native/src/sslconf.c | 73 +++++++++++++++++++++++--------------------- 1 file changed, 39 insertions(+), 34 deletions(-) diff --git a/native/src/sslconf.c b/native/src/sslconf.c index b5ff3fd55..e4fad86b3 100644 --- a/native/src/sslconf.c +++ b/native/src/sslconf.c @@ -153,16 +153,16 @@ TCN_IMPLEMENT_CALL(jint, SSLConf, check)(TCN_STDARGS, jlong cctx, TCN_ASSERT(c->cctx != 0); if (!J2S(cmd)) { tcn_Throw(e, "Can not check null SSL_CONF command"); - return SSL_THROW_RETURN; + rc = SSL_THROW_RETURN; + goto cleanup; } if (!strcmp(J2S(cmd), "NO_OCSP_CHECK")) { if (!strcasecmp(J2S(value), "false")) c->no_ocsp_check = 0; else c->no_ocsp_check = 1; - TCN_FREE_CSTRING(cmd); - TCN_FREE_CSTRING(value); - return 1; + rc = 1; + goto cleanup; } if (!strcmp(J2S(cmd), "OCSP_SOFT_FAIL")) { @@ -170,9 +170,8 @@ TCN_IMPLEMENT_CALL(jint, SSLConf, check)(TCN_STDARGS, jlong cctx, c->ocsp_soft_fail = 0; else c->ocsp_soft_fail = 1; - TCN_FREE_CSTRING(cmd); - TCN_FREE_CSTRING(value); - return 1; + rc = 1; + goto cleanup; } if (!strcmp(J2S(cmd), "OCSP_TIMEOUT")) { @@ -183,9 +182,8 @@ TCN_IMPLEMENT_CALL(jint, SSLConf, check)(TCN_STDARGS, jlong cctx, // Tomcat configures timeout is millisecond. APR uses microseconds. c->ocsp_timeout = i * 1000; } - TCN_FREE_CSTRING(cmd); - TCN_FREE_CSTRING(value); - return 1; + rc = 1; + goto cleanup; } if (!strcmp(J2S(cmd), "OCSP_VERIFY_FLAGS")) { @@ -195,9 +193,8 @@ TCN_IMPLEMENT_CALL(jint, SSLConf, check)(TCN_STDARGS, jlong cctx, if (!errno) { c->ocsp_verify_flags = i; } - TCN_FREE_CSTRING(cmd); - TCN_FREE_CSTRING(value); - return 1; + rc = 1; + goto cleanup; } SSL_ERR_clear(); @@ -207,35 +204,42 @@ TCN_IMPLEMENT_CALL(jint, SSLConf, check)(TCN_STDARGS, jlong cctx, char err[TCN_OPENSSL_ERROR_STRING_LENGTH]; ERR_error_string_n(ec, err, TCN_OPENSSL_ERROR_STRING_LENGTH); tcn_Throw(e, "Could not determine SSL_CONF command type for '%s' (%s)", J2S(cmd), err); - return 0; + rc = 0; + goto cleanup; } if (value_type == SSL_CONF_TYPE_UNKNOWN) { tcn_Throw(e, "Invalid SSL_CONF command '%s', type unknown", J2S(cmd)); - return SSL_THROW_RETURN; + rc = SSL_THROW_RETURN; + goto cleanup; } if (value_type == SSL_CONF_TYPE_FILE) { if (!J2S(value)) { tcn_Throw(e, "SSL_CONF command '%s' needs a non-empty file argument", J2S(cmd)); - return SSL_THROW_RETURN; + rc = SSL_THROW_RETURN; + goto cleanup; } if (check_file(c->pool, J2S(value))) { tcn_Throw(e, "SSL_CONF command '%s' file '%s' does not exist or is empty", J2S(cmd), J2S(value)); - return SSL_THROW_RETURN; + rc = SSL_THROW_RETURN; + goto cleanup; } } else if (value_type == SSL_CONF_TYPE_DIR) { if (!J2S(value)) { tcn_Throw(e, "SSL_CONF command '%s' needs a non-empty directory argument", J2S(cmd)); - return SSL_THROW_RETURN; + rc = SSL_THROW_RETURN; + goto cleanup; } if (check_dir(c->pool, J2S(value))) { tcn_Throw(e, "SSL_CONF command '%s' directory '%s' does not exist", J2S(cmd), J2S(value)); - return SSL_THROW_RETURN; + rc = SSL_THROW_RETURN; + goto cleanup; } } +cleanup: TCN_FREE_CSTRING(cmd); TCN_FREE_CSTRING(value); return rc; @@ -277,7 +281,8 @@ TCN_IMPLEMENT_CALL(jint, SSLConf, apply)(TCN_STDARGS, jlong cctx, TCN_ASSERT(c->cctx != 0); if (!J2S(cmd)) { tcn_Throw(e, "Can not apply null SSL_CONF command"); - return SSL_THROW_RETURN; + rc = SSL_THROW_RETURN; + goto cleanup; } #ifndef HAVE_EXPORT_CIPHERS if (!strcmp(J2S(cmd), "CipherString")) { @@ -289,7 +294,8 @@ TCN_IMPLEMENT_CALL(jint, SSLConf, apply)(TCN_STDARGS, jlong cctx, buf = malloc(len * sizeof(char *)); if (buf == NULL) { tcn_Throw(e, "Could not allocate memory to adjust cipher string"); - return SSL_THROW_RETURN; + rc = SSL_THROW_RETURN; + goto cleanup; } memcpy(buf, SSL_CIPHERS_ALWAYS_DISABLED, strlen(SSL_CIPHERS_ALWAYS_DISABLED)); memcpy(buf + strlen(SSL_CIPHERS_ALWAYS_DISABLED), J2S(value), strlen(J2S(value))); @@ -301,18 +307,16 @@ TCN_IMPLEMENT_CALL(jint, SSLConf, apply)(TCN_STDARGS, jlong cctx, c->no_ocsp_check = 0; else c->no_ocsp_check = 1; - TCN_FREE_CSTRING(cmd); - TCN_FREE_CSTRING(value); - return 1; + rc = 1; + goto cleanup; } if (!strcmp(J2S(cmd), "OCSP_SOFT_FAIL")) { if (!strcasecmp(J2S(value), "false")) c->ocsp_soft_fail = 0; else c->ocsp_soft_fail = 1; - TCN_FREE_CSTRING(cmd); - TCN_FREE_CSTRING(value); - return 1; + rc = 1; + goto cleanup; } if (!strcmp(J2S(cmd), "OCSP_TIMEOUT")) { int i; @@ -322,9 +326,8 @@ TCN_IMPLEMENT_CALL(jint, SSLConf, apply)(TCN_STDARGS, jlong cctx, // Tomcat configures timeout is millisecond. APR uses microseconds. c->ocsp_timeout = i * 1000; } - TCN_FREE_CSTRING(cmd); - TCN_FREE_CSTRING(value); - return 1; + rc = 1; + goto cleanup; } if (!strcmp(J2S(cmd), "OCSP_VERIFY_FLAGS")) { int i; @@ -333,9 +336,8 @@ TCN_IMPLEMENT_CALL(jint, SSLConf, apply)(TCN_STDARGS, jlong cctx, if (!errno) { c->ocsp_verify_flags = i; } - TCN_FREE_CSTRING(cmd); - TCN_FREE_CSTRING(value); - return 1; + rc = 1; + goto cleanup; } SSL_ERR_clear(); rc = SSL_CONF_cmd(c->cctx, J2S(cmd), buf != NULL ? buf : J2S(value)); @@ -348,8 +350,11 @@ TCN_IMPLEMENT_CALL(jint, SSLConf, apply)(TCN_STDARGS, jlong cctx, } else { tcn_Throw(e, "Could not apply SSL_CONF command '%s' with value '%s'", J2S(cmd), buf != NULL ? buf : J2S(value)); } - return SSL_THROW_RETURN; + rc = SSL_THROW_RETURN; + goto cleanup; } + +cleanup: #ifndef HAVE_EXPORT_CIPHERS if (buf != NULL) { free(buf);