rsyslog (4.6.4-2) 02-tls_loop_fix.patch

Summary

 runtime/nsdsel_gtls.c |   17 +++++++++++++++++
 1 file changed, 17 insertions(+)

    
download this patch

Patch contents

commit 925504d565c6cf4a712dd8c8217891662aaf639e
Author: Rainer Gerhards <rgerhards@adiscon.com>
Date:   Wed Nov 24 11:14:21 2010 +0100

    bugfix(important): problem in TLS handling could cause rsyslog to loop
    
    ... in a tight loop, effectively disabling functionality and bearing the
    risk of unresponsiveness of the whole system.
    Bug tracker: http://bugzilla.adiscon.com/show_bug.cgi?id=194

diff --git a/runtime/nsdsel_gtls.c b/runtime/nsdsel_gtls.c
index c3a93be..1a389a0 100644
--- a/runtime/nsdsel_gtls.c
+++ b/runtime/nsdsel_gtls.c
@@ -76,6 +76,9 @@ Add(nsdsel_t *pNsdsel, nsd_t *pNsd, nsdsel_waitOp_t waitOp)
 	if(pNsdGTLS->iMode == 1) {
 		if(waitOp == NSDSEL_RD && gtlsHasRcvInBuffer(pNsdGTLS)) {
 			++pThis->iBufferRcvReady;
+			dbgprintf("nsdsel_gtls: data already present in buffer, initiating "
+				  "dummy select %p->iBufferRcvReady=%d\n",
+				  pThis, pThis->iBufferRcvReady);
 			FINALIZE;
 		}
 		if(pNsdGTLS->rtryCall != gtlsRtry_None) {
@@ -109,6 +112,7 @@ Select(nsdsel_t *pNsdsel, int *piNumReady)
 	if(pThis->iBufferRcvReady > 0) {
 		/* we still have data ready! */
 		*piNumReady = pThis->iBufferRcvReady;
+		dbgprintf("nsdsel_gtls: doing dummy select, data present\n");
 	} else {
 		iRet = nsdsel_ptcp.Select(pThis->pTcp, piNumReady);
 	}
@@ -190,6 +194,9 @@ IsReady(nsdsel_t *pNsdsel, nsd_t *pNsd, nsdsel_waitOp_t waitOp, int *pbIsReady)
 	if(pNsdGTLS->iMode == 1) {
 		if(waitOp == NSDSEL_RD && gtlsHasRcvInBuffer(pNsdGTLS)) {
 			*pbIsReady = 1;
+			--pThis->iBufferRcvReady; /* one "pseudo-read" less */
+			dbgprintf("nsdl_gtls: dummy read, decermenting %p->iBufRcvReady, now %d\n",
+				   pThis, pThis->iBufferRcvReady);
 			FINALIZE;
 		}
 		if(pNsdGTLS->rtryCall != gtlsRtry_None) {
@@ -200,6 +207,16 @@ IsReady(nsdsel_t *pNsdsel, nsd_t *pNsd, nsdsel_waitOp_t waitOp, int *pbIsReady)
 			*pbIsReady = 0;
 			FINALIZE;
 		}
+		/* now we must ensure that we do not fall back to PTCP if we have
+		 * done a "dummy" select. In that case, we know when the predicate
+		 * is not matched here, we do not have data available for this
+		 * socket. -- rgerhards, 2010-11-20
+		 */
+		if(pThis->iBufferRcvReady) {
+			dbgprintf("nsd_gtls: dummy read, buffer not available for this FD\n");
+			*pbIsReady = 0;
+			FINALIZE;
+		}
 	}
 
 	CHKiRet(nsdsel_ptcp.IsReady(pThis->pTcp, pNsdGTLS->pTcp, waitOp, pbIsReady));