mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-12-06 19:41:15 +01:00
Merge branch 'maint-0.3.5' into release-0.3.5
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
o Minor features (address selection):
|
||||
- Make Tor aware of the RFC 6598 (Carrier Grade NAT) IP range, which is the
|
||||
subnet 100.64.0.0/10. This is deployed by many ISPs as an alternative to
|
||||
RFC 1918 that does not break existing internal networks. This patch fixes
|
||||
security issues caused by RFC 6518 by blocking control ports on these
|
||||
addresses and warns users if client ports or ExtORPorts are listening on
|
||||
a RFC 6598 address. Closes ticket 28525. Patch by Neel Chauhan.
|
||||
@@ -0,0 +1,5 @@
|
||||
o Minor bugfixes (hardening):
|
||||
- Verify in more places that we are not about to create a buffer
|
||||
with more than INT_MAX bytes, to avoid possible OOB access in the event
|
||||
of bugs. Fixes bug 30041; bugfix on 0.2.0.16. Found and fixed by
|
||||
Tobias Stoeckmann.
|
||||
@@ -0,0 +1,6 @@
|
||||
o Minor bugfixes (portability):
|
||||
- Avoid crashing in our tor_vasprintf() implementation on systems that
|
||||
define neither vasprintf() nor _vscprintf(). (This bug has been here
|
||||
long enough that we question whether people are running Tor on such
|
||||
systems, but we're applying the fix out of caution.) Fixes bug 30561;
|
||||
bugfix on 0.2.8.2-alpha. Found and fixed by Tobias Stoeckmann.
|
||||
@@ -0,0 +1,4 @@
|
||||
o Minor bugfixes (directory authorities):
|
||||
- Stop crashing after parsing an unknown descriptor purpose annotation.
|
||||
We think this bug can only be triggered by modifying a local file.
|
||||
Fixes bug 30781; bugfix on 0.2.0.8-alpha.
|
||||
@@ -0,0 +1,9 @@
|
||||
o Minor bugfixes (compilation):
|
||||
- Avoid using labs() on time_t, which can cause compilation warnings
|
||||
on 64-bit Windows builds. Fixes bug 31343; bugfix on 0.2.4.4-alpha.
|
||||
|
||||
o Minor bugfixes (clock skew detection):
|
||||
- Don't believe clock skew results from NETINFO cells that appear to
|
||||
arrive before the VERSIONS cells they are responding to were sent.
|
||||
Previously, we would accept them up to 3 minutes "in the past".
|
||||
Fixes bug 31343; bugfix on 0.2.4.4-alpha.
|
||||
@@ -0,0 +1,4 @@
|
||||
o Minor bugfixes (compilation warning):
|
||||
- Fix a compilation warning on Windows about casting a function
|
||||
pointer for GetTickCount64(). Fixes bug 31374; bugfix on
|
||||
0.2.9.1-alpha.
|
||||
@@ -3759,6 +3759,10 @@ connection_buf_read_from_socket(connection_t *conn, ssize_t *max_to_read,
|
||||
if (conn->linked_conn) {
|
||||
result = buf_move_to_buf(conn->inbuf, conn->linked_conn->outbuf,
|
||||
&conn->linked_conn->outbuf_flushlen);
|
||||
if (BUG(result<0)) {
|
||||
log_warn(LD_BUG, "reading from linked connection buffer failed.");
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
result = 0;
|
||||
}
|
||||
|
||||
@@ -1637,7 +1637,19 @@ channel_tls_process_padding_negotiate_cell(cell_t *cell, channel_tls_t *chan)
|
||||
}
|
||||
|
||||
/**
|
||||
* Process a 'netinfo' cell.
|
||||
* Helper: compute the absolute value of a time_t.
|
||||
*
|
||||
* (we need this because labs() doesn't always work for time_t, since
|
||||
* long can be shorter than time_t.)
|
||||
*/
|
||||
static inline time_t
|
||||
time_abs(time_t val)
|
||||
{
|
||||
return (val < 0) ? -val : val;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process a 'netinfo' cell
|
||||
*
|
||||
* This function is called to handle an incoming NETINFO cell; read and act
|
||||
* on its contents, and set the connection state to "open".
|
||||
@@ -1654,7 +1666,7 @@ channel_tls_process_netinfo_cell(cell_t *cell, channel_tls_t *chan)
|
||||
time_t now = time(NULL);
|
||||
const routerinfo_t *me = router_get_my_routerinfo();
|
||||
|
||||
long apparent_skew = 0;
|
||||
time_t apparent_skew = 0;
|
||||
tor_addr_t my_apparent_addr = TOR_ADDR_NULL;
|
||||
int started_here = 0;
|
||||
const char *identity_digest = NULL;
|
||||
@@ -1721,7 +1733,11 @@ channel_tls_process_netinfo_cell(cell_t *cell, channel_tls_t *chan)
|
||||
|
||||
/* Decode the cell. */
|
||||
timestamp = ntohl(get_uint32(cell->payload));
|
||||
if (labs(now - chan->conn->handshake_state->sent_versions_at) < 180) {
|
||||
const time_t sent_versions_at =
|
||||
chan->conn->handshake_state->sent_versions_at;
|
||||
if (now > sent_versions_at && (now - sent_versions_at) < 180) {
|
||||
/* If we have gotten the NETINFO cell reasonably soon after having
|
||||
* sent our VERSIONS cell, maybe we can learn skew information from it. */
|
||||
apparent_skew = now - timestamp;
|
||||
}
|
||||
|
||||
@@ -1801,7 +1817,7 @@ channel_tls_process_netinfo_cell(cell_t *cell, channel_tls_t *chan)
|
||||
/* Act on apparent skew. */
|
||||
/** Warn when we get a netinfo skew with at least this value. */
|
||||
#define NETINFO_NOTICE_SKEW 3600
|
||||
if (labs(apparent_skew) > NETINFO_NOTICE_SKEW &&
|
||||
if (time_abs(apparent_skew) > NETINFO_NOTICE_SKEW &&
|
||||
(started_here ||
|
||||
connection_or_digest_is_known_relay(chan->conn->identity_digest))) {
|
||||
int trusted = router_digest_is_trusted_dir(chan->conn->identity_digest);
|
||||
|
||||
@@ -556,6 +556,9 @@ router_parse_entry_from_string(const char *s, const char *end,
|
||||
if ((tok = find_opt_by_keyword(tokens, A_PURPOSE))) {
|
||||
tor_assert(tok->n_args);
|
||||
router->purpose = router_purpose_from_string(tok->args[0]);
|
||||
if (router->purpose == ROUTER_PURPOSE_UNKNOWN) {
|
||||
goto err;
|
||||
}
|
||||
} else {
|
||||
router->purpose = ROUTER_PURPOSE_GENERAL;
|
||||
}
|
||||
|
||||
@@ -2856,7 +2856,7 @@ int
|
||||
router_differences_are_cosmetic(const routerinfo_t *r1, const routerinfo_t *r2)
|
||||
{
|
||||
time_t r1pub, r2pub;
|
||||
long time_difference;
|
||||
time_t time_difference;
|
||||
tor_assert(r1 && r2);
|
||||
|
||||
/* r1 should be the one that was published first. */
|
||||
@@ -2920,7 +2920,9 @@ router_differences_are_cosmetic(const routerinfo_t *r1, const routerinfo_t *r2)
|
||||
* give or take some slop? */
|
||||
r1pub = r1->cache_info.published_on;
|
||||
r2pub = r2->cache_info.published_on;
|
||||
time_difference = labs(r2->uptime - (r1->uptime + (r2pub - r1pub)));
|
||||
time_difference = r2->uptime - (r1->uptime + (r2pub - r1pub));
|
||||
if (time_difference < 0)
|
||||
time_difference = - time_difference;
|
||||
if (time_difference > ROUTER_ALLOW_UPTIME_DRIFT &&
|
||||
time_difference > r1->uptime * .05 &&
|
||||
time_difference > r2->uptime * .05)
|
||||
|
||||
@@ -283,7 +283,7 @@ buf_t *
|
||||
buf_new_with_data(const char *cp, size_t sz)
|
||||
{
|
||||
/* Validate arguments */
|
||||
if (!cp || sz <= 0) {
|
||||
if (!cp || sz <= 0 || sz >= INT_MAX) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -657,7 +657,7 @@ buf_move_to_buf(buf_t *buf_out, buf_t *buf_in, size_t *buf_flushlen)
|
||||
char b[4096];
|
||||
size_t cp, len;
|
||||
|
||||
if (BUG(buf_out->datalen >= INT_MAX))
|
||||
if (BUG(buf_out->datalen >= INT_MAX || *buf_flushlen >= INT_MAX))
|
||||
return -1;
|
||||
if (BUG(buf_out->datalen >= INT_MAX - *buf_flushlen))
|
||||
return -1;
|
||||
@@ -689,6 +689,10 @@ buf_move_all(buf_t *buf_out, buf_t *buf_in)
|
||||
tor_assert(buf_out);
|
||||
if (!buf_in)
|
||||
return;
|
||||
if (BUG(buf_out->datalen >= INT_MAX || buf_in->datalen >= INT_MAX))
|
||||
return;
|
||||
if (BUG(buf_out->datalen >= INT_MAX - buf_in->datalen))
|
||||
return;
|
||||
|
||||
if (buf_out->head == NULL) {
|
||||
buf_out->head = buf_in->head;
|
||||
@@ -756,6 +760,7 @@ buf_find_pos_of_char(char ch, buf_pos_t *out)
|
||||
static inline int
|
||||
buf_pos_inc(buf_pos_t *pos)
|
||||
{
|
||||
tor_assert(pos->pos < INT_MAX - 1);
|
||||
++pos->pos;
|
||||
if (pos->pos == (off_t)pos->chunk->datalen) {
|
||||
if (!pos->chunk->next)
|
||||
@@ -836,6 +841,7 @@ buf_find_offset_of_char(buf_t *buf, char ch)
|
||||
{
|
||||
chunk_t *chunk;
|
||||
off_t offset = 0;
|
||||
tor_assert(buf->datalen < INT_MAX);
|
||||
for (chunk = buf->head; chunk; chunk = chunk->next) {
|
||||
char *cp = memchr(chunk->data, ch, chunk->datalen);
|
||||
if (cp)
|
||||
@@ -905,6 +911,7 @@ buf_assert_ok(buf_t *buf)
|
||||
for (ch = buf->head; ch; ch = ch->next) {
|
||||
total += ch->datalen;
|
||||
tor_assert(ch->datalen <= ch->memlen);
|
||||
tor_assert(ch->datalen < INT_MAX);
|
||||
tor_assert(ch->data >= &ch->mem[0]);
|
||||
tor_assert(ch->data <= &ch->mem[0]+ch->memlen);
|
||||
if (ch->data == &ch->mem[0]+ch->memlen) {
|
||||
|
||||
+15
-4
@@ -236,9 +236,18 @@ tor_addr_make_null(tor_addr_t *a, sa_family_t family)
|
||||
a->family = family;
|
||||
}
|
||||
|
||||
/** Return true iff <b>ip</b> is an IP reserved to localhost or local networks
|
||||
* in RFC1918 or RFC4193 or RFC4291. (fec0::/10, deprecated by RFC3879, is
|
||||
* also treated as internal for now.)
|
||||
/** Return true iff <b>ip</b> is an IP reserved to localhost or local networks.
|
||||
*
|
||||
* If <b>ip</b> is in RFC1918 or RFC4193 or RFC4291, we will return true.
|
||||
* (fec0::/10, deprecated by RFC3879, is also treated as internal for now
|
||||
* and will return true.)
|
||||
*
|
||||
* If <b>ip</b> is 0.0.0.0 or 100.64.0.0/10 (RFC6598), we will act as:
|
||||
* - Internal if <b>for_listening</b> is 0, as these addresses are not
|
||||
* routable on the internet and we won't be publicly accessible to clients.
|
||||
* - External if <b>for_listening</b> is 1, as clients could connect to us
|
||||
* from the internet (in the case of 0.0.0.0) or a service provider's
|
||||
* internal network (in the case of RFC6598).
|
||||
*/
|
||||
int
|
||||
tor_addr_is_internal_(const tor_addr_t *addr, int for_listening,
|
||||
@@ -286,11 +295,13 @@ tor_addr_is_internal_(const tor_addr_t *addr, int for_listening,
|
||||
|
||||
return 0;
|
||||
} else if (v_family == AF_INET) {
|
||||
if (for_listening && !iph4) /* special case for binding to 0.0.0.0 */
|
||||
/* special case for binding to 0.0.0.0 or 100.64/10 (RFC6598) */
|
||||
if (for_listening && (!iph4 || ((iph4 & 0xffc00000) == 0x64400000)))
|
||||
return 0;
|
||||
if (((iph4 & 0xff000000) == 0x0a000000) || /* 10/8 */
|
||||
((iph4 & 0xff000000) == 0x00000000) || /* 0/8 */
|
||||
((iph4 & 0xff000000) == 0x7f000000) || /* 127/8 */
|
||||
((iph4 & 0xffc00000) == 0x64400000) || /* 100.64/10 */
|
||||
((iph4 & 0xffff0000) == 0xa9fe0000) || /* 169.254/16 */
|
||||
((iph4 & 0xfff00000) == 0xac100000) || /* 172.16/12 */
|
||||
((iph4 & 0xffff0000) == 0xc0a80000)) /* 192.168/16 */
|
||||
|
||||
+13
-3
@@ -131,14 +131,24 @@ tor_vasprintf(char **strp, const char *fmt, va_list args)
|
||||
* characters we need. We give it a try on a short buffer first, since
|
||||
* it might be nice to avoid the second vsnprintf call.
|
||||
*/
|
||||
/* XXXX This code spent a number of years broken (see bug 30651). It is
|
||||
* possible that no Tor users actually run on systems without vasprintf() or
|
||||
* _vscprintf(). If so, we should consider removing this code. */
|
||||
char buf[128];
|
||||
int len, r;
|
||||
va_list tmp_args;
|
||||
va_copy(tmp_args, args);
|
||||
/* vsnprintf() was properly checked but tor_vsnprintf() available so
|
||||
* why not use it? */
|
||||
len = tor_vsnprintf(buf, sizeof(buf), fmt, tmp_args);
|
||||
/* Use vsnprintf to retrieve needed length. tor_vsnprintf() is not an
|
||||
* option here because it will simply return -1 if buf is not large enough
|
||||
* to hold the complete string.
|
||||
*/
|
||||
len = vsnprintf(buf, sizeof(buf), fmt, tmp_args);
|
||||
va_end(tmp_args);
|
||||
buf[sizeof(buf) - 1] = '\0';
|
||||
if (len < 0) {
|
||||
*strp = NULL;
|
||||
return -1;
|
||||
}
|
||||
if (len < (int)sizeof(buf)) {
|
||||
*strp = tor_strdup(buf);
|
||||
return len;
|
||||
|
||||
@@ -519,7 +519,7 @@ monotime_init_internal(void)
|
||||
|
||||
HANDLE h = load_windows_system_library(TEXT("kernel32.dll"));
|
||||
if (h) {
|
||||
GetTickCount64_fn = (GetTickCount64_fn_t)
|
||||
GetTickCount64_fn = (GetTickCount64_fn_t) (void(*)(void))
|
||||
GetProcAddress(h, "GetTickCount64");
|
||||
}
|
||||
// FreeLibrary(h) ?
|
||||
|
||||
@@ -1189,6 +1189,23 @@ test_addr_make_null(void *data)
|
||||
tor_free(zeros);
|
||||
}
|
||||
|
||||
#define TEST_ADDR_INTERNAL(a, for_listening, rv) STMT_BEGIN \
|
||||
tor_addr_t t; \
|
||||
tt_int_op(tor_inet_pton(AF_INET, a, &t.addr.in_addr), OP_EQ, 1); \
|
||||
t.family = AF_INET; \
|
||||
tt_int_op(tor_addr_is_internal(&t, for_listening), OP_EQ, rv); \
|
||||
STMT_END;
|
||||
|
||||
static void
|
||||
test_addr_rfc6598(void *arg)
|
||||
{
|
||||
(void)arg;
|
||||
TEST_ADDR_INTERNAL("100.64.0.1", 0, 1);
|
||||
TEST_ADDR_INTERNAL("100.64.0.1", 1, 0);
|
||||
done:
|
||||
;
|
||||
}
|
||||
|
||||
#define ADDR_LEGACY(name) \
|
||||
{ #name, test_addr_ ## name , 0, NULL, NULL }
|
||||
|
||||
@@ -1203,5 +1220,6 @@ struct testcase_t addr_tests[] = {
|
||||
{ "sockaddr_to_str", test_addr_sockaddr_to_str, 0, NULL, NULL },
|
||||
{ "is_loopback", test_addr_is_loopback, 0, NULL, NULL },
|
||||
{ "make_null", test_addr_make_null, 0, NULL, NULL },
|
||||
{ "rfc6598", test_addr_rfc6598, 0, NULL, NULL },
|
||||
END_OF_TESTCASES
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user