From mboxrd@z Thu Jan 1 00:00:00 1970 X-Msuck: nntp://news.gmane.org/gmane.linux.lib.musl.general/13268 Path: news.gmane.org!.POSTED!not-for-mail From: Rich Felker Newsgroups: gmane.linux.lib.musl.general Subject: Re: [PATCH] always reset DST rules during tzset Date: Fri, 14 Sep 2018 21:16:34 -0400 Message-ID: <20180915011634.GP1878@brightrain.aerifal.cx> References: <20180914224655.24718-1-benjamin@python.org> Reply-To: musl@lists.openwall.com NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: blaine.gmane.org 1536974084 22323 195.159.176.226 (15 Sep 2018 01:14:44 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Sat, 15 Sep 2018 01:14:44 +0000 (UTC) User-Agent: Mutt/1.5.21 (2010-09-15) To: musl@lists.openwall.com Original-X-From: musl-return-13284-gllmg-musl=m.gmane.org@lists.openwall.com Sat Sep 15 03:14:40 2018 Return-path: Envelope-to: gllmg-musl@m.gmane.org Original-Received: from mother.openwall.net ([195.42.179.200]) by blaine.gmane.org with smtp (Exim 4.84_2) (envelope-from ) id 1g0zAT-0005g5-W7 for gllmg-musl@m.gmane.org; Sat, 15 Sep 2018 03:14:38 +0200 Original-Received: (qmail 13709 invoked by uid 550); 15 Sep 2018 01:16:46 -0000 Mailing-List: contact musl-help@lists.openwall.com; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-ID: Original-Received: (qmail 13687 invoked from network); 15 Sep 2018 01:16:46 -0000 Content-Disposition: inline In-Reply-To: <20180914224655.24718-1-benjamin@python.org> Original-Sender: Rich Felker Xref: news.gmane.org gmane.linux.lib.musl.general:13268 Archived-At: On Fri, Sep 14, 2018 at 03:46:55PM -0700, Benjamin Peterson wrote: > do_tzset() did't always reset the DST transition rules r0 and r1. That means the > rules from older TZ settings could leak into newer ones. > > The following program demonstrates this bug. It should print out the same > timezone twice but doesn't due to the leaky state. > > int main() { > time_t t = 0; > struct tm p; > setenv("TZ", "STD-1DST", 1); > localtime_r(&t, &p); > printf("%s\n", p.tm_zone); > setenv("TZ", "STD-1DST,M3.2.0,M11.1.0", 1); > tzset(); > setenv("TZ", "STD-1DST", 1); > localtime_r(&t, &p); > printf("%s\n", p.tm_zone); > return 0; > } > --- > src/time/__tz.c | 4 +++- > 1 file changed, 3 insertions(+), 1 deletion(-) > > diff --git a/src/time/__tz.c b/src/time/__tz.c > index 51e66514..3ccfdd5d 100644 > --- a/src/time/__tz.c > +++ b/src/time/__tz.c > @@ -130,6 +130,9 @@ static void do_tzset() > > if (old_tz && !strcmp(s, old_tz)) return; > > + memset(r0, 0, sizeof r0); > + memset(r1, 0, sizeof r1); > + > if (zi) __munmap((void *)zi, map_size); > > /* Cache the old value of TZ to check if it has changed. Avoid > @@ -194,7 +197,6 @@ static void do_tzset() > const unsigned char *p; > __tzname[0] = __tzname[1] = 0; > __daylight = __timezone = dst_off = 0; > - for (i=0; i<5; i++) r0[i] = r1[i] = 0; > for (p=types; p if (!p[4] && !__tzname[0]) { > __tzname[0] = (char *)abbrevs + p[5]; > -- > 2.17.1 This looks right, but is there a reason you swapped the for loop out for memsets? Either should work, but I probably preferred the loop in the original since, due to -ffreestanding which is necessary when building a libc, the compiler can't inline the memset automatically with a builtin. I might however use the new header wrapper framework to make it so (dependent on __GNUC__) memcpy and memset get redirected to the __builtin_* versions except in the source files that define them, in which case this kind of thing wouldn't matter. Rich