NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: bin/56538: netbsd-3 /bin/ls crashes with current libc



The following reply was made to PR bin/56538; it has been noted by GNATS.

From: mlelstv%serpens.de@localhost (Michael van Elst)
To: gnats-bugs%netbsd.org@localhost
Cc: 
Subject: Re: bin/56538: netbsd-3 /bin/ls crashes with current libc
Date: Sun, 5 Dec 2021 18:27:30 -0000 (UTC)

 coypu%sdf.org@localhost writes:
 
 >curl -LO http://archive.netbsd.org/pub/NetBSD-archive/NetBSD-3.0/amd64/binary/sets/base.tgz
 >tar xf base.tgz
 >TZ=UTC ./bin/ls -l              # works
 >TZ="Asia/Jerusalem" ./bin/ls -l # crashes
 
 ctime() may return NULL on failure and ls(1) from netbsd-3 doesn't
 validate the result.
 
 ctime returns NULL from localtime.c:1601 as the timezone state gets corrupted.
 
 First call to tzload:
 
 #0  tzload (doextend=true, sp=0x7f7ff7e68740, name=0x0) at /scratch/netbsd-current/src/lib/libc/time/localtime.c:795
 #1  zoneinit (sp=sp@entry=0x7f7ff7e68740, name=name@entry=0x0) at /scratch/netbsd-current/src/lib/libc/time/localtime.c:1440
 #2  0x00007f7ff7487954 in tzsetlcl (name=0x0) at /scratch/netbsd-current/src/lib/libc/time/localtime.c:1462
 #3  0x00007f7ff7488ad3 in __tzset_unlocked () at /scratch/netbsd-current/src/lib/libc/time/localtime.c:1484
 #4  0x00007f7ff7488b83 in localtime_tzset (setname=true, tmp=0x7f7ff77fb6a0, timep=0x7f7fffffdeec)
     at /scratch/netbsd-current/src/lib/libc/time/localtime.c:1668
 #5  localtime (timep=0x7f7fffffdeec) at /scratch/netbsd-current/src/lib/libc/time/localtime.c:1677
 #6  0x00007f7ff7488d3a in ctime (timep=<optimized out>) at /scratch/netbsd-current/src/lib/libc/time/localtime.c:1920
 #7  0x000000000040367b in printtime ()
 #8  0x0000000000402b69 in printlong ()
 #9  0x0000000000402510 in display ()
 #10 0x0000000000401fd4 in traverse ()
 #11 0x0000000000401d36 in ls_main ()
 
 and:
 
 (gdb) print sizeof(sp->ats[0])
 $29 = 4
 
 
 Second call to tzload:
 
 #0  tzload (doextend=true, sp=0x7f7ff7e68740, name=0x0) at /scratch/netbsd-current/src/lib/libc/time/localtime.c:795
 #1  zoneinit (sp=sp@entry=0x7f7ff7e68740, name=name@entry=0x0) at /scratch/netbsd-current/src/lib/libc/time/localtime.c:1440
 #2  0x00007f7ff756c97c in tzsetlcl (name=0x0) at /scratch/netbsd-current/src/lib/libc/time/localtime.c:1462
 #3  0x00007f7ff756db4e in __tzset_unlocked50 () at /scratch/netbsd-current/src/lib/libc/time/localtime.c:1484
 #4  0x00007f7ff74bb1ea in strftime (s=s@entry=0x7f7fffffde43 "\367\177\177", maxsize=maxsize@entry=13, format=format@entry=0x7f7ff75b874e "%Y", 
     t=t@entry=0x7f7ff77fb6a0) at /scratch/netbsd-current/src/lib/libc/time/strftime.c:743
 #5  0x00007f7ff756e1f9 in _asctime_r (timeptr=0x7f7ff77fb6a0, buf=0x7f7ff7a16e80 "") at /scratch/netbsd-current/src/lib/libc/time/asctime.c:116
 #6  0x000000000040367b in printtime ()
 #7  0x0000000000402b69 in printlong ()
 #8  0x0000000000402510 in display ()
 #9  0x0000000000401fd4 in traverse ()
 #10 0x0000000000401d36 in ls_main ()
 
 and:
 
 (gdb) print sizeof(sp->ats[0])
 $30 = 8
 
 
 A bit confusing (same tzload function, same parameter type), but shows that the first call is done from _tzset_unlocked (old 32bit time_t entry)
 while the second is done from __tzset_unlocked50 (new 64bit time_t entry). And both use the same global __lclptr to store timezone data.
 
 (gdb) print __lclptr
 $5 = (struct __state *) 0x7f7ff7e68740
 
 
 But why is ls calling _asctime_r ?
 
 char *
 ctime(const time_t *timep)
 {
         struct tm *tmp = localtime(timep);
         return tmp ? asctime(tmp) : NULL;
 }
 
 And there is only one asctime and _asctime_r using a 'struct tm' parameter, but internally
 it references the global timezone data using 64bit time_t functions.
 
 The first call to ctime() works, but asctime() corrupts the global timezone data. The second time
 this causes localtime() to fail, ctime to return NULL and ls to segfault.
 
 


Home | Main Index | Thread Index | Old Index