Bug 1870279 - Transfer via socat fails with openssl enabled
Summary: Transfer via socat fails with openssl enabled
Keywords:
Status: ON_QA
Alias: None
Product: Red Hat Enterprise Linux 8
Classification: Red Hat
Component: socat
Version: CentOS Stream
Hardware: x86_64
OS: Linux
low
low
Target Milestone: rc
: 8.0
Assignee: Paul Wouters
QA Contact: BaseOS QE Security Team
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2020-08-19 16:08 UTC by Pavel Safronov
Modified: 2021-04-20 07:51 UTC (History)
6 users (show)

Fixed In Version: socat-1.7.4.1-1.el8
Doc Type: No Doc Update
Doc Text:
Clone Of:
Environment:
Last Closed:
Type: Bug
Target Upstream Version:


Attachments (Terms of Use)
don't disable SSL_MODE_AUTO_RETRY (1.40 KB, patch)
2020-08-24 16:36 UTC, Carl George 🤠
no flags Details | Diff

Description Pavel Safronov 2020-08-19 16:08:07 UTC
Description of problem:

The receiver side of the transfer with ssl enabled always hits "SSL_read(): Connection reset by peer" when it gets close to EOF and leaves the transfer partially finished.

Version-Release number of selected component (if applicable):
1.7.3.3-2.el8


How reproducible:
Almost always. 90% of my attempts failed


Steps to Reproduce:
1. Run the server `socat openssl-listen:12345,reuseaddr,pf=ip6,cert=server.pem - > /dev/null`
2. Run client `yes | head -n 1000000 | socat  -u - openssl-connect:[::1]:12345,cn=host:/example.com,cert=server.pem,cafile=ca.pem` (on the same machine or somewhere else, doesn't matter)
3. You should see an error like this on the receiving side as a result
2020/08/19 08:52:06 socat[2164968] E SSL_read(): Connection reset by peer


Actual results:
Getting an error "E SSL_read(): Connection reset by peer" and transfer fails


Expected results:
No error, transfer succeeds

Additional info:
Allegedly this is the consequence of the modification of file xio-openssl.c introduced in version 1.7.3.3 which forcefully disables SSL_MODE_AUTO_RETRY. After commenting out line "SSL_CTX_clear_mode(*ctx, SSL_MODE_AUTO_RETRY);" and rebuilding the client socat binary I don't have an error anymore.
Also it works well with version 1.7.3.2 of socat.

Comment 1 Pavel Safronov 2020-08-21 17:58:36 UTC
This patch below is fixing the problem by rolling back the change. So basically we don't disable SSL_MODE_AUTO_RETRY anymore.

Tests run results:

For both tests I run the following command multiple times and check the server output
yes | head -n 1000000 | socat  -u - openssl-connect:[::1]:12345,cn=host:/example.com,cert=server.pem,cafile=ca.pem


With patch:
# while true; do socat openssl-listen:12345,reuseaddr,pf=ip6,cert=server.pem - > /dev/null; date; done
Fri Aug 21 10:53:11 PDT 2020
Fri Aug 21 10:53:13 PDT 2020
Fri Aug 21 10:53:15 PDT 2020
Fri Aug 21 10:53:17 PDT 2020
Fri Aug 21 10:53:19 PDT 2020
Fri Aug 21 10:53:22 PDT 2020
Fri Aug 21 10:53:24 PDT 2020

Without patch:
# while true; do ./socat openssl-listen:12345,reuseaddr,pf=ip6,cert=server.pem - > /dev/null; date; done
Fri Aug 21 10:50:01 PDT 2020
2020/08/21 10:50:02 socat[976825] E SSL_read(): Connection reset by peer
Fri Aug 21 10:50:02 PDT 2020
2020/08/21 10:50:05 socat[977067] E SSL_read(): Connection reset by peer
Fri Aug 21 10:50:05 PDT 2020
2020/08/21 10:50:07 socat[977300] E SSL_read(): Connection reset by peer
Fri Aug 21 10:50:07 PDT 2020
2020/08/21 10:50:09 socat[977442] E SSL_read(): Connection reset by peer
Fri Aug 21 10:50:09 PDT 2020
2020/08/21 10:50:10 socat[977660] E SSL_read(): Connection reset by peer
Fri Aug 21 10:50:10 PDT 2020
2020/08/21 10:50:12 socat[977718] E SSL_read(): Connection reset by peer
Fri Aug 21 10:50:12 PDT 2020
Fri Aug 21 10:50:14 PDT 2020



Here is the patch:

diff -Naur socat-1.7.3.3-orig/CHANGES socat-1.7.3.3/CHANGES
--- socat-1.7.3.3-orig/CHANGES	2019-04-05 13:10:24.000000000 -0700
+++ socat-1.7.3.3/CHANGES	2020-08-21 09:59:35.233714747 -0700
@@ -79,9 +79,6 @@
 	RES_AAONLY, RES_PRIMARY are deprecated. You can still enable them with
 	configure option --enable-res-deprecated.
 
-	New versions of OpenSSL preset SSL_MODE_AUTO_RETRY which may hang socat.
-	Solution: clear SSL_MODE_AUTO_RETRY when it is set.
-
 	Renamed configure.in to configure.ac and set an appropriate symlink for
 	older environments.
 	Related Gentoo bug 426262: Warning on configure.in
diff -Naur socat-1.7.3.3-orig/xio-openssl.c socat-1.7.3.3/xio-openssl.c
--- socat-1.7.3.3-orig/xio-openssl.c	2019-04-04 01:59:55.000000000 -0700
+++ socat-1.7.3.3/xio-openssl.c	2020-08-21 09:58:27.445138134 -0700
@@ -1023,18 +1023,6 @@
    }
 #endif
 
-   /* It seems that OpenSSL-1.1.1 presets the mode differently.
-      Without correction socat might hang in SSL_read() */
-   {
-      long mode = 0;
-      mode = SSL_CTX_get_mode(*ctx);
-      if (mode & SSL_MODE_AUTO_RETRY) {
-	 Info("SSL_CTX mode has SSL_MODE_AUTO_RETRY set. Correcting..");
-	 Debug1("SSL_CTX_clean_mode(%p, SSL_MODE_AUTO_RETRY)", *ctx);
-	 SSL_CTX_clear_mode(*ctx, SSL_MODE_AUTO_RETRY);
-      }
-   }
-
    if (opt_cafile != NULL || opt_capath != NULL) {
       if (sycSSL_CTX_load_verify_locations(*ctx, opt_cafile, opt_capath) != 1) {
 	 int result;

Comment 2 Pavel Safronov 2020-08-21 18:07:20 UTC
Created a pull request to centos8 socat repo with the patch https://git.centos.org/rpms/socat/pull-request/1

Comment 3 Carl George 🤠 2020-08-24 16:36:47 UTC
Created attachment 1712396 [details]
don't disable SSL_MODE_AUTO_RETRY

Here is the patch file from Pavel's pull request.  It is a revert of this upstream commit.

https://repo.or.cz/socat.git/commitdiff/bc3723e970bf5e47d681f719f67899046554459c?hp=7a621dd3a245a46c65b726b86a72564f84dced74


Note You need to log in before you can comment on or make changes to this bug.