bug-cpio
[Top][All Lists]
Advanced

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

[Bug-cpio] Re: Bug#565474: cpio makes device nodes into hard links when


From: Clint Adams
Subject: [Bug-cpio] Re: Bug#565474: cpio makes device nodes into hard links when copying out of a cramfs image
Date: Sat, 16 Jan 2010 05:09:45 +0000
User-agent: Mutt/1.5.18 (2008-05-17)

On Fri, Jan 15, 2010 at 08:06:54PM -0800, Carl Miller wrote:
> cramfs takes a shortcut with device nodes, and assigns them all inode 1.
> When using cpio to copy files out of a cramfs image, cpio turns the second
> and all subsequent copied device nodes into hard links to the first copied
> out device node, based on them all having the same st_dev and st_ino.  The
> resulting archive does not extract properly, because you cannot make a
> hard link to a device node.
> 
> Solution: when checking for hard links during copy-out, take the file
> type into account.  The test should be changed from "st_devs equal and
> st_inos equal" to "st_devs equal and st_inos equal and not block device
> and not char device".
> 
> 
> 
> 
> address@hidden:/tmp/unpack# mkdir mnt_228
> address@hidden:/tmp/unpack# mount -t cramfs -o ro,nodev,noexec,loop 
> /usr/local/isengard/share/builds/build228/disk_fs.img mnt_228
> address@hidden:/tmp/unpack# ls -l mnt_228/dev/loop?
> brw-r--r-- 1 root root 7, 0 1969-12-31 16:00 mnt_228/dev/loop0
> brw-r--r-- 1 root root 7, 1 1969-12-31 16:00 mnt_228/dev/loop1
> brw-r--r-- 1 root root 7, 2 1969-12-31 16:00 mnt_228/dev/loop2
> brw-r--r-- 1 root root 7, 3 1969-12-31 16:00 mnt_228/dev/loop3
> address@hidden:/tmp/unpack# cd mnt_228
> address@hidden:/tmp/unpack/mnt_228# ( echo "dev" ; echo "dev/loop0" ; echo 
> "dev/loop1" ; echo "dev/loop2" ; echo "dev/loop3" ) | cpio -o -F 
> /tmp/looptest.tar -H ustar --quiet
> address@hidden:/tmp/unpack/mnt_228# tar -tf /tmp/looptest.tar
> tar: Record size = 7 blocks
> dev/
> dev/loop0/
> dev/loop1/
> dev/loop2/
> dev/loop3/
> address@hidden:/tmp/unpack/mnt_228# cd ..
> address@hidden:/tmp/unpack# tar -xvf /tmp/looptest.tar
> tar: Record size = 7 blocks
> dev/
> dev/loop0/
> tar: dev/loop0: implausibly old time stamp 1969-12-31 16:00:00
> dev/loop1/
> tar: dev/loop1: Cannot hard link to `dev/loop0/': Not a directory
> dev/loop2/
> tar: dev/loop2: Cannot hard link to `dev/loop0/': Not a directory
> dev/loop3/
> tar: dev/loop3: Cannot hard link to `dev/loop0/': Not a directory
> tar: dev: implausibly old time stamp 1969-12-31 16:00:00
> tar: Exiting with failure status due to previous errors
> address@hidden:/tmp/unpack# ls -l dev
> total 0
> brw-r--r-- 1 root root 7, 0 1969-12-31 16:00 loop0

You mean something like this?


diff --git a/src/copyout.c b/src/copyout.c
index 98f3895..f0741f7 100644
--- a/src/copyout.c
+++ b/src/copyout.c
@@ -121,7 +121,9 @@ count_defered_links_to_dev_ino (struct cpio_file_stat 
*file_hdr)
   for (d = deferouts; d != NULL; d = d->next)
     {
       if ( (d->header.c_ino == ino) && (d->header.c_dev_maj == maj)
-         && (d->header.c_dev_min == min) )
+         && (d->header.c_dev_min == min)
+         && ((d->header.c_mode & CP_IFBLK) != CP_IFBLK)
+         && ((d->header.c_mode & CP_IFCHR) != CP_IFCHR) )
        ++count;
     }
   return count;
@@ -178,7 +180,9 @@ writeout_other_defers (struct cpio_file_stat *file_hdr, int 
out_des)
   while (d != NULL)
     {
       if ( (d->header.c_ino == ino) && (d->header.c_dev_maj == maj)
-         && (d->header.c_dev_min == min) )
+         && (d->header.c_dev_min == min)
+         && ((d->header.c_mode & CP_IFBLK) != CP_IFBLK)
+         && ((d->header.c_mode & CP_IFCHR) != CP_IFCHR) )
        {
          struct deferment *d_free;
          d->header.c_filesize = 0;




reply via email to

[Prev in Thread] Current Thread [Next in Thread]