From nobody@FreeBSD.org  Wed Jul 26 13:27:56 2006
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125])
	by hub.freebsd.org (Postfix) with ESMTP id DD17616A4DD
	for <freebsd-gnats-submit@FreeBSD.org>; Wed, 26 Jul 2006 13:27:55 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (www.freebsd.org [216.136.204.117])
	by mx1.FreeBSD.org (Postfix) with ESMTP id 9D4A443D49
	for <freebsd-gnats-submit@FreeBSD.org>; Wed, 26 Jul 2006 13:27:55 +0000 (GMT)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (localhost [127.0.0.1])
	by www.freebsd.org (8.13.1/8.13.1) with ESMTP id k6QDRtfE005381
	for <freebsd-gnats-submit@FreeBSD.org>; Wed, 26 Jul 2006 13:27:55 GMT
	(envelope-from nobody@www.freebsd.org)
Received: (from nobody@localhost)
	by www.freebsd.org (8.13.1/8.13.1/Submit) id k6QDRtsi005380;
	Wed, 26 Jul 2006 13:27:55 GMT
	(envelope-from nobody)
Message-Id: <200607261327.k6QDRtsi005380@www.freebsd.org>
Date: Wed, 26 Jul 2006 13:27:55 GMT
From: Spencer Minear <minear@securecomputing.com>
To: freebsd-gnats-submit@FreeBSD.org
Subject: Error in libarchive/archive_write.c blocks use of libarchive in a archive in archive out filter
X-Send-Pr-Version: www-2.3

>Number:         100881
>Category:       kern
>Synopsis:       [libarchive] [patch] 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:    kientzle
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Wed Jul 26 13:30:10 GMT 2006
>Closed-Date:    Tue Sep 05 05:56:32 GMT 2006
>Last-Modified:  Tue Sep 05 05:56:32 GMT 2006
>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@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:
Responsible-Changed-From-To: freebsd-bugs->kientzle 
Responsible-Changed-By: arved 
Responsible-Changed-When: Sat Jul 29 21:31:21 UTC 2006 
Responsible-Changed-Why:  
Over to maintainer 

http://www.freebsd.org/cgi/query-pr.cgi?pr=100881 
State-Changed-From-To: open->patched 
State-Changed-By: kientzle 
State-Changed-When: Mon Aug 7 06:20:24 UTC 2006 
State-Changed-Why:  
Proposed fix committed to -CURRENT. 

Another set of related fixes are being tested and will 
be committed to -CURRENT soon. 



http://www.freebsd.org/cgi/query-pr.cgi?pr=100881 
State-Changed-From-To: patched->closed 
State-Changed-By: kientzle 
State-Changed-When: Tue Sep 5 05:55:51 UTC 2006 
State-Changed-Why:  
MFCed to 6-STABLE 

http://www.freebsd.org/cgi/query-pr.cgi?pr=100881 
>Unformatted:
