Replace malware_name_buffer with exim-standard allocated space.
authorJeremy Harris <jgh146exb@wizmail.org>
Sun, 19 Jan 2014 22:22:37 +0000 (22:22 +0000)
committerJeremy Harris <jgh146exb@wizmail.org>
Sun, 19 Jan 2014 22:39:48 +0000 (22:39 +0000)
Also lose drweb_match_string, kav_match_string and pre_malware_nb

src/src/malware.c

index 2b4d282331bec752170a8e6c2018aebd3e7cd549..fcb72189ef3d3685f7c9c7d35062f53468b9faef 100644 (file)
@@ -56,7 +56,7 @@ int test_byte_order() {
       return(byte[0] ? LITTLE_MY_ENDIAN : BIG_MY_ENDIAN);
 }
 
-uschar malware_name_buffer[256];
+static uschar * malware_name_internal = NULL;
 int malware_ok = 0;
 
 /* Gross hacks for the -bmalware option; perhaps we should just create
@@ -350,15 +350,11 @@ static int malware_internal(uschar **listptr, uschar *eml_filename, BOOL faking)
         } else if ( detected && (strhelper = Ustrstr(buf, US"<name>")) ) {
           if ((strhelper2 = Ustrstr(buf, US"</name>")) != NULL) {
             *strhelper2 = '\0';
-            Ustrcpy(malware_name_buffer, strhelper + 6);
+           malware_name_internal = string_copy(strhelper+6);
           }
-        } else if ( Ustrstr(buf, US"<summary code=\"") ) {
-          if ( Ustrstr(buf, US"<summary code=\"11\">") ) {
-            malware_name = malware_name_buffer;
-          } else {
-            malware_name = NULL;
-          }
-        }
+        } else if ( Ustrstr(buf, US"<summary code=\"") )
+         malware_name = Ustrstr(buf, US"<summary code=\"11\">")
+           ? malware_name_internal : NULL;
       }
     }
     (void)close(sock);
@@ -374,7 +370,6 @@ static int malware_internal(uschar **listptr, uschar *eml_filename, BOOL faking)
     int sock, result, ovector[30];
     unsigned int port, fsize;
     uschar tmpbuf[1024], *drweb_fbuf;
-    uschar drweb_match_string[128];
     int drweb_rc, drweb_cmd, drweb_flags = 0x0000, drweb_fd,
         drweb_vnum, drweb_slen, drweb_fin = 0x0000;
     unsigned long bread;
@@ -554,16 +549,19 @@ static int malware_internal(uschar **listptr, uschar *eml_filename, BOOL faking)
     if (drweb_vnum)
     {
       int i;
-      uschar pre_malware_nb[256];
-
-      malware_name = malware_name_buffer;
 
       /* setup default virus name */
-      Ustrcpy(malware_name_buffer,"unknown");
+      malware_name_internal = "unknown";
+      malware_name = malware_name_internal;
+
+      /* set up match regex */
+      drweb_re = pcre_compile( "infected\\swith\\s*(.+?)$", PCRE_COPT,
+       (const char **)&rerror, &roffset, NULL );
 
       /* read and concatenate virus names into one string */
       for (i=0;i<drweb_vnum;i++)
       {
+       int size = 0, off = 0;
         /* read the size of report */
         if ((bread = recv(sock, &drweb_slen, sizeof(drweb_slen), 0) != sizeof(drweb_slen))) {
           (void)close(sock);
@@ -582,30 +580,23 @@ static int malware_internal(uschar **listptr, uschar *eml_filename, BOOL faking)
         };
         tmpbuf[drweb_slen] = '\0';
 
-        /* set up match regex, depends on retcode */
-        Ustrcpy(drweb_match_string, "infected\\swith\\s*(.+?)$");
-
-        drweb_re = pcre_compile( CS drweb_match_string,
-          PCRE_COPT,
-          (const char **)&rerror,
-          &roffset,
-          NULL );
-
         /* try matcher on the line, grab substring */
         result = pcre_exec(drweb_re, NULL, CS tmpbuf, Ustrlen(tmpbuf), 0, 0, ovector, 30);
         if (result >= 2) {
-          pcre_copy_substring(CS tmpbuf, ovector, result, 1, CS pre_malware_nb, 255);
-        }
-        /* the first name we just copy to malware_name */
-        if (i==0)
-          Ustrcpy(CS malware_name_buffer, CS pre_malware_nb);
-        else {
-          /* concatenate each new virus name to previous */
-          int slen = Ustrlen(malware_name_buffer);
-          if (slen < (slen+Ustrlen(pre_malware_nb))) {
-            Ustrcat(malware_name_buffer, "/");
-            Ustrcat(malware_name_buffer, pre_malware_nb);
-          }
+         const char * pre_malware_nb;
+
+          pcre_get_substring(CS tmpbuf, ovector, result, 1, &pre_malware_nb);
+
+         /* the first name we just copy to malware_name */
+         if (i==0)
+           malware_name_internal = string_append(NULL, &size, &off,
+                                       1, pre_malware_nb);
+         else
+           /* concatenate each new virus name to previous */
+           malware_name_internal = string_append(malware_name_internal,
+                                       &size, &off, 2, "/", pre_malware_nb);
+
+         pcre_free_substring(pre_malware_nb);
         }
       }
     }
@@ -705,9 +696,9 @@ static int malware_internal(uschar **listptr, uschar *eml_filename, BOOL faking)
   } else if (Ustrncmp(buf,"322",3) == 0) {
           uschar *p = Ustrchr(&buf[4],' ');
           *p = '\0';
-          Ustrcpy(malware_name_buffer,&buf[4]);
-          malware_name = malware_name_buffer;
-  };
+          malware_name_internal = string_copy(&buf[4]);
+          malware_name = malware_name_internal;
+       }
       }
 
       /* prepare our command */
@@ -845,8 +836,9 @@ static int malware_internal(uschar **listptr, uschar *eml_filename, BOOL faking)
           i = pcre_exec(fs_inf, NULL, CS av_buffer, Ustrlen(av_buffer), 0, 0, ovector, 30);
           if (i >= 2) {
             /* Got it */
-            pcre_copy_substring(CS av_buffer, ovector, i, 1, CS malware_name_buffer, 255);
-            malware_name = malware_name_buffer;
+            pcre_get_substring(CS av_buffer, ovector, i, 1,
+                               (const char **) &malware_name_internal);
+            malware_name = malware_name_internal;
           };
         };
       }
@@ -865,7 +857,6 @@ static int malware_internal(uschar **listptr, uschar *eml_filename, BOOL faking)
       time_t t;
       uschar tmpbuf[1024];
       uschar scanrequest[1024];
-      uschar kav_match_string[128];
       int kav_rc;
       unsigned long kav_reportlen, bread;
       pcre *kav_re;
@@ -970,8 +961,8 @@ static int malware_internal(uschar **listptr, uschar *eml_filename, BOOL faking)
         int report_flag = 0;
 
         /* setup default virus name */
-        Ustrcpy(malware_name_buffer,"unknown");
-        malware_name = malware_name_buffer;
+        malware_name_internal = "unknown";
+        malware_name = malware_name_internal;
 
         if (test_byte_order() == LITTLE_MY_ENDIAN) {
           report_flag = tmpbuf[1];
@@ -994,12 +985,9 @@ static int malware_internal(uschar **listptr, uschar *eml_filename, BOOL faking)
           reportsize is 0 (!?) */
           if (kav_reportlen > 0) {
             /* set up match regex, depends on retcode */
-            if( kav_rc == 3 )
-              Ustrcpy(kav_match_string, "suspicion:\\s*(.+?)\\s*$");
-            else
-              Ustrcpy(kav_match_string, "infected:\\s*(.+?)\\s*$");
-
-            kav_re = pcre_compile( CS kav_match_string,
+            kav_re = pcre_compile( kav_rc == 3
+                                  ? "suspicion:\\s*(.+?)\\s*$"
+                                  : "infected:\\s*(.+?)\\s*$",
                                    PCRE_COPT,
                                    (const char **)&rerror,
                                    &roffset,
@@ -1022,7 +1010,8 @@ static int malware_internal(uschar **listptr, uschar *eml_filename, BOOL faking)
               /* try matcher on the line, grab substring */
               result = pcre_exec(kav_re, NULL, CS tmpbuf, Ustrlen(tmpbuf), 0, 0, ovector, 30);
               if (result >= 2) {
-                pcre_copy_substring(CS tmpbuf, ovector, result, 1, CS malware_name_buffer, 255);
+                pcre_get_substring(CS tmpbuf, ovector, result, 1,
+                                   (const char **) &malware_name_internal);
                 break;
               };
             };
@@ -1187,17 +1176,16 @@ static int malware_internal(uschar **listptr, uschar *eml_filename, BOOL faking)
 
       if (trigger) {
         /* setup default virus name */
-        Ustrcpy(malware_name_buffer,"unknown");
-        malware_name = malware_name_buffer;
+       malware_name = US"unknown";
 
         /* re-open the scanner output file, look for name match */
         scanner_record = fopen(CS file_name,"rb");
         while(fgets(CS linebuffer,32767,scanner_record) != NULL) {
           /* try match */
           result = pcre_exec(cmdline_regex_re, NULL, CS linebuffer, Ustrlen(linebuffer), 0, 0, ovector, 30);
-          if (result >= 2) {
-            pcre_copy_substring(CS linebuffer, ovector, result, 1, CS malware_name_buffer, 255);
-          };
+          if (result >= 2)
+            pcre_get_substring(CS linebuffer, ovector, result, 1,
+                               (const char **) &malware_name_internal);
         };
         (void)fclose(scanner_record);
       }
@@ -1284,8 +1272,8 @@ static int malware_internal(uschar **listptr, uschar *eml_filename, BOOL faking)
       /* infected ? */
       if (av_buffer[0] == '1') {
         if (Ustrchr(av_buffer, '\n')) *Ustrchr(av_buffer, '\n') = '\0';
-        Ustrcpy(malware_name_buffer,&av_buffer[2]);
-        malware_name = malware_name_buffer;
+        malware_name_internal = string_copy(&av_buffer[2]);
+        malware_name = malware_name_internal;
       }
       else if (!strncmp(CS av_buffer, "-1", 2)) {
         log_write(0, LOG_MAIN|LOG_PANIC,
@@ -1712,6 +1700,7 @@ try_next_server:
                   "malware acl condition: clamd: buffer too small");
         return DEFER;
       }
+      /* We're now assured of a NULL at the end of av_buffer */
 
       /* Check the result. ClamAV returns one of two result formats.
       In the basic mode, the response is of the form:
@@ -1785,8 +1774,8 @@ try_next_server:
          if (p)
            *p = '\0';
        }
-       Ustrncpy(malware_name_buffer, vname, sizeof(malware_name_buffer)-1);
-       malware_name = malware_name_buffer;
+       malware_name_internal = string_copy(vname);
+       malware_name = malware_name_internal;
        DEBUG(D_acl) debug_printf("Malware found, name \"%s\"\n", malware_name);
 
       } else if (Ustrcmp(result_tag, "ERROR") == 0) {
@@ -1982,11 +1971,11 @@ static int mksd_parse_line (char *line)
       /* VIR */
       if ((p = strchr (line, '\n')) != NULL) {
         (*p) = '\0';
-        if (((p-line) > 5) && ((p-line) < sizeof (malware_name_buffer)) && (line[3] == ' '))
+        if (((p-line) > 5) && (line[3] == ' '))
           if (((p = strchr (line+4, ' ')) != NULL) && ((p-line) > 4)) {
-            (*p) = '\0';
-            Ustrcpy (malware_name_buffer, line+4);
-      malware_name = malware_name_buffer;
+            *p = '\0';
+            malware_name_internal = string_copy(line+4);
+           malware_name = malware_name_internal;
             return OK;
           }
       }