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)

Reply via email to