Bug 1519

Summary: hardlink of symlink in archive messes up permissions
Product: Busybox Reporter: Nils Rennebarth <nils.rennebarth>
Component: OtherAssignee: unassigned
Status: RESOLVED FIXED    
Severity: minor CC: busybox-cvs
Priority: P5    
Version: 1.16.x   
Target Milestone: ---   
Hardware: PC   
OS: Linux   
Host: Target:
Build:

Description Nils Rennebarth 2010-04-08 11:52:57 UTC
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.
Comment 1 Denys Vlasenko 2010-04-09 08:53:24 UTC
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
Comment 2 Denys Vlasenko 2010-04-09 11:43:32 UTC
Ahh... I see! It happens with hardlink TO SYMLINK
Comment 3 Denys Vlasenko 2010-04-09 12:12:39 UTC
Fixed in git, please test.