X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/187bc588ac69994548471cc4a303e77fb0e957bc..9acf6b941e1356590e94e8e4a0bcf5dd3318087c:/src/src/malware.c diff --git a/src/src/malware.c b/src/src/malware.c index aaf3fcb7e..93bcf8667 100644 --- a/src/src/malware.c +++ b/src/src/malware.c @@ -42,7 +42,7 @@ static struct scan #define MAX_CLAMD_ADDRESS_LENGTH_S "64" typedef struct clamd_address_container { - uschar tcp_addr[MAX_CLAMD_ADDRESS_LENGTH]; + uschar tcp_addr[MAX_CLAMD_ADDRESS_LENGTH+1]; unsigned int tcp_port; } clamd_address_container; @@ -401,6 +401,7 @@ malware_internal(uschar **listptr, uschar *eml_filename, BOOL faking) case MC_TCP: sock = m_tcpsocket_fromdef(scanner_options, &errstr); break; case MC_UNIX: sock = m_unixsocket(scanner_options, &errstr); break; case MC_STRM: sock = m_streamsocket(scanner_options, &errstr); break; + default: /* compiler quietening */ break; } if (sock < 0) return m_errlog_defer(scanent, errstr); @@ -455,7 +456,8 @@ malware_internal(uschar **listptr, uschar *eml_filename, BOOL faking) /* v0.0 - initial release -- support for unix sockets */ { int result; - unsigned int fsize; + off_t fsize; + unsigned int fsize_uint; uschar * tmpbuf, *drweb_fbuf; int drweb_rc, drweb_cmd, drweb_flags = 0x0000, drweb_fd, drweb_vnum, drweb_slen, drweb_fin = 0x0000; @@ -483,6 +485,14 @@ malware_internal(uschar **listptr, uschar *eml_filename, BOOL faking) eml_filename, strerror(err)), sock); } + fsize_uint = (unsigned int) fsize; + if ((off_t)fsize_uint != fsize) { + (void)close(drweb_fd); + return m_errlog_defer_3(scanent, + string_sprintf("seeking spool file %s, size overflow", + eml_filename), + sock); + } drweb_slen = htonl(fsize); lseek(drweb_fd, 0, SEEK_SET); @@ -500,11 +510,11 @@ malware_internal(uschar **listptr, uschar *eml_filename, BOOL faking) sock); } - if (!(drweb_fbuf = (uschar *) malloc (fsize))) { + if (!(drweb_fbuf = (uschar *) malloc (fsize_uint))) { (void)close(drweb_fd); return m_errlog_defer_3(scanent, string_sprintf("unable to allocate memory %u for file (%s)", - fsize, eml_filename), + fsize_uint, eml_filename), sock); } @@ -944,12 +954,10 @@ malware_internal(uschar **listptr, uschar *eml_filename, BOOL faking) sep = pclose(scanner_out); signal(SIGCHLD,eximsigchld); signal(SIGPIPE,eximsigpipe); if (sep != 0) - if (sep == -1) return m_errlog_defer(scanent, - string_sprintf("running scanner failed: %s", strerror(sep))); - else - return m_errlog_defer(scanent, - string_sprintf("scanner returned error code: %d", sep)); + sep == -1 + ? string_sprintf("running scanner failed: %s", strerror(sep)) + : string_sprintf("scanner returned error code: %d", sep)); if (trigger) { uschar * s; @@ -1030,19 +1038,20 @@ malware_internal(uschar **listptr, uschar *eml_filename, BOOL faking) uschar *p, *vname, *result_tag, *response_end; int bread=0; - unsigned int port; uschar * file_name; uschar av_buffer[1024]; uschar *hostname = US""; host_item connhost; uschar *clamav_fbuf; int clam_fd, result; - unsigned int fsize; + off_t fsize; + unsigned int fsize_uint; BOOL use_scan_command = FALSE; clamd_address_container * clamd_address_vector[MAX_CLAMD_SERVERS]; int current_server; int num_servers = 0; #ifdef WITH_OLD_CLAMAV_STREAM + unsigned int port; uschar av_buffer2[1024]; int sockData; #else @@ -1232,17 +1241,25 @@ malware_internal(uschar **listptr, uschar *eml_filename, BOOL faking) eml_filename, strerror(err)), sock); } + fsize_uint = (unsigned int) fsize; + if ((off_t)fsize_uint != fsize) { + CLOSE_SOCKDATA; (void)close(clam_fd); + return m_errlog_defer_3(scanent, + string_sprintf("seeking spool file %s, size overflow", + eml_filename), + sock); + } lseek(clam_fd, 0, SEEK_SET); - if (!(clamav_fbuf = (uschar *) malloc (fsize))) { + if (!(clamav_fbuf = (uschar *) malloc (fsize_uint))) { CLOSE_SOCKDATA; (void)close(clam_fd); return m_errlog_defer_3(scanent, string_sprintf("unable to allocate memory %u for file (%s)", - fsize, eml_filename), + fsize_uint, eml_filename), sock); } - if ((result = read(clam_fd, clamav_fbuf, fsize)) < 0) { + if ((result = read(clam_fd, clamav_fbuf, fsize_uint)) < 0) { int err = errno; free(clamav_fbuf); CLOSE_SOCKDATA; (void)close(clam_fd); return m_errlog_defer_3(scanent, @@ -1254,7 +1271,7 @@ malware_internal(uschar **listptr, uschar *eml_filename, BOOL faking) /* send file body to socket */ #ifdef WITH_OLD_CLAMAV_STREAM - if (send(sockData, clamav_fbuf, fsize, 0) < 0) { + if (send(sockData, clamav_fbuf, fsize_uint, 0) < 0) { free(clamav_fbuf); CLOSE_SOCKDATA; return m_errlog_defer_3(scanent, string_sprintf("unable to send file body to socket (%s:%u)", @@ -1262,16 +1279,15 @@ malware_internal(uschar **listptr, uschar *eml_filename, BOOL faking) sock); } #else - send_size = htonl(fsize); + send_size = htonl(fsize_uint); send_final_zeroblock = 0; if ((send(sock, &send_size, sizeof(send_size), 0) < 0) || - (send(sock, clamav_fbuf, fsize, 0) < 0) || + (send(sock, clamav_fbuf, fsize_uint, 0) < 0) || (send(sock, &send_final_zeroblock, sizeof(send_final_zeroblock), 0) < 0)) { free(clamav_fbuf); return m_errlog_defer_3(scanent, - string_sprintf("unable to send file body to socket (%s:%u)", - hostname, port), + string_sprintf("unable to send file body to socket (%s)", hostname), sock); } #endif @@ -1427,9 +1443,9 @@ malware_internal(uschar **listptr, uschar *eml_filename, BOOL faking) if ((sockline_scanner = string_nextinlist(&av_scanner_work, &sep, NULL, 0))) { /* check for no expansions apart from one %s */ - char * s = index(CS sockline_scanner, '%'); + uschar * s = Ustrchr(sockline_scanner, '%'); if (s++) - if ((*s != 's' && *s != '%') || index(s+1, '%')) + if ((*s != 's' && *s != '%') || Ustrchr(s+1, '%')) return m_errlog_defer_3(scanent, US"unsafe sock scanner call spec", sock); }