|
|
Message-ID: <14e83e71-4905-4458-a767-e6934a4d2c43@iki.fi>
Date: Mon, 30 Mar 2026 22:05:33 +0300
From: Hannu Nyman <hannu.nyman@....fi>
To: musl@...ts.openwall.com, Rich Felker <dalias@...c.org>
Cc: Shiji Yang <yangshiji66@...look.com>
Subject: Re: strptime in 1.2.6 - is tzname[0/1] guaranteed to be set?
Rich Felker kirjoitti 23.3.2026 klo 19.38:
> On Mon, Mar 23, 2026 at 06:38:07PM +0200, Hannu Nyman wrote:
>> Is a new patch version still coming, or was the last one ("the attached is
>> good") already fine?
> Here's a fixed one,
>
Hello Rich,
the current patch version seems to be still somewhat problematic regarding
the fallback 'else' part.
+ } else {
+ /* FIXME: is this supposed to be an error? */
+ while ((**s|32)-'a' <= 'z'-'a') ++*s;
+ }
To my understanding the part is supposed to consume the alpha chars of the
passed timezone name string and then enable further parsing of the total date
stamp with other possible %-modifiers. Apparently the current check fails to
stop at null \0 and may continue further, causing segmentation error at some
point.
It has seemed to work ok for me on ARM CPUs, but for another OpenWrt tester
on MIPS CPU it still crashes, but this time for evaluating the *s contents,
not the tzname[0]. (tzname is still unitialized, but even if it is set, but
to a unmatching string, the evaluation continues to the 'else' part)
After adding debug print to the start of the function (to print also tzname
pointers) and into the "while" row, it is evident that evaluation continues
past the supposed end of the GMT\0 string.
Mon Mar 30 13:23:22 2026 daemon.err uhttpd[2820]: dump |GMT|(null)|(null)|
Mon Mar 30 13:23:22 2026 daemon.err uhttpd[2820]: *s=|MT|
Mon Mar 30 13:23:22 2026 daemon.err uhttpd[2820]: *s=|T|
Mon Mar 30 13:23:22 2026 daemon.err uhttpd[2820]: *s=||
Mon Mar 30 13:23:22 2026 daemon.err uhttpd[2820]: *s=||
Mon Mar 30 13:23:22 2026 daemon.err uhttpd[2820]: *s=||
Mon Mar 30 13:23:22 2026 daemon.err uhttpd[2820]: *s=|ƒ|
Mon Mar 30 13:23:22 2026 daemon.err uhttpd[2820]: *s=||
Mon Mar 30 13:23:22 2026 daemon.err uhttpd[2820]: *s=||
Mon Mar 30 13:23:22 2026 daemon.err uhttpd[2820]: *s=|#|
Mon Mar 30 13:23:22 2026 daemon.err uhttpd[2820]: *s=||
Mon Mar 30 13:23:22 2026 daemon.err uhttpd[2820]: *s=|accept|
Mon Mar 30 13:23:22 2026 daemon.err uhttpd[2820]: *s=|ccept|
...
He suggests changing the while statement to
|while (isalpha(**s)) ++*s;|
which should nicely consume just the A-z,a-z chars.
I proposed as an alternative a null char check, which also seems to work for
him on MIPS:
|while (**s && (**s|32)-'a' <= 'z'-'a') ++*s;|
I added a slightly different debug print for my own ARM build, also showing
the first char as hex and also the next character. It finally stops, when
there is 0x83 as the next character, as it is bigger than 'z':
while ((**s|32)-'a' <= 'z'-'a') { dprintf(2, "|%s|%1x|\n", *s, **s); ++*s;
dprintf(2, "|%1x|\n", **s);}
[30 Mar 2026, 21:58:04 EEST] daemon.err: uhttpd[4072]: |GMT|(null)|(null)|
[30 Mar 2026, 21:58:04 EEST] daemon.err: uhttpd[4072]: |GMT|47|
[30 Mar 2026, 21:58:04 EEST] daemon.err: uhttpd[4072]: |4d|
[30 Mar 2026, 21:58:04 EEST] daemon.err: uhttpd[4072]: |MT|4d|
[30 Mar 2026, 21:58:04 EEST] daemon.err: uhttpd[4072]: |54|
[30 Mar 2026, 21:58:04 EEST] daemon.err: uhttpd[4072]: |T|54|
[30 Mar 2026, 21:58:04 EEST] daemon.err: uhttpd[4072]: |0|
[30 Mar 2026, 21:58:04 EEST] daemon.err: uhttpd[4072]: ||0|
[30 Mar 2026, 21:58:04 EEST] daemon.err: uhttpd[4072]: |0|
[30 Mar 2026, 21:58:04 EEST] daemon.err: uhttpd[4072]: ||0|
[30 Mar 2026, 21:58:04 EEST] daemon.err: uhttpd[4072]: |0|
[30 Mar 2026, 21:58:04 EEST] daemon.err: uhttpd[4072]: ||0|
[30 Mar 2026, 21:58:04 EEST] daemon.err: uhttpd[4072]: |83|
A check for \0 or 'isalpha' is really needed there.
Ps. Discussion in
https://github.com/openwrt/openwrt/pull/22547#discussion_r3005844156
Powered by blists - more mailing lists
Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.