Cyl created ZOOKEEPER-5006:
------------------------------
Summary: SSL Context Leak in ZooKeeper C Client
Key: ZOOKEEPER-5006
URL: https://issues.apache.org/jira/browse/ZOOKEEPER-5006
Project: ZooKeeper
Issue Type: Bug
Components: c client
Affects Versions: 3.9.4
Reporter: Cyl
Attachments: ssl-ctx-leak.zip
h2. Vulnerability Summary
A memory leak exists in the ZooKeeper C client when SSL initialization fails.
Specifically, if {{SSL_new}} fails during {{{}init_ssl_for_socket{}}}, the
allocated {{SSL_CTX}} is not freed. The cleanup function {{close_zsock}} only
frees {{ssl_ctx}} if {{ssl_sock}} is also non-NULL, which is not the case when
{{SSL_new}} fails.
h2. Reproduction Steps
# Configure the ZooKeeper C client to use SSL.
# Force {{SSL_new}} to fail (e.g., using {{LD_PRELOAD}} to hook {{SSL_new}}
and return NULL).
# Attempt to connect to a ZooKeeper server.
# The client will retry the connection.
# Each retry allocates a new {{SSL_CTX}} which is never freed, leading to
unbounded memory growth.
h2. Root Cause
In {{{}src/zookeeper.c{}}}, the {{close_zsock}} function:
{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);
fd->ssl_ctx = NULL;
}
#endif
close(fd->sock);
fd->sock = -1;
}
} {code}
The {{SSL_CTX_free}} call is guarded by {{{}if (fd->ssl_sock){}}}. However, in
{{{}init_ssl_for_socket{}}}, {{fd->ssl_ctx}} is allocated _before_
{{{}fd->ssl_sock{}}}. If {{SSL_new}} fails, {{fd->ssl_sock}} remains NULL, but
{{fd->ssl_ctx}} is allocated. When {{close_zsock}} is subsequently called (via
error handling path), it skips freeing {{{}fd->ssl_ctx{}}}.
PoC in attachment
--
This message was sent by Atlassian Jira
(v8.20.10#820010)