From fd02dc0e4e20ecebb0f247641c5aff519bc5e4db Mon Sep 17 00:00:00 2001 From: Jeremy Harris Date: Fri, 21 Nov 2014 18:04:07 +0000 Subject: [PATCH] Apply timeout to Fsecure malware response. Bug 1549 --- src/src/malware.c | 51 ++++++++++++++++++++++++++++++++++------------- 1 file changed, 37 insertions(+), 14 deletions(-) diff --git a/src/src/malware.c b/src/src/malware.c index 167f47f2c..1a3dc7f9b 100644 --- a/src/src/malware.c +++ b/src/src/malware.c @@ -710,12 +710,13 @@ malware_internal(uschar **listptr, uschar *eml_filename, BOOL faking) US"CONFIGURE\tTIMEOUT\t0\n", US"CONFIGURE\tMAXARCH\t5\n", US"CONFIGURE\tMIME\t1\n" }; + time_t tmo; malware_name = NULL; DEBUG(D_acl) debug_printf("Malware scan: issuing %s scan [%s]\n", scanner_name, scanner_options); - + tmo = time(NULL) + MALWARE_TIMEOUT; /* pass options */ memset(av_buffer, 0, sizeof(av_buffer)); for (i=0; i != nelements(cmdopt); i++) { @@ -744,24 +745,46 @@ malware_internal(uschar **listptr, uschar *eml_filename, BOOL faking) /* todo also SUSPICION\t */ fs_inf = m_pcre_compile(US"\\S{0,5}INFECTED\\t[^\\t]*\\t([^\\t]+)\\t\\S*$", &errstr); - /* read report, linewise */ - do { - i = 0; - memset(av_buffer, 0, sizeof(av_buffer)); - do { - if ((bread= ip_recv(sock, &av_buffer[i], 1, MALWARE_TIMEOUT)) < 0) + /* read report, linewise. Apply a timeout as the Fsecure daemon + sometimes wants an answer to "PING" but they won't tell us what */ + { + uschar * p = av_buffer; + uschar * q; + + for (;;) + { + int t = tmo - time(NULL); + + errno = ETIME; + i = av_buffer+sizeof(av_buffer)-p; + if ( t <= 0 + || (bread= ip_recv(sock, p, i-1, t)) < 0 + ) return m_errlog_defer_3(scanent, string_sprintf("unable to read result (%s)", strerror(errno)), sock); - } while (++i < sizeof(av_buffer)-1 && av_buffer[i-1] != '\n'); - av_buffer[i-1] = '\0'; - /* Really search for virus again? */ - if (malware_name == NULL) - /* try matcher on the line, grab substring */ - malware_name = m_pcre_exec(fs_inf, av_buffer); + for (p[bread] = '\0'; q = strchr(p, '\n'); p = q+1) + { + *q = '\0'; + + /* Really search for virus again? */ + if (!malware_name) + /* try matcher on the line, grab substring */ + malware_name = m_pcre_exec(fs_inf, p); + + if (Ustrstr(p, "OK\tScan ok.")) + goto fsec_found; + } + + /* copy down the trailing partial line then read another chunk */ + i = av_buffer+sizeof(av_buffer)-p; + memmove(av_buffer, p, i); + p = av_buffer+i; + } } - while (Ustrstr(av_buffer, "OK\tScan ok.") == NULL); + + fsec_found: break; } /* fsecure */ -- 2.30.2