Merge branch 'maint-0.2.4' into maint-0.2.5

This commit is contained in:
Nick Mathewson 2017-02-15 07:47:04 -05:00
commit a452b71395
3 changed files with 48 additions and 19 deletions

10
changes/bug20384 Normal file
View File

@ -0,0 +1,10 @@
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
changes/trove-2017-001.2 Normal file
View File

@ -0,0 +1,8 @@
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.

View File

@ -4301,26 +4301,37 @@ tor_version_compare(tor_version_t *a, tor_version_t *b)
int i; int i;
tor_assert(a); tor_assert(a);
tor_assert(b); tor_assert(b);
if ((i = a->major - b->major))
return i; /* We take this approach to comparison to ensure the same (bogus!) behavior
else if ((i = a->minor - b->minor)) * on all inputs as we would have seen before bug #21278 was fixed. The
return i; * only important difference here is that this method doesn't cause
else if ((i = a->micro - b->micro)) * a signed integer underflow.
return i; */
else if ((i = a->status - b->status)) #define CMP(field) do { \
return i; unsigned aval = (unsigned) a->field; \
else if ((i = a->patchlevel - b->patchlevel)) unsigned bval = (unsigned) b->field; \
return i; int result = (int) (aval - bval); \
else if ((i = strcmp(a->status_tag, b->status_tag))) if (result < 0) \
return i; return -1; \
else if ((i = a->svn_revision - b->svn_revision)) else if (result > 0) \
return i; return 1; \
else if ((i = a->git_tag_len - b->git_tag_len)) } while (0)
return i;
else if (a->git_tag_len) CMP(major);
return fast_memcmp(a->git_tag, b->git_tag, a->git_tag_len); CMP(minor);
CMP(micro);
CMP(status);
CMP(patchlevel);
if ((i = strcmp(a->status_tag, b->status_tag)))
return i;
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 else
return 0; return 0;
#undef CMP
} }
/** Return true iff versions <b>a</b> and <b>b</b> belong to the same series. /** Return true iff versions <b>a</b> and <b>b</b> belong to the same series.