diff options
author | Roger Dingledine <arma@torproject.org> | 2012-09-11 13:57:24 -0400 |
---|---|---|
committer | Roger Dingledine <arma@torproject.org> | 2012-09-11 13:57:24 -0400 |
commit | d204b04298952373d3f6f89e7153ceeb17053b1c (patch) | |
tree | e9bbdd6ca68c281466438e619f4cefe40cddd7f8 | |
parent | 2a824b942a82818a794f85e0784d77c7dd3bbfef (diff) | |
parent | 84f47ffc462dface8db1def322414daa43400d1c (diff) | |
download | tor-d204b04298952373d3f6f89e7153ceeb17053b1c.tar.gz tor-d204b04298952373d3f6f89e7153ceeb17053b1c.zip |
Merge branch 'maint-0.2.2' into release-0.2.2
-rw-r--r-- | changes/bug6690 | 7 | ||||
-rw-r--r-- | changes/bug6811 | 5 | ||||
-rw-r--r-- | src/common/util.c | 27 | ||||
-rw-r--r-- | src/common/util.h | 2 | ||||
-rw-r--r-- | src/or/directory.c | 3 | ||||
-rw-r--r-- | src/or/dirvote.c | 6 | ||||
-rw-r--r-- | src/or/policies.c | 6 | ||||
-rw-r--r-- | src/test/test_util.c | 13 |
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) { |