From 51cad214e5ee6bc4cfdba9dcbc5a673472eba0c1 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) Conflicts: libcfnet/classic.c libcfnet/tls_generic.c --- libcfnet/classic.c | 27 +++++++++++++++++++++++++-- libcfnet/tls_generic.c | 35 +++++++++++++++++++++++++++++++---- libcfnet/tls_generic.h | 2 +- libutils/platform.h | 3 +++ 4 files changed, 60 insertions(+), 7 deletions(-) diff --git a/libcfnet/classic.c b/libcfnet/classic.c index 0c0b7cc88b..bb02dc7a8f 100644 --- a/libcfnet/classic.c +++ b/libcfnet/classic.c @@ -53,7 +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 actual length read. + * + * @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 e168d29388..8b2ccd9502 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 length); int TLSRecvLines(SSL *ssl, char *buf, size_t buf_size); diff --git a/libutils/platform.h b/libutils/platform.h index 994c4fb6de..77d71abbe5 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. */