If an archive contains a hardlink of a symlink, extracting the hardlink messes up the permissions of the real file. Assume the following situtation (under linux, other OS may behave differently, but I heard Solaris does the same) $ touch file $ ln -s file link $ mkdir dir $ ln file dir $ ln link dir Now dir will contain two hardlinks, one named "file" and one named "link" When GNU tar creates an archive of all this and busybox tar extracts it, the "file" will have permission 777. The bug lies in archival/libunarchive/data_extract_all.c, where hardlinks are first handled separately (line 73-80), but later chown and chmod is performed, and that is done by chmod itself, which uses the permissions of the symlink which are always 777. I would argue that a hardlink has no permissions (nor timestamps nor uid/gid) itself, because all that data is in the inode. And the code relies on the existance of the link target already, so my proposal for a fix would be to simply return on line 80.
Works for me: tar.tests: ========== #!/bin/sh rm -rf input_* test.tar 2>/dev/null >input_hard1 chmod 741 input_hard1 ln input_hard1 input_hard2 mkdir input_dir chmod 550 input_dir ln input_hard1 input_dir ln input_hard2 input_dir /usr/bin/tar cf test.tar input_* rm -rf input_* ./busybox tar tvf test.tar ./busybox tar xf test.tar echo Ok: $? ls -l . input_dir/* | grep input_ rm -rf input_* test.tar 2>/dev/null Running it: dr-xr-x--- root/root 0 2010-04-09 10:50:08 input_dir/ -rwxr----x root/root 0 2010-04-09 10:50:08 input_dir/input_hard1 -rwxr----x root/root 0 2010-04-09 10:50:08 input_dir/input_hard2 -> input_dir/input_hard1 -rwxr----x root/root 0 2010-04-09 10:50:08 input_hard1 -> input_dir/input_hard1 -rwxr----x root/root 0 2010-04-09 10:50:08 input_hard2 -> input_dir/input_hard1 Ok: 0 -rwxr----x 4 root root 0 Apr 9 10:50 input_dir/input_hard1 -rwxr----x 4 root root 0 Apr 9 10:50 input_dir/input_hard2 dr-xr-x--- 2 root root 112 Apr 9 10:50 input_dir -rwxr----x 4 root root 0 Apr 9 10:50 input_hard1 -rwxr----x 4 root root 0 Apr 9 10:50 input_hard2
Ahh... I see! It happens with hardlink TO SYMLINK
Fixed in git, please test.