Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix some EOF-handling issues in TLS #44563

Closed
wants to merge 2 commits into from

Commits on Sep 7, 2022

  1. tls: fix re-entrancy issue with TLS close_notify

    Like errno, OpenSSL's API requires SSL_get_error and error queue be
    checked immediately after the failing operation, otherwise the error
    queue or SSL object may have changed state and no longer report
    information about the operation the caller wanted.
    
    TLSWrap almost heeds this rule, except in TLSWrap::ClearOut. If SSL_read
    picks up a closing alert (detected by checking SSL_get_shutdown), Node
    calls out to JS with EmitRead(UV_EOF) and only afterwards proceeds to
    dispatch on the error. But, by this point, Node has already re-entered
    JS, which may change the error.
    
    In particular, I've observed that, on close_notify, JS seems to
    sometimes call back into TLSWrap::DoShutdown, calling SSL_shutdown. (I
    think this comes from onStreamRead in stream_base_commons.js?)
    
    Instead, SSL_get_error and the error queue should be sampled earlier.
    Back in nodejs#1661, Node needed to account for GetSSLError being called after
    ssl_ was destroyed. This was the real cause. With this fixed, there's no
    need to account for this. (Any case where ssl_ may be destroyed before
    SSL_get_error is a case where ssl_ or the error queue could change
    state, so it's a bug either way.)
    
    This is the first of two fixes in error-handling here. The
    EmitRead(UV_EOF) seems to additionally swallow fatal alerts from the
    peer. Some of the ECONNRESET expectations in the tests aren't actually
    correct. The next commit will fix this as well.
    davidben committed Sep 7, 2022
    Copy the full SHA
    426b4a6 View commit details
    Browse the repository at this point in the history

Commits on Sep 8, 2022

  1. tls: don't treat fatal TLS alerts as EOF

    SSL_RECEIVED_SHUTDOWN means not just close_notify or fatal alert. From
    what I can tell, this was just a mistake? OnStreamRead's comment
    suggests eof_ was intended to be for close_notify.
    
    This fixes a bug in TLSSocket error reporting that seems to have made it
    into existing tests. If we receive a fatal alert, EmitRead(UV_EOF)
    would, via onConnectEnd in _tls_wrap.js, synthesize an ECONNRESET before
    the alert itself is surfaced. As a result, TLS alerts received during
    the handshake are misreported by Node.
    
    See the tests that had to be updated as part of this.
    davidben committed Sep 8, 2022
    Copy the full SHA
    030b8c2 View commit details
    Browse the repository at this point in the history