Merge branch 'maint-0.2.7' into maint-0.2.8

This commit is contained in:
Nick Mathewson 2017-02-15 07:47:28 -05:00
commit 1ebdae6171
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

@ -4848,26 +4848,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))
return i;
else if (a->git_tag_len)
return fast_memcmp(a->git_tag, b->git_tag, a->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;
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;
return 0;
#undef CMP
}
/** Return true iff versions <b>a</b> and <b>b</b> belong to the same series.