From owner-freebsd-current@FreeBSD.ORG Fri Aug 20 09:41:23 2004 Return-Path: Delivered-To: freebsd-current@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id B825716A4CE for ; Fri, 20 Aug 2004 09:41:23 +0000 (GMT) Received: from kane.otenet.gr (kane.otenet.gr [195.170.0.27]) by mx1.FreeBSD.org (Postfix) with ESMTP id 58AB143D2D for ; Fri, 20 Aug 2004 09:41:20 +0000 (GMT) (envelope-from keramida@linux.gr) Received: from orion.daedalusnetworks.priv (aris.bedc.ondsl.gr [62.103.39.226])i7K9fFT0025471; Fri, 20 Aug 2004 12:41:17 +0300 Received: from orion.daedalusnetworks.priv (orion [127.0.0.1]) i7K9f7UP006860; Fri, 20 Aug 2004 12:41:07 +0300 (EEST) (envelope-from keramida@linux.gr) Received: (from keramida@localhost)i7K9f7c1006859; Fri, 20 Aug 2004 12:41:07 +0300 (EEST) (envelope-from keramida@linux.gr) Date: Fri, 20 Aug 2004 12:41:07 +0300 From: Giorgos Keramidas To: Sean McNeil Message-ID: <20040820094107.GB6606@orion.daedalusnetworks.priv> References: <1092777586.92327.9.camel@server.mcneil.com> <20040817213813.GE3827@gothmog.gr> <1092951447.1167.12.camel@server.mcneil.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1092951447.1167.12.camel@server.mcneil.com> cc: freebsd-current@freebsd.org Subject: Re: bsdtar core dumps X-BeenThere: freebsd-current@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Discussions about the use of FreeBSD-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 20 Aug 2004 09:41:23 -0000 On 2004-08-19 14:37, Sean McNeil wrote: > Here is a backtrace of the error: > > #0 0x0000000200926d7e in __vfprintf (fp=0x7fffffffe360, > fmt0=0x4161d9 "Failed to open '%s'", ap=0x7fffffffe640) > at /usr/src/lib/libc/stdio/vfprintf.c:1052 > #1 0x00000002008c4006 in vsnprintf (str=0x32
, > n=4284889, fmt=0x4161d9 "Failed to open '%s'", ap=0x7fffffffe640) > at /usr/src/lib/libc/stdio/vsnprintf.c:75 > #2 0x0000000000411478 in __archive_string_vsprintf (as=0x520240, > fmt=0x4161d9 "Failed to open '%s'", ap=0x7fffffffe640) > at /usr/src/lib/libarchive/archive_string_sprintf.c:60 > #3 0x00000000004112f5 in archive_set_error (a=0x520000, error_number=2, > fmt=0x0) at /usr/src/lib/libarchive/archive_util.c:133 > #4 0x00000000004080cd in file_open (a=0x520000, client_data=0x4161d9) > at /usr/src/lib/libarchive/archive_read_open_file.c:90 > #5 0x0000000000411639 in archive_read_open (a=0x520000, client_data=0x51e0c0, > opener=0x408060 , reader=0x408130 , > closer=0x408160 ) at /usr/src/lib/libarchive/archive_read.c:124 > #6 0x0000000000408039 in archive_read_open_file (a=0x520000, > filename=0x7fffffffec02 "nonexistent.tar.gz", block_size=10240) > at /usr/src/lib/libarchive/archive_read_open_file.c:75 > #7 0x0000000000403a90 in read_archive (bsdtar=0x7fffffffe8b0, mode=120 'x') > at /usr/src/usr.bin/tar/read.c:86 > #8 0x000000000040398e in tar_mode_x (bsdtar=0x32) > at /usr/src/usr.bin/tar/read.c:62 > #9 0x0000000000402e1a in main (argc=7, argv=0xffffffff) > at /usr/src/usr.bin/tar/bsdtar.c:525 > > Looks like something wrote past the end of a buffer as the str argument > to vsnprintf is not correct. > > (gdb) p *as > $8 = {s = 0x51e100 "", length = 0, buffer_length = 64} > > should be > > str=0x51e100, n=0 > > and on the callback trace it is > > str=0x32
, n=4284889 > > Could be a compiler bug I suppose, but more likely I think it is this > code: > > if (n == 0) { > if (on > 0) > *str = '\0'; > str = dummy; > n = 1; > } I might be wrong here, but looking at the code here's what I managed to understood about the way it works: Originally the value passed as `n' is saved in `on' (original n). Then, only if n != 0, n is decremented. In the special case that (n == 1) the vsnprintf() function can only write up to (n - 1) == 0 bytes to the output buffer, according to its manpage. In this case the check at line 63 (n == 0) will be true after the initial magic in lines 57-61: 57 on = n; 58 if (n != 0) 59 n--; 60 if (n > INT_MAX) 61 n = INT_MAX; 62 /* Stdio internals do not deal correctly with zero length buffer */ 63 if (n == 0) { 64 if (on > 0) 65 *str = '\0'; 66 str = dummy; 67 n = 1; 68 } The code in lines 63-68 is an attempt to pass a buffer with space for at least 1 character to __vfprintf(), in order to let __vfprintf() count the bytes of the buffer that would be used if the size was infinite (as per the manpage). > It seems very inappropriate to be messing with an input parameter like > that and then using an uninitialized string in it's place. Yeah, the dummy[] buffer is uninitialized, but that shouldn't be a problem since it's passed to __vfprintf() with a buffer size of 1 byte. Summing up, there is probably something wrong with the code but it's not the fact that dummy[] is uninitialized. It's more likely that something else is going on. I'm not sure what, though...