tar 1.33 symlinks : Cannot change mode to...

Corinna Vinschen corinna-cygwin@cygwin.com
Tue Jan 12 17:15:05 GMT 2021


On Jan 12 11:55, Ken Brown via Cygwin wrote:
> On 1/11/2021 6:50 PM, Ken Brown via Cygwin wrote:
> > On 1/11/2021 2:57 PM, Morgan King via Cygwin wrote:
> > > Hello,
> > > 
> > > I am experiencing the same issue with tar and I am able to reproduce
> > > it following the steps at:
> > > https://lists.gnu.org/archive/html/bug-tar/2011-08/msg00006.html
> > > 
> > > This issue only appears to occur when using 32-bit Cygwin, I am
> > > unable to reproduce it using 64-bit Cygwin.
> > 
> > I can confirm this.  Running the tar command under gdb shows a problem
> > at gnu/fchmodat.c:94:
> > 
> > 94            if (S_ISLNK (st.st_mode))
> > 
> > Here st is a stat structure for directory/1, so S_ISLNK() should be
> > true.  It is indeed true on 64-bit Cygwin but not on 32-bit Cygwin. 
> > Someone needs to look more closely and find out why this happened.  I'll
> > try to do it tomorrow if no one beats me to it.
> 
> This appears to be a bug in fstat in 32-bit Cygwin.  Here's what I'm seeing
> in gdb, using an unoptimized build of cygwin1.dll.  There is a call to
> fstatat in the tar source file gnu/fchmodat.c:87.  This ultimately leads to
> a call to fstat, whose definition in syscalls.cc is the following in the
> 32-bit case:

No, wait.  struct stat == struct _stat64 since Cygwin 1.5.0!

With Cygwin 1.5.0, the old entry point fstat was only retained to serve
old 32 bit applications buil.t under Cygwin 1.3.x or earlier.

Consequentially, newer 32 bit apps, built with Cygwin 1.5.0 or later,
are redirected to fstat64, see NEW_FUNCTIONS in Makefile.in.

If tar is actually calling fstat, something fishy is going on.

> After the call to stat64_to_stat32, buf looks like this:
> 
> (gdb) p/o *buf
> $22 = {st_dev = 026106753173, st_ino = 017510000040000120777, st_mode = 01001,
>   st_nlink = 01, st_uid = 013777346014, st_gid = 03415154434,
>   st_rdev = 013777334323, st_size = 0161040234413777346014, st_atim = {
>     tv_sec = 0200000, tv_nsec = 0}, st_mtim = {tv_sec = 01, tv_nsec = 0},
>   st_ctim = {tv_sec = 06533716, tv_nsec = 025000000}, st_blksize = 0,
>   st_blocks = 0, st_birthtim = {tv_sec = 0, tv_nsec = 03}}
> 
> Note that many of the values have been corrupted or shifted.

NHo, they are not.  The problme is jsut that buf is defined as
`struct stat' for API compatibility, but older (pre Cygwin-1.5.0)
32 bit apps expect the old 32 bit struct __stat32.  Therefore,
to evaluate the content of buf correctly, you have to cast it to
struct __stat32 * in GDB.  But... see above.


Corinna


More information about the Cygwin mailing list