Merge branch 'master' into dane
[exim.git] / src / src / malware.c
index 7b3453f727439d0ac31087da94cabc4e885fa438..04b5887e7308ca1bf2edff60df3102b61cd2627a 100644 (file)
@@ -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,11 +401,13 @@ 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);
       break;
     }
+    DEBUG(D_lookup) debug_printf("Malware scan: %s\n", scanner_name);
 
     switch (scanent->scancode) {
     case M_FPROTD: /* "f-protd" scanner type -------------------------------- */
@@ -454,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;
@@ -482,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);
 
@@ -499,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);
          }
 
@@ -943,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;
@@ -1029,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
@@ -1231,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,
@@ -1253,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)",
@@ -1261,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