mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2025-02-24 22:58:50 +01:00
Avoid overflow in tor_timegm on 32 bit platforms due to year 2038
This commit is contained in:
parent
e019e11e61
commit
e71e8e005a
2 changed files with 25 additions and 3 deletions
5
changes/bug18479
Normal file
5
changes/bug18479
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
o Minor bugfixes (time parsing):
|
||||||
|
- Avoid overflow in tor_timegm when parsing dates in and after 2038
|
||||||
|
on platforms with 32-bit time_t.
|
||||||
|
Fixes bug 18479; bugfix on 3c4b4c8ca in tor-0.0.2pre14.
|
||||||
|
Patch by "teor".
|
|
@ -1475,9 +1475,19 @@ tor_timegm(const struct tm *tm, time_t *time_out)
|
||||||
{
|
{
|
||||||
/* This is a pretty ironclad timegm implementation, snarfed from Python2.2.
|
/* This is a pretty ironclad timegm implementation, snarfed from Python2.2.
|
||||||
* It's way more brute-force than fiddling with tzset().
|
* It's way more brute-force than fiddling with tzset().
|
||||||
*/
|
*
|
||||||
time_t year, days, hours, minutes, seconds;
|
* We use int64_t rather than time_t to avoid overflow on multiplication on
|
||||||
|
* platforms with 32-bit time_t. Since year is clipped to INT32_MAX, and
|
||||||
|
* since 365 * 24 * 60 * 60 is approximately 31 million, it's not possible
|
||||||
|
* for INT32_MAX years to overflow int64_t when converted to seconds. */
|
||||||
|
int64_t year, days, hours, minutes, seconds;
|
||||||
int i, invalid_year, dpm;
|
int i, invalid_year, dpm;
|
||||||
|
|
||||||
|
/* Initialize time_out to 0 for now, to avoid bad usage in case this function
|
||||||
|
fails and the caller ignores the return value. */
|
||||||
|
tor_assert(time_out);
|
||||||
|
*time_out = 0;
|
||||||
|
|
||||||
/* avoid int overflow on addition */
|
/* avoid int overflow on addition */
|
||||||
if (tm->tm_year < INT32_MAX-1900) {
|
if (tm->tm_year < INT32_MAX-1900) {
|
||||||
year = tm->tm_year + 1900;
|
year = tm->tm_year + 1900;
|
||||||
|
@ -1516,7 +1526,14 @@ tor_timegm(const struct tm *tm, time_t *time_out)
|
||||||
|
|
||||||
minutes = hours*60 + tm->tm_min;
|
minutes = hours*60 + tm->tm_min;
|
||||||
seconds = minutes*60 + tm->tm_sec;
|
seconds = minutes*60 + tm->tm_sec;
|
||||||
*time_out = seconds;
|
/* Check that "seconds" will fit in a time_t. On platforms where time_t is
|
||||||
|
* 32-bit, this check will fail for dates in and after 2038.
|
||||||
|
* "seconds" can't be negative, because "year" >= 1970. */
|
||||||
|
if (seconds < TIME_MIN || seconds > TIME_MAX) {
|
||||||
|
log_warn(LD_BUG, "Result does not fit in tor_timegm");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
*time_out = (time_t)seconds;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue