Uploaded image for project: 'MariaDB Connector/C'
  1. MariaDB Connector/C
  2. CONC-818

ma_tls_read() reports CR_SSL_CONNECTION_ERROR instead of CR_SERVER_LOST on connection close

    XMLWordPrintable

Details

    • Bug
    • Status: Open (View Workflow)
    • Major
    • Resolution: Unresolved
    • 3.4.8
    • None
    • TLS/SSL

    Description

      When the server closes a TLS connection (orderly or abrupt), ma_tls_read() in the OpenSSL and GnuTLS backends unconditionally calls ma_tls_set_error(), which sets CR_SSL_CONNECTION_ERROR (2026). The caller ma_net_safe_read() then preserves that error code instead of reporting the correct CR_SERVER_LOST (2013), because of the guard at mariadb_lib.c:232:

      if (net->last_errno != CR_SSL_CONNECTION_ERROR)
      my_set_error(mysql, CR_SERVER_LOST, ...);

      This produces confusing error messages like "TLS/SSL error: unexpected eof while reading" or "TLS/SSL error: Success (0)" in situations where the server simply went away (too many connections, shutdown, killed connection, etc.).

      The Schannel backend already handles this correctly since 2016 (commit 93af3ae6 by Vladislav Vaintroub): it returns 0 on SEC_I_CONTEXT_EXPIRED without setting any TLS error, letting ma_net_safe_read() report CR_SERVER_LOST.

      The fix is to apply the same logic to OpenSSL and GnuTLS: detect connection-close conditions in ma_tls_read() and return 0 without calling ma_tls_set_error().

      Connection-close conditions per backend:

      • OpenSSL: SSL_ERROR_ZERO_RETURN (orderly close_notify), SSL_ERROR_SYSCALL with empty error queue (EOF without close_notify, OpenSSL 1.x), SSL_ERROR_SSL with SSL_R_UNEXPECTED_EOF_WHILE_READING (same EOF, OpenSSL 3.x)
      • GnuTLS: rc == 0 (orderly close_notify), GNUTLS_E_PREMATURE_TERMINATION (EOF without close_notify, GnuTLS 3.7.4+)
      • Schannel: SEC_I_CONTEXT_EXPIRED (already handled)

      History:

      A partial fix was attempted in MDEV-30452 (commits 38ab8546 and 5ad8b2af by Julius Goryavsky, Jan 2023), which added special-case handling inside ma_tls_set_error(). That fix was never merged (only exists on branches bb-3.3-MDEV-30452 and bb-3.3-MDEV-30452-gnutls). The approach taken there was incomplete because it still allowed CR_SSL_CONNECTION_ERROR to be set for some close conditions (e.g. SSL_ERROR_ZERO_RETURN), and fixing inside ma_tls_set_error() conflicts with the ma_net_safe_read() guard logic.

      An earlier partial fix by Sergei Golubchik (commit ad43ed29, Sep 2022) added else if (!save_errno) → CR_SERVER_LOST inside ma_tls_set_error(), which covers the OpenSSL 1.x EOF case but not OpenSSL 3.x or orderly close_notify.

      Attempt for a fix:

      https://github.com/mariadb-corporation/mariadb-connector-c/pull/308

      Related:

      • MDEV-39318: MTR test failures with --ssl (server-side symptom)
      • MDEV-30452: ssl error: unexpected EOF while reading (same root cause, partial fix never merged)
      • CONC-603: Wrong error handling in TLS read/write (related but different: post-handshake alert handling)

      Attachments

        Issue Links

          Activity

            People

              georg Georg Richter
              mschorm Michal Schorm
              Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

                Created:
                Updated:

                Git Integration

                  Error rendering 'com.xiplink.jira.git.jira_git_plugin:git-issue-webpanel'. Please contact your Jira administrators.