Join GitHub today
GitHub is home to over 28 million developers working together to host and review code, manage projects, and build software together.Sign up
Clear error queue before SSL I/O operations #439
We need to clear the SSL error queue before performing SSL I/O operations. Otherwise we can see errors that are not related to the operation we error check. SSL_get_error() inspects the thread's error queue.
I read about this here: https://www.openssl.org/docs/manmaster/ssl/SSL_get_error.html where it says "The current thread's error queue must be empty before the TLS/SSL I/O operation is attempted, or SSL_get_error() will not work reliably."
How I came across this: I have a module (irssi-tcl) that itself initiates SSL connections through scripts (HTTP in the case I found). For some URLs I found that Irssi was complaining about read errors after SSL_read() and then dropping all the active SSL IRC connections. I would see "Irssi: warning SSL read error: No such file or directory". I found the condition being hit in irssi_ssl_read() was the 'SSL_ERROR_SYSCALL' one.
Unfortunately it does not always happen so it is difficult to reliably reproduce. However after applying this change I have not been able to cause it.
Thank you for looking at this and for the help!
Regarding having this in irssi_ssl_get_iochannel(): Where in that function do you think it would be best to do this? Perhaps before the first if statement? (if (!ssl_inited ...). I don't see one of the function calls mentioned in the documentation for SSL_get_error() in there so I am not sure where it should be.
Ah... True. That function takes the first error from the same queue. The earliest apparently!
So before relying on it we should make sure that queue is cleared out.
I found there are several function calls inside irssi_ssl_get_iochannel that can raise errors to the queue. SSL_CTX_new(), SSL_set_fd(), and SSL_CTX_use_certificate_file() being some of them.
I'll add a clear error call in two spots: Before the first function that can add to this queue (SSL_CTX_new()) and before the two calls where we actually use ERR_get_error()). Do you think that is sufficient?
Possibly we could have it before each function that can add to the queue, but that seems like it will clutter the code. Likely we could rely on having cleared it earlier in the function, and deal with errors as they arise.
We actually care about the code paths where we show the errors, beside the ones that could make the IO actions fail and you already covered those. The remaining spots are the two