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)

Reply via email to