youlong chen created ZOOKEEPER-5004:
---------------------------------------
Summary: Memory Leak (SSL Context Leak) in init_ssl_for_socket
Key: ZOOKEEPER-5004
URL: https://issues.apache.org/jira/browse/ZOOKEEPER-5004
Project: ZooKeeper
Issue Type: Bug
Components: c client
Affects Versions: 3.9.4
Reporter: youlong chen
{*}Description{*}: In
{{{}zookeeper-client/zookeeper-client-c/src/zookeeper.c{}}}, the function
{{init_ssl_for_socket}} allocates an {{SSL_CTX}} object but fails to free it if
{{SSL_new}} fails.
{code:java}
static int init_ssl_for_socket(zsock_t *fd, zhandle_t *zh, int fail_on_error) {
// ...
fd->ssl_ctx = SSL_CTX_new(method);
// ...
fd->ssl_sock = SSL_new(*ctx);
if (fd->ssl_sock == NULL) {
if (fail_on_error) {
return handle_socket_error_msg(zh, ...);
} else {
return ZSSLCONNECTIONERROR;
}
}
// ...
} {code}
If {{SSL_new}} fails (returns NULL), the function returns an error. If
{{fail_on_error}} is true, {{handle_socket_error_msg}} calls
{{{}close_zsock{}}}. If {{fail_on_error}} is false, the caller (e.g.,
{{{}ping_rw_server{}}}) calls {{{}close_zsock{}}}.
However, {{close_zsock}} only frees {{ssl_ctx}} if {{ssl_sock}} is not NULL:
{code:java}
void close_zsock(zsock_t *fd)
{
if (fd->sock != -1) {
#ifdef HAVE_OPENSSL_H
if (fd->ssl_sock) {
SSL_free(fd->ssl_sock);
fd->ssl_sock = NULL;
SSL_CTX_free(fd->ssl_ctx); // Only freed if ssl_sock exists!
fd->ssl_ctx = NULL;
}
#endif
close(fd->sock);
fd->sock = -1;
}
} {code}
Since {{fd->ssl_sock}} is NULL (because {{SSL_new}} failed), {{SSL_CTX_free}}
is never called, leaking {{{}fd->ssl_ctx{}}}.
*Impact* If {{SSL_new}} fails repeatedly (e.g., due to temporary memory
pressure), {{SSL_CTX}} objects will leak, potentially leading to permanent OOM.
*Fix* Free {{SSL_CTX}} if {{SSL_new}} fails.
{code:java}
fd->ssl_sock = SSL_new(*ctx);
if (fd->ssl_sock == NULL) {
SSL_CTX_free(*ctx); // Fix: Free context
fd->ssl_ctx = NULL; // Clear pointer
if (fail_on_error) {
return handle_socket_error_msg(zh, ...);
} else {
LOG_ERROR(LOGCALLBACK(zh), "error creating ssl context");
return ZSSLCONNECTIONERROR;
}
} {code}
--
This message was sent by Atlassian Jira
(v8.20.10#820010)