[BusyBox 0003844]: tar replaces permissions on existing directories

bugs at busybox.net bugs at busybox.net
Tue Jun 24 19:19:29 UTC 2008


A NOTE has been added to this issue. 
====================================================================== 
http://busybox.net/bugs/view.php?id=3844 
====================================================================== 
Reported By:                wz2b
Assigned To:                BusyBox
====================================================================== 
Project:                    BusyBox
Issue ID:                   3844
Category:                   Standards Compliance
Reproducibility:            always
Severity:                   major
Priority:                   normal
Status:                     assigned
====================================================================== 
Date Submitted:             06-23-2008 09:06 PDT
Last Modified:              06-24-2008 12:19 PDT
====================================================================== 
Summary:                    tar replaces permissions on existing directories
Description: 
I have been diagnosing some dpkg installation behavior that differs from
what non-busybox dpkg.  The unpacking in dpkg actually occurs in the code
for tar, so as an experiment I tried to determine if tar has the same
behavior.  The scenario is this: if an archive contains intermediate
directories, busybox's untar apparently sets the permissions of those
intermediate directories to match the tarball even if the directory
already existed.



====================================================================== 

---------------------------------------------------------------------- 
 vda - 06-23-08 10:41  
---------------------------------------------------------------------- 
> What's perplexing is what's the "right" thing to do?

Right thing to do is to adhere to standards, and to GNU tools' behavior
(in this order of importance). 

---------------------------------------------------------------------- 
 vda - 06-23-08 10:57  
---------------------------------------------------------------------- 
I just tried - GNU tar also restores mode of the files and dirs even if
they already existed.

So, "standard" dpkg does not use tar but performs tar unpacking
internally, and it does not restore modes? Can you upload an example file
and specify how to reporduce the problem?

BTW, tghanks for looking into dpkg, it needs some work... 

---------------------------------------------------------------------- 
 wz2b - 06-24-08 09:21  
---------------------------------------------------------------------- 
I'm confused that you don't see the same behavior with tar as I do, so to
begin, I have uploaded a small shell script to test the behavior.  This
script produces different results between gnu tar 1.15.1 and busybox.  On
gnu tar, I get:

==== Test 2 - directory already exists ====
drwx------ 2 cepasp ahm 4096 2008-06-24 12:16 ./tar_test
This directory should have permissions 0700
because tar did not overwrite the existing directory


which is what I hoped; tar saw that the directory tar_test already existed
so it did not alter its permissions (or owner, but it's easier to test this
when you change the permissions, because you don't have to be root as you
would when changing owner).


Now, running the same script on busybox, I get this result:

==== Test 2 - directory already exists ====
drwxr-xr-x    2 root     root         1024 Jun 24 16:10 ./tar_test
This directory should have permissions 0700
because tar did not overwrite the existing directory


So what busybox's tar did was to replace the existing permissions with
those in the archive.

It's interesting that you note that "standard" dpkg doesn't call tar, but
does the untarring internally.  Maybe that's the answer here, too -- maybe
busybox's dpkg needs to do something slightly different than the internal
tar. 

---------------------------------------------------------------------- 
 vda - 06-24-08 11:32  
---------------------------------------------------------------------- 
I added
tar --version 2>&1 | head -3
tar --help 2>&1 | head -3
so that version will be visible, then ran:


Busybox:

# sh tartest.sh
tar: unrecognized option `--version'
BusyBox v1.11.0.svn (2008-04-29 04:44:30 CEST) multi-call binary

BusyBox v1.11.0.svn (2008-04-29 04:44:30 CEST) multi-call binary

Usage: tar -[czjaZxtvO] [-X FILE] [-f TARFILE] [-C DIR] [FILE(s)]...
==== Test 1 - directory gets permissions in tarball ====
drwxr-xr-x    2 root     root           72 Jun 24 20:29 ./tar_test

This directory should have permissions 0755
because that's what is in the tarball
==== Test 2 - directory already exists ====
drwxr-xr-x    2 root     root           72 Jun 24 20:29 ./tar_test

This directory should have permissions 0700
because tar did not overwrite the existing directory


GNU:

# PATH=/usr/bin:$PATH sh tartest.sh
tar (GNU tar) 1.15.1
Usage: tar [OPTION...] [FILE]...
GNU `tar' saves many files together into a single tape or disk archive,
and can
restore individual files from the archive.
==== Test 1 - directory gets permissions in tarball ====
drwxr-xr-x 2 root root 72 2008-06-24 20:28 ./tar_test

This directory should have permissions 0755
because that's what is in the tarball
==== Test 2 - directory already exists ====
drwxr-xr-x 2 root root 72 2008-06-24 20:28 ./tar_test

This directory should have permissions 0700
because tar did not overwrite the existing directory


Conclusion: with your script even GNU tar overwrites permissions
of existing directory. At least GNU tar 1.15.1 

---------------------------------------------------------------------- 
 wz2b - 06-24-08 11:54  
---------------------------------------------------------------------- 
Wow, I am totally mind-boggled because this is not what I get.  On my
ubuntu system with gnu tar 1.15.1:

$ ./tartest.sh
==== Test 1 - directory gets permissions in tarball ====
drwxr-xr-x 2 cepasp ahm 4096 2008-06-24 14:53 ./tar_test

This directory should have permissions 0755
because that's what is in the tarball
==== Test 2 - directory already exists ====
drwx------ 2 cepasp ahm 4096 2008-06-24 14:53 ./tar_test

This directory should have permissions 0700
because tar did not overwrite the existing directory

$ tar --version
tar (GNU tar) 1.15.1

What on earth could be causing us to get different behavior? 

---------------------------------------------------------------------- 
 vda - 06-24-08 12:06  
---------------------------------------------------------------------- 
Made tar run under strace:

chmod ${MODE2} ${DIR}
strace -o tar.strace tar -zxf ${DIR}.tgz
^^^^^^^^^^^^^^^^^^^^

The end of strace log is as follows:

mkdir("./tar_test", 0755)               = -1 EEXIST (File exists)
stat64("./tar_test", {st_mode=S_IFDIR|0700, st_size=48, ...}) = 0
open("./tar_test/testfile", O_WRONLY|O_CREAT|O_EXCL|O_LARGEFILE, 0644) =
5
close(5)                                = 0
utime("./tar_test/testfile", [2008/06/24-21:02:28, 2008/06/24-21:02:28]) =
0
chown32("./tar_test/testfile", 0, 0)    = 0
read(3, "", 10240)                      = 0
gettimeofday({1214334148, 991164}, NULL) = 0
gettimeofday({1214334148, 991216}, NULL) = 0
close(3)                                = 0
waitpid(7168, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0) = 7168
utime("./tar_test", [2008/06/24-21:02:28, 2008/06/24-21:02:28]) = 0
chmod("./tar_test", 0755)               = 0 <===================== HERE
chown32("./tar_test", 0, 0)             = 0
close(1)                                = 0
close(2)                                = 0
exit_group(0)                           = ?

It sees that dir exists, with mode 700.
It definitely does chmod("./tar_test", 0755).
What do you see?
Does it differ under root and non-root? 

---------------------------------------------------------------------- 
 wz2b - 06-24-08 12:15  
---------------------------------------------------------------------- 
>Does it differ under root and non-root?
Yep, you nailed it.  That's the difference.

I was running these tests as myself  If you're non-root, strace shows that
tar performs no chmod.  It just fails on creation of the directory, and
moves on silently:

mkdir("./tar_test", 0755)               = -1 EEXIST (File exists)
stat64("./tar_test", {st_mode=S_IFDIR|0700, st_size=4096, ...}) = 0

So ... now what?  I guess I should see what dpkg does on ubuntu compared
to busybox and see what happens.  I'll try that, and when I figure
something out I'll post the results -- and upload a tiny sample .deb 

---------------------------------------------------------------------- 
 vda - 06-24-08 12:19  
---------------------------------------------------------------------- 
Please attach full strace output 

Issue History 
Date Modified   Username       Field                    Change               
====================================================================== 
06-23-08 09:06  wz2b           New Issue                                    
06-23-08 09:06  wz2b           Status                   new => assigned     
06-23-08 09:06  wz2b           Assigned To               => BusyBox         
06-23-08 09:12  wz2b           Issue Monitored: wz2b                        
06-23-08 10:41  vda            Note Added: 0008474                          
06-23-08 10:57  vda            Note Added: 0008484                          
06-24-08 09:14  wz2b           File Added: tartest.sh                       
06-24-08 09:21  wz2b           Note Added: 0008494                          
06-24-08 11:32  vda            Note Added: 0008504                          
06-24-08 11:54  wz2b           Note Added: 0008514                          
06-24-08 12:06  vda            Note Added: 0008524                          
06-24-08 12:15  wz2b           Note Added: 0008534                          
06-24-08 12:19  vda            Note Added: 0008544                          
======================================================================




More information about the busybox-cvs mailing list