Commit 2afdf8de authored by Nick Mathewson's avatar Nick Mathewson 🐚
Browse files

Merge branch 'maint-0.2.4' into release-0.2.4

parents 92f8b56e 194e3105
Loading
Loading
Loading
Loading

changes/bug20384

0 → 100644
+10 −0
Original line number Diff line number Diff line
  o Major features (security fixes):
    - Prevent a class of security bugs caused by treating the contents
      of a buffer chunk as if they were a NUL-terminated string. At
      least one such bug seems to be present in all currently used
      versions of Tor, and would allow an attacker to remotely crash
      most Tor instances, especially those compiled with extra compiler
      hardening. With this defense in place, such bugs can't crash Tor,
      though we should still fix them as they occur. Closes ticket
      20384 (TROVE-2016-10-001).
+8 −0
Original line number Diff line number Diff line
  o Major bugfixes (parsing):
    - Fix an integer underflow bug when comparing malformed Tor versions.
      This bug is harmless, except when Tor has been built with
      --enable-expensive-hardening, which would turn it into a crash;
      or on Tor 0.2.9.1-alpha through Tor 0.2.9.8, which were built with
      -ftrapv by default.
      Part of TROVE-2017-001. Fixes bug 21278; bugfix on
      0.0.8pre1. Found by OSS-Fuzz.
+30 −19
Original line number Diff line number Diff line
@@ -4545,26 +4545,37 @@ tor_version_compare(tor_version_t *a, tor_version_t *b)
  int i;
  tor_assert(a);
  tor_assert(b);
  if ((i = a->major - b->major))
    return i;
  else if ((i = a->minor - b->minor))
    return i;
  else if ((i = a->micro - b->micro))
    return i;
  else if ((i = a->status - b->status))
    return i;
  else if ((i = a->patchlevel - b->patchlevel))
    return i;
  else if ((i = strcmp(a->status_tag, b->status_tag)))
    return i;
  else if ((i = a->svn_revision - b->svn_revision))
    return i;
  else if ((i = a->git_tag_len - b->git_tag_len))

  /* We take this approach to comparison to ensure the same (bogus!) behavior
   * on all inputs as we would have seen before bug #21278 was fixed. The
   * only important difference here is that this method doesn't cause
   * a signed integer underflow.
   */
#define CMP(field) do {                               \
    unsigned aval = (unsigned) a->field;              \
    unsigned bval = (unsigned) b->field;              \
    int result = (int) (aval - bval);                 \
    if (result < 0)                                   \
      return -1;                                      \
    else if (result > 0)                              \
      return 1;                                       \
  } while (0)

  CMP(major);
  CMP(minor);
  CMP(micro);
  CMP(status);
  CMP(patchlevel);
  if ((i = strcmp(a->status_tag, b->status_tag)))
     return i;
  else if (a->git_tag_len)
  CMP(svn_revision);
  CMP(git_tag_len);
  if (a->git_tag_len)
     return fast_memcmp(a->git_tag, b->git_tag, a->git_tag_len);
  else
     return 0;

#undef CMP
}

/** Return true iff versions <b>a</b> and <b>b</b> belong to the same series.