]>
Commit | Line | Data |
---|---|---|
da122e9b JB |
1 | Avoid integer overflow when using TZ in form stdNdst without explicit dst rules, |
2 | when: | |
3 | * using 32-bit time_t | |
4 | * first system timezone transition rule begins before 1901 (i.e. ~INT32_MAX) | |
a6f50bfe | 5 | * TZ is on west of system timezone |
da122e9b JB |
6 | --- glibc-2.27/time/tzfile.c.orig 2018-02-10 11:10:05.455102136 +0100 |
7 | +++ glibc-2.27/time/tzfile.c 2018-07-14 21:25:23.090397420 +0200 | |
8 | @@ -543,6 +543,25 @@ | |
9 | We will use the names and offsets from the user, and the rules | |
10 | from the TZDEFRULES file. */ | |
11 | ||
12 | +static void time_adjust_limited(time_t *value, long diff) | |
13 | +{ | |
b5de568d JB |
14 | + static time_t time_min = (sizeof(time_t) == 4) ? INT32_MIN : INT64_MIN; |
15 | + static time_t time_max = (sizeof(time_t) == 4) ? INT32_MAX : INT64_MAX; | |
da122e9b JB |
16 | + if (diff < 0) |
17 | + { | |
b5de568d | 18 | + if (*value >= time_min - diff) |
da122e9b JB |
19 | + *value += diff; |
20 | + else | |
21 | + *value = time_min; | |
22 | + } else if (diff > 0) | |
23 | + { | |
24 | + if (*value <= time_max - diff) | |
25 | + *value += diff; | |
26 | + else | |
27 | + *value = time_max; | |
28 | + } | |
29 | +} | |
30 | + | |
31 | void | |
32 | __tzfile_default (const char *std, const char *dst, | |
33 | long int stdoff, long int dstoff) | |
34 | @@ -590,13 +609,13 @@ | |
35 | wall clock time as of the previous transition was DST. Correct | |
36 | for the difference between the rule's DST offset and the user's | |
37 | DST offset. */ | |
38 | - transitions[i] += dstoff - rule_dstoff; | |
39 | + time_adjust_limited(&transitions[i], dstoff - rule_dstoff); | |
40 | else | |
41 | /* This transition is in "local wall clock time", and wall clock | |
42 | time as of this iteration is non-DST. Correct for the | |
43 | difference between the rule's standard offset and the user's | |
44 | standard offset. */ | |
45 | - transitions[i] += stdoff - rule_stdoff; | |
46 | + time_adjust_limited(&transitions[i], stdoff - rule_stdoff); | |
47 | ||
48 | /* The DST state of "local wall clock time" for the next iteration is | |
49 | as specified by this transition. */ |