aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoger Dingledine <arma@torproject.org>2012-09-11 13:57:24 -0400
committerRoger Dingledine <arma@torproject.org>2012-09-11 13:57:24 -0400
commitd204b04298952373d3f6f89e7153ceeb17053b1c (patch)
treee9bbdd6ca68c281466438e619f4cefe40cddd7f8
parent2a824b942a82818a794f85e0784d77c7dd3bbfef (diff)
parent84f47ffc462dface8db1def322414daa43400d1c (diff)
downloadtor-d204b04298952373d3f6f89e7153ceeb17053b1c.tar.gz
tor-d204b04298952373d3f6f89e7153ceeb17053b1c.zip
Merge branch 'maint-0.2.2' into release-0.2.2
-rw-r--r--changes/bug66907
-rw-r--r--changes/bug68115
-rw-r--r--src/common/util.c27
-rw-r--r--src/common/util.h2
-rw-r--r--src/or/directory.c3
-rw-r--r--src/or/dirvote.c6
-rw-r--r--src/or/policies.c6
-rw-r--r--src/test/test_util.c13
8 files changed, 50 insertions, 19 deletions
diff --git a/changes/bug6690 b/changes/bug6690
new file mode 100644
index 0000000000..99d42976ed
--- /dev/null
+++ b/changes/bug6690
@@ -0,0 +1,7 @@
+ o Major bugfixes (security):
+ - Do not crash when comparing an address with port value 0 to an
+ address policy. This bug could have been used to cause a remote
+ assertion failure by or against directory authorities, or to
+ allow some applications to crash clients. Fixes bug 6690; bugfix
+ on 0.2.1.10-alpha.
+
diff --git a/changes/bug6811 b/changes/bug6811
new file mode 100644
index 0000000000..841ec1c54a
--- /dev/null
+++ b/changes/bug6811
@@ -0,0 +1,5 @@
+ o Major security fixes:
+ - Fix an assertion failure in tor_timegm that could be triggered
+ by a badly formatted directory object. Bug found by fuzzing with
+ Radamsa. Fixes bug 6811; bugfix on 0.2.0.20-rc.
+
diff --git a/src/common/util.c b/src/common/util.c
index a03a576321..698f989ec1 100644
--- a/src/common/util.c
+++ b/src/common/util.c
@@ -1212,11 +1212,11 @@ n_leapdays(int y1, int y2)
static const int days_per_month[] =
{ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
-/** Return a time_t given a struct tm. The result is given in GMT, and
- * does not account for leap seconds.
+/** Compute a time_t given a struct tm. The result is given in GMT, and
+ * does not account for leap seconds. Return 0 on success, -1 on failure.
*/
-time_t
-tor_timegm(struct tm *tm)
+int
+tor_timegm(const struct tm *tm, time_t *time_out)
{
/* This is a pretty ironclad timegm implementation, snarfed from Python2.2.
* It's way more brute-force than fiddling with tzset().
@@ -1224,11 +1224,11 @@ tor_timegm(struct tm *tm)
time_t year, days, hours, minutes, seconds;
int i;
year = tm->tm_year + 1900;
- if (year < 1970 || tm->tm_mon < 0 || tm->tm_mon > 11) {
+ if (year < 1970 || tm->tm_mon < 0 || tm->tm_mon > 11 ||
+ tm->tm_year >= INT32_MAX-1900) {
log_warn(LD_BUG, "Out-of-range argument to tor_timegm");
return -1;
}
- tor_assert(year < INT_MAX);
days = 365 * (year-1970) + n_leapdays(1970,(int)year);
for (i = 0; i < tm->tm_mon; ++i)
days += days_per_month[i];
@@ -1239,7 +1239,8 @@ tor_timegm(struct tm *tm)
minutes = hours*60 + tm->tm_min;
seconds = minutes*60 + tm->tm_sec;
- return seconds;
+ *time_out = seconds;
+ return 0;
}
/* strftime is locale-specific, so we need to replace those parts */
@@ -1299,7 +1300,7 @@ parse_rfc1123_time(const char *buf, time_t *t)
return -1;
}
if (tm_mday < 1 || tm_mday > 31 || tm_hour > 23 || tm_min > 59 ||
- tm_sec > 60) {
+ tm_sec > 60 || tm_year >= INT32_MAX || tm_year < 1970) {
char *esc = esc_for_log(buf);
log_warn(LD_GENERAL, "Got invalid RFC1123 time %s", esc);
tor_free(esc);
@@ -1335,8 +1336,7 @@ parse_rfc1123_time(const char *buf, time_t *t)
}
tm.tm_year -= 1900;
- *t = tor_timegm(&tm);
- return 0;
+ return tor_timegm(&tm, t);
}
/** Set <b>buf</b> to the ISO8601 encoding of the local value of <b>t</b>.
@@ -1378,13 +1378,13 @@ parse_iso_time(const char *cp, time_t *t)
return -1;
}
if (year < 1970 || month < 1 || month > 12 || day < 1 || day > 31 ||
- hour > 23 || minute > 59 || second > 60) {
+ hour > 23 || minute > 59 || second > 60 || year >= INT32_MAX) {
char *esc = esc_for_log(cp);
log_warn(LD_GENERAL, "ISO time %s was nonsensical", esc);
tor_free(esc);
return -1;
}
- st_tm.tm_year = year-1900;
+ st_tm.tm_year = (int)year-1900;
st_tm.tm_mon = month-1;
st_tm.tm_mday = day;
st_tm.tm_hour = hour;
@@ -1397,8 +1397,7 @@ parse_iso_time(const char *cp, time_t *t)
tor_free(esc);
return -1;
}
- *t = tor_timegm(&st_tm);
- return 0;
+ return tor_timegm(&st_tm, t);
}
/** Given a <b>date</b> in one of the three formats allowed by HTTP (ugh),
diff --git a/src/common/util.h b/src/common/util.h
index d4771562ee..75de3422d7 100644
--- a/src/common/util.h
+++ b/src/common/util.h
@@ -232,7 +232,7 @@ int64_t tv_to_msec(const struct timeval *tv);
int64_t tv_to_usec(const struct timeval *tv);
long tv_udiff(const struct timeval *start, const struct timeval *end);
long tv_mdiff(const struct timeval *start, const struct timeval *end);
-time_t tor_timegm(struct tm *tm);
+int tor_timegm(const struct tm *tm, time_t *time_out);
#define RFC1123_TIME_LEN 29
void format_rfc1123_time(char *buf, time_t t);
int parse_rfc1123_time(const char *buf, time_t *t);
diff --git a/src/or/directory.c b/src/or/directory.c
index 29cf10cea0..975f8910cd 100644
--- a/src/or/directory.c
+++ b/src/or/directory.c
@@ -2493,7 +2493,8 @@ directory_handle_command_get(dir_connection_t *conn, const char *headers,
if ((header = http_get_header(headers, "If-Modified-Since: "))) {
struct tm tm;
if (parse_http_time(header, &tm) == 0) {
- if_modified_since = tor_timegm(&tm);
+ if (tor_timegm(&tm, &if_modified_since)<0)
+ if_modified_since = 0;
}
/* The correct behavior on a malformed If-Modified-Since header is to
* act as if no If-Modified-Since header had been given. */
diff --git a/src/or/dirvote.c b/src/or/dirvote.c
index ab08fd0200..a557fc782e 100644
--- a/src/or/dirvote.c
+++ b/src/or/dirvote.c
@@ -2536,7 +2536,7 @@ time_t
dirvote_get_start_of_next_interval(time_t now, int interval)
{
struct tm tm;
- time_t midnight_today;
+ time_t midnight_today=0;
time_t midnight_tomorrow;
time_t next;
@@ -2545,7 +2545,9 @@ dirvote_get_start_of_next_interval(time_t now, int interval)
tm.tm_min = 0;
tm.tm_sec = 0;
- midnight_today = tor_timegm(&tm);
+ if (tor_timegm(&tm, &midnight_today) < 0) {
+ log_warn(LD_BUG, "Ran into an invalid time when trying to find midnight.");
+ }
midnight_tomorrow = midnight_today + (24*60*60);
next = midnight_today + ((now-midnight_today)/interval + 1)*interval;
diff --git a/src/or/policies.c b/src/or/policies.c
index c87036013d..55d08afc81 100644
--- a/src/or/policies.c
+++ b/src/or/policies.c
@@ -685,7 +685,11 @@ compare_tor_addr_to_addr_policy(const tor_addr_t *addr, uint16_t port,
/* no policy? accept all. */
return ADDR_POLICY_ACCEPTED;
} else if (tor_addr_is_null(addr)) {
- tor_assert(port != 0);
+ if (port == 0) {
+ log_info(LD_BUG, "Rejecting null address with 0 port (family %d)",
+ addr ? tor_addr_family(addr) : -1);
+ return ADDR_POLICY_REJECTED;
+ }
return compare_unknown_tor_addr_to_addr_policy(port, policy);
} else if (port == 0) {
return compare_known_tor_addr_to_addr_policy_noport(addr, policy);
diff --git a/src/test/test_util.c b/src/test/test_util.c
index f9a83a38a5..12e3fa9793 100644
--- a/src/test/test_util.c
+++ b/src/test/test_util.c
@@ -13,6 +13,19 @@
#include "mempool.h"
#include "memarea.h"
+/* XXXX this is a minimal wrapper to make the unit tests compile with the
+ * changed tor_timegm interface. */
+static time_t
+tor_timegm_wrapper(const struct tm *tm)
+{
+ time_t t;
+ if (tor_timegm(tm, &t) < 0)
+ return -1;
+ return t;
+}
+
+#define tor_timegm tor_timegm_wrapper
+
static void
test_util_time(void)
{