From 9e9c857775d3a8552a57206d78e5d79bed2a0349 Mon Sep 17 00:00:00 2001 From: Dimitrios Apostolou Date: Thu, 22 Oct 2015 21:46:23 +0200 Subject: [PATCH] Redmine#6027: Fix possible corruption in case of socket recv() timeout Make sure a timed-out connection gets closed at the lowest level, so that further calls of recv() do not return the delayed server reply. (cherry picked from commit a08248f86a63d2863b29b8692136c5c43decc492) --- libcfnet/classic.c | 23 +++++++++++++++-------- libcfnet/tls_generic.c | 36 +++++++++++++++++++++++++++++++----- libcfnet/tls_generic.h | 2 +- libutils/platform.h | 3 +++ 4 files changed, 50 insertions(+), 14 deletions(-) diff --git a/libcfnet/classic.c b/libcfnet/classic.c index 712e3ddc8f0..2f3d02c3912 100644 --- a/libcfnet/classic.c +++ b/libcfnet/classic.c @@ -53,10 +53,11 @@ static bool LastRecvTimedOut(void) * @param buffer Buffer into which to read data * @param toget Number of bytes to read; a '\0' shall be written after * the data; buffer must have space for that. - - * @return -1 on error; or number of bytes received. It should return less - * than #toget bytes only if the peer closed the connection or timeout - * or other unrecoverable error occurred. + * + * @return number of bytes actually received, might be less than #toget + * 0 && ret > 0) + { + char tmpbuf[bytes_still_buffered]; + ret = SSL_read(ssl, tmpbuf, bytes_still_buffered); + bytes_still_buffered -= ret; + } + } + return -1; } else if (received == 0) diff --git a/libcfnet/tls_generic.h b/libcfnet/tls_generic.h index ac537b426c9..1730bfd5aed 100644 --- a/libcfnet/tls_generic.h +++ b/libcfnet/tls_generic.h @@ -41,7 +41,7 @@ bool TLSGenericInitialize(void); int TLSVerifyCallback(X509_STORE_CTX *ctx, void *arg); int TLSVerifyPeer(ConnectionInfo *conn_info, const char *remoteip, const char *username); X509 *TLSGenerateCertFromPrivKey(RSA *privkey); -void TLSLogError(SSL *ssl, LogLevel level, const char *prepend, int code); +int TLSLogError(SSL *ssl, LogLevel level, const char *prepend, int code); int TLSSend(SSL *ssl, const char *buffer, int length); int TLSRecv(SSL *ssl, char *buffer, int toget); int TLSRecvLines(SSL *ssl, char *buf, size_t buf_size); diff --git a/libutils/platform.h b/libutils/platform.h index 6c3fbcd7fb3..8f48f5ded57 100644 --- a/libutils/platform.h +++ b/libutils/platform.h @@ -63,6 +63,9 @@ # include # include # include // for disphelper +# ifndef SHUT_RDWR // for shutdown() +# define SHUT_RDWR SD_BOTH +# endif #endif /* Standard C. */