mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-10 05:03:43 +01:00
Fix assertion failure in tor_timegm.
Fixes bug 6811.
This commit is contained in:
parent
1c30e6abc9
commit
973c18bf0e
5
changes/bug6811
Normal file
5
changes/bug6811
Normal file
@ -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.
|
||||
|
@ -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),
|
||||
|
@ -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);
|
||||
|
@ -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. */
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user