Skip to content

Conversation

@remicollet
Copy link
Member

Regression introduced in fix for #76972

@petk petk added the Bug label Nov 15, 2018
@remicollet
Copy link
Member Author

@manuelm @cmb69 @nikic please review / test

if (data_available(ftp, fd)) {
ERR_clear_error();
nread = SSL_read(ssl_handle, buf, sizeof(buf));
while (!done && data_available(ftp, fd)) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

test grouped to avoid (possible) dead loop when !done and no data available.

while (!done && data_available(ftp, fd)) {
ERR_clear_error();
nread = SSL_read(ssl_handle, buf, sizeof(buf));
if (nread <= 0) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

manage error, only if read fails.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SSL_get_error returns SSL_ERROR_NONE if nread > 0

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

btw, faster

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's not my point. My point is this doesn't look like a fix as it doesn't actually change anything.

Also please note that there are at least two more cases with SSL_get_error in the same file with the same pattern.

@remicollet
Copy link
Member Author

second commit make warning conditional by sslerror.

if ((sslerror = ERR_get_error())) {
ERR_error_string_n(sslerror, buf, sizeof(buf));
ERR_error_string_n(sslerror, buf, sizeof(buf));
php_error_docref(NULL, E_WARNING, "SSL_read on shutdown: %s", buf);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems wrong. SSL_get_error may also return SSL_ERROR_SYSCALL in which case OpenSSL indicates that the underlying syscall has failed. This changes hides this error case from the user.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still better that current broken implementation.

Please understand that we have released 7.1.24/7.2.12 with a regression, for which we need an urgent fix.

@manuelm
Copy link
Contributor

manuelm commented Nov 15, 2018

So I found a ftp service that let me reproduce the bug report. In this case err is set to SSL_ERROR_SYSCALL although errno is 0. So omitting the print in the err == SSL_ERROR_SYSCALL && errno == 0 case should do the trick.

I'm still wondering why errno is zero. Looks like a normal behavior which indicates the connection has already been closed. My PR was based upon the curl implementation: https://github.com/curl/curl/blob/e2dd435d473cdc97785df95d032276fafb4b7746/lib/vtls/openssl.c#L1267

Edit: I'm suggesting something like this (together with the data_available move):

--- ext/ftp/ftp.c  2018-11-15 17:58:32.454527562 +0100
+++ ext/ftp/ftp.c       2018-11-15 18:05:38.706094266 +0100
@@ -1930,6 +1930,12 @@
                                        /* SSL wants a write. Really odd. Let's bail out. */
                                        done = 1;
                                        break;
+                               case SSL_ERROR_SYSCALL:
+                                   if (errno == 0) {
+                                       /* The connection has already been closed */
+                                       done = 1;
+                                       break;
+                                   }
                                default:
                                        if ((sslerror = ERR_get_error())) {
                                            ERR_error_string_n(sslerror, buf, sizeof(buf));

@remicollet
Copy link
Member Author

I have re-add warning when errno is set.

So no message will be output when sslerror=0 and errno=0

Regression introduced in fix for #76972

only display the error message when sslerror
or if errno is set (for SSL_ERROR_SYSCALL case)
@remicollet
Copy link
Member Author

@cmb69 I'd like to merge this one before today RCs

@cmb69
Copy link
Member

cmb69 commented Nov 20, 2018

@remicollet Okay, please go ahead.

Copy link
Member

@nikic nikic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The newest version looks good to me.

@remicollet
Copy link
Member Author

Merged.

@remicollet remicollet closed this Nov 20, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants