From nobody@FreeBSD.org  Sat Mar 31 22:41:30 2007
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52])
	by hub.freebsd.org (Postfix) with ESMTP id CD77616A403
	for <freebsd-gnats-submit@FreeBSD.org>; Sat, 31 Mar 2007 22:41:30 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (www.freebsd.org [69.147.83.33])
	by mx1.freebsd.org (Postfix) with ESMTP id A69C213C48C
	for <freebsd-gnats-submit@FreeBSD.org>; Sat, 31 Mar 2007 22:41:30 +0000 (UTC)
	(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 l2VMfUbW004122
	for <freebsd-gnats-submit@FreeBSD.org>; Sat, 31 Mar 2007 22:41:30 GMT
	(envelope-from nobody@www.freebsd.org)
Received: (from nobody@localhost)
	by www.freebsd.org (8.13.1/8.13.1/Submit) id l2VMaSkJ003630;
	Sat, 31 Mar 2007 22:36:28 GMT
	(envelope-from nobody)
Message-Id: <200703312236.l2VMaSkJ003630@www.freebsd.org>
Date: Sat, 31 Mar 2007 22:36:28 GMT
From: Patrick Lamaiziere<patpr@davenulle.org>
To: freebsd-gnats-submit@FreeBSD.org
Subject: [libarchive] problem with big file
X-Send-Pr-Version: www-3.0

>Number:         111079
>Category:       kern
>Synopsis:       [libarchive] problem with big file
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    kientzle
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Sat Mar 31 22:50:06 GMT 2007
>Closed-Date:    Sun Apr 01 11:39:28 GMT 2007
>Last-Modified:  Sun Apr  1 23:20:04 GMT 2007
>Originator:     Patrick Lamaiziere
>Release:        6.2-RELEASE
>Organization:
>Environment:
FreeBSD roxette.lamaiziere.net 6.2-RELEASE-p3 FreeBSD 6.2-RELEASE-p3 #0: Sat Mar 24 14:08:07 CET 2007     patrick@roxette.lamaiziere.net:/usr/obj/usr/src/sys/GENERIC  i386

>Description:
With a .tar file that include a big file (6 Go), bsdtar fails to extract
or list the files into the archive because a bug into libarchive :
 
$ tar tf samba.tar
[...]
samba/bigfile.rar
tar: (Empty error message)

$ truss tf samba.tar
write(1,"\n",1)                                  = 1 (0x1)
samba/bigfile.rarwrite(1,"samba/bigfile.rar"...,79) = 79 (0x4f)
lseek(3,0x0,SEEK_CUR)                            = 843239424 (0x3242d000)
lseek(3,0x846ca000,SEEK_CUR)                     = -1230016512 (0xb6af7000)

write(1,"\n",1)                                  = 1 (0x1)
tar: write(2,"tar: ",5)                          = 5 (0x5)
(Empty error message)write(2,"(Empty error message)",21) = 21 (0x15)

--------------------

I think the problem is into the "file_skip" functions because this is the
only place where there are two lseek(). I don't know witch one : there is
one function into "archive_read_open_fd.c" and the other into
"archive_read_open_file.c". Anyway they are similar:

file archive_read_open_fd.c :

static ssize_t
file_skip(struct archive *a, void *client_data, size_t request)
{
        struct read_fd_data *mine = client_data;
        off_t old_offset, new_offset;

        /* Reduce request to the next smallest multiple of block_size */
        request = (request / mine->block_size) * mine->block_size;
        /*
         * Hurray for lazy evaluation: if the first lseek fails, the second
         * one will not be executed.
         */
        if (((old_offset = lseek(mine->fd, 0, SEEK_CUR)) < 0) ||
            ((new_offset = lseek(mine->fd, request, SEEK_CUR)) < 0))
        {
[...CUT...]
        return (new_offset - old_offset);
}

The result is a ssize_t (int32) and new_offset, old_offset are off_t (int64)
There is an owerflow here :
from truss :
lseek(3,0x0,SEEK_CUR)                            = 843239424 (0x3242d000)
lseek(3,0x846ca000,SEEK_CUR)                     = -1230016512 (0xb6af7000)

So :
new_offset - old_offset
0xb6af7000 - 0x3242d000 = 0x846ca000 => this is a negative value on int32.

I don't know how to solve this problem, sorry.

Also, may be it would be better to compare lseek() == -1 instead lseek () < 0 ?

Best regards.
>How-To-Repeat:
list or extract big files (several Go) from a .tar with bsdtar.

$tar tf tar_with_big_file.tar
>Fix:

>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: freebsd-bugs->kientzle 
Responsible-Changed-By: linimon 
Responsible-Changed-When: Sun Apr 1 00:30:39 UTC 2007 
Responsible-Changed-Why:  
Over to maintainer. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=111079 
State-Changed-From-To: open->closed 
State-Changed-By: linimon 
State-Changed-When: Sun Apr 1 11:39:04 UTC 2007 
State-Changed-Why:  
cperciva reports that this problem has already been fixed, but thanks 
for the report. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=111079 

From: Colin Percival <cperciva@freebsd.org>
To: bug-followup@FreeBSD.org, patpr@davenulle.org
Cc:  
Subject: Re: kern/111079
Date: Sun, 01 Apr 2007 15:19:06 -0700

 Just to get this attached to the PR in case anyone looks at it later:
 
 > Tim Kientzle wrote:
 >>> >> With a .tar file that include a big file (6 Go),
 >>> >> bsdtar fails to extract or list the files ...
 >> > 
 >> > I believe this is fixed in both 6-STABLE and -CURRENT.
 >> > Colin Percival did some work in this
 >> > area a little while ago.
 > 
 > Yes, it should now work in -CURRENT due to the change to use off_t
 > for client skip functions, and should now work in RELENG_6 due to
 > archive_decompressor_none_skip not asking the client skip function
 > to handle anything larger than SSIZE_MAX bytes.
 > 
 > Colin Percival
>Unformatted:
