misc/100881: Error in libarchive/archive_write.c blocks use of libarchive in a archive in archive out filter

Spencer Minear minear at securecomputing.com
Wed Jul 26 13:30:18 UTC 2006


>Number:         100881
>Category:       misc
>Synopsis:       Error in libarchive/archive_write.c blocks use of libarchive in a archive in archive out filter
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Wed Jul 26 13:30:10 GMT 2006
>Closed-Date:
>Last-Modified:
>Originator:     Spencer Minear
>Release:        6.0 but the problem appears to still be in the current code
>Organization:
Secure Computing
>Environment:
FreeBSD nowind2.scur.com 6.0-RELEASE FreeBSD 6.0-RELEASE #0: Mon Jan 16 13:04:57 CST 2006     mkarels at nowind2.scur.com:/usr/src/sys/i386/compile/SMP  i386

>Description:
There is a logic check between the archive_open functions and the archive_write functions to make sure one does not attempt to add an archive file to itself.

The check is accomplished by saving the st_dev and st_ino values of the archive file in the archive header archive header's skip_file_dev and skip_file_ino fields.  Later when a archive entry is added to the archive in archive_write_header the dev and ino values of the archive entry header are checked against the previously saved values for the archive file.

The problem shows up when the archive is opened via a archive_write_open_fd call.  IN this case the input MAY be from a pipe in which case the dev and ino values are set to 0.  Also if the archive entry that is to be written to the archive also came from a pipe in which case the archive entry header also has the dev and ino values set to 0.  When one attemtps to write that archive header into the archive the check sees 0s in both the entry header and the archive header, which match and blocks the write.

I believe that the check in archive_write.c should be modified to require that the   check applies only in the case where the dev and ino values are not 0.

*** archive_write.c     2006/01/03 20:34:31     1.3
--- archive_write.c     2006/07/26 13:10:55
***************
*** 201,207 ****
        if (a->state & ARCHIVE_STATE_DATA)
                ((a->format_finish_entry)(a));
  
!       if (archive_entry_dev(entry) == a->skip_file_dev &&
            archive_entry_ino(entry) == a->skip_file_ino) {
                archive_set_error(a, 0, "Can't add archive to itself");
                return (ARCHIVE_WARN);
--- 201,209 ----
        if (a->state & ARCHIVE_STATE_DATA)
                ((a->format_finish_entry)(a));
  
!       if (archive_entry_dev(entry) != 0 &&
!           archive_entry_dev(entry) == a->skip_file_dev &&
!           archive_entry_ino(entry) != 0 &&
            archive_entry_ino(entry) == a->skip_file_ino) {
                archive_set_error(a, 0, "Can't add archive to itself");
                return (ARCHIVE_WARN);

I believe that this fix allows the use of library code to build an archive filter that receives and writes via a pipeline processing and still does what it was intended to do, i.e. keep some one from building a tar file that recures on it self.


>How-To-Repeat:
You need to build a pipeline that ends up providing a raw archive as input feed it to a filter that reads archive entries and then writes them out through another pipeline.
>Fix:
See diff in the full description.
>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list