Explorar el Código

Ensure that bw_file_headers is not bigger than max

juga0 hace 5 años
padre
commit
8164534f46
Se han modificado 3 ficheros con 24 adiciones y 10 borrados
  1. 16 7
      src/feature/dirauth/dirvote.c
  2. 3 0
      src/feature/dirauth/dirvote.h
  3. 5 3
      src/feature/dircache/dirserv.c

+ 16 - 7
src/feature/dirauth/dirvote.c

@@ -254,7 +254,7 @@ format_networkstatus_vote(crypto_pk_t *private_signing_key,
     /* XXXX Abstraction violation: should be pulling a field out of v3_ns.*/
     char *flag_thresholds = dirserv_get_flag_thresholds_line();
     char *params;
-    char *bw_file_headers;
+    char *bw_file_headers = NULL;
     authority_cert_t *cert = v3_ns->cert;
     char *methods =
       make_consensus_method_list(MIN_SUPPORTED_CONSENSUS_METHOD,
@@ -269,11 +269,19 @@ format_networkstatus_vote(crypto_pk_t *private_signing_key,
     else
       params = tor_strdup("");
     tor_assert(cert);
-    if (v3_ns->bw_file_headers)
-      bw_file_headers = smartlist_join_strings(v3_ns->bw_file_headers, " ", 0,
-                                              NULL);
-    else
-      bw_file_headers = tor_strdup("");
+
+    if (v3_ns->bw_file_headers) {
+      if (! BUG(smartlist_len(v3_ns->bw_file_headers)
+                > MAX_BW_FILE_HEADER_COUNT_IN_VOTE)) {
+        bw_file_headers = smartlist_join_strings(v3_ns->bw_file_headers, " ",
+                                                 0, NULL);
+        if (BUG(strlen(bw_file_headers) > MAX_BW_FILE_HEADERS_LINE_LEN)) {
+          /* Free and set to NULL, so the vote header line is empty */
+          tor_free(bw_file_headers);
+        }
+      }
+    }
+
     smartlist_add_asprintf(chunks,
                  "network-status-version 3\n"
                  "vote-status %s\n"
@@ -309,7 +317,8 @@ format_networkstatus_vote(crypto_pk_t *private_signing_key,
                  voter->contact,
                  shared_random_vote_str ?
                            shared_random_vote_str : "",
-                 bw_file_headers);
+                 bw_file_headers ?
+                           bw_file_headers : "");
 
     tor_free(params);
     tor_free(flags);

+ 3 - 0
src/feature/dirauth/dirvote.h

@@ -89,6 +89,9 @@
 #define DGV_INCLUDE_PENDING 2
 #define DGV_INCLUDE_PREVIOUS 4
 
+/** Maximum size of a line in a vote. */
+#define MAX_BW_FILE_HEADERS_LINE_LEN 1024
+
 /*
  * Public API. Used outside of the dirauth subsystem.
  *

+ 5 - 3
src/feature/dircache/dirserv.c

@@ -2679,17 +2679,19 @@ dirserv_read_measured_bandwidths(const char *from_file,
           applied_lines++;
       /* if the terminator is found, it is the end of header lines, set the
        * flag but do not store anything */
-      } else if (strcmp(line, BW_FILE_TERMINATOR) == 0)
+      } else if (strcmp(line, BW_FILE_HEADERS_TERMINATOR) == 0) {
         line_is_after_headers = 1;
       /* if the line was not a correct relay line nor the terminator and
        * the end of the header lines has not been detected yet
        * and it is key_value and bw_file_headers did not reach the maximum
        * number of headers,
        * then assume this line is a header and add it to bw_file_headers */
-      else if (bw_file_headers &&
+      } else if (bw_file_headers &&
               (line_is_after_headers == 0) &&
               string_is_key_value(LOG_DEBUG, line) &&
-              (smartlist_len(bw_file_headers) < MAX_BW_FILE_HEADERS_LEN)) {
+              !strchr(line, ' ') &&
+              (smartlist_len(bw_file_headers)
+               < MAX_BW_FILE_HEADER_COUNT_IN_VOTE)) {
         line[strlen(line)-1] = '\0';
         smartlist_add_strdup(bw_file_headers, line);
       };