ref: 158b9dbe0d41ab150f62104258315d8238318292
parent: dd26895a25cf8fa532d1249af4e414fe75b43304
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Thu Apr 17 01:25:00 EDT 2025
libc: fix ALL tzload() bugs It used snprint() return to check for Tzone.tzname truncation, can never happen as our snprintf() will never return anything >= the passed buffer size (it always nul-terminates). Return path is wrong, forgetting to unlock. Passing the tzname to snprint format! so if you tzload("%s") it crashes. Does the realloc() of the zones array in wrong order (before load). In case tzload() fails, and returns. We never assign newzones to zones, so zones points to potentially stale data.
--- a/sys/src/libc/port/date.c
+++ b/sys/src/libc/port/date.c
@@ -167,6 +167,11 @@
int i, f, r;
memset(tz, 0, sizeof(Tzone));
+ strncpy(tz->tzname, name, sizeof(tz->tzname));
+ if(tz->tzname[sizeof(tz->tzname)-1]){
+ werrstr("timezone name too long");
+ return -1;
+ }
if(strcmp(name, "local") == 0)
snprint(path, sizeof(path), "/env/timezone");
else
@@ -223,15 +228,11 @@
tz = malloc(sizeof(Tzone));
if(tz == nil)
goto error;
+ if(loadzone(tz, tzname) != 0)
+ goto error;
newzones = realloc(zones, (nzones + 1) * sizeof(Tzone*));
if(newzones == nil)
goto error;
- if(loadzone(tz, tzname) != 0)
- goto error;
- if(snprint(tz->tzname, sizeof(tz->tzname), tzname) >= sizeof(tz->tzname)){
- werrstr("timezone name too long");
- return nil;
- }
zones = newzones;
zones[nzones] = tz;
nzones++;
--
⑨