From owner-freebsd-bugs@FreeBSD.ORG Sat Mar 31 22:50:07 2007 Return-Path: X-Original-To: freebsd-bugs@hub.freebsd.org Delivered-To: freebsd-bugs@hub.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id B824D16A4ED for ; Sat, 31 Mar 2007 22:50:07 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [69.147.83.40]) by mx1.freebsd.org (Postfix) with ESMTP id 9029013C45B for ; Sat, 31 Mar 2007 22:50:07 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (gnats@localhost [127.0.0.1]) by freefall.freebsd.org (8.13.4/8.13.4) with ESMTP id l2VMo7rf064577 for ; Sat, 31 Mar 2007 22:50:07 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.13.4/8.13.4/Submit) id l2VMo7KR064576; Sat, 31 Mar 2007 22:50:07 GMT (envelope-from gnats) Resent-Date: Sat, 31 Mar 2007 22:50:07 GMT Resent-Message-Id: <200703312250.l2VMo7KR064576@freefall.freebsd.org> Resent-From: FreeBSD-gnats-submit@FreeBSD.org (GNATS Filer) Resent-To: freebsd-bugs@FreeBSD.org Resent-Reply-To: FreeBSD-gnats-submit@FreeBSD.org, Patrick Lamaiziere Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id CD77616A403 for ; 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 ; 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 ; 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 To: freebsd-gnats-submit@FreeBSD.org X-Send-Pr-Version: www-3.0 Cc: Subject: bin/111079: [libarchive] problem with big file X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 31 Mar 2007 22:50:07 -0000 >Number: 111079 >Category: bin >Synopsis: [libarchive] problem with big file >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: Sat Mar 31 22:50:06 GMT 2007 >Closed-Date: >Last-Modified: >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: >Unformatted: