[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Bug-tar] getline() differences FreeBSD / GNU libc

From: Eric Blake
Subject: Re: [Bug-tar] getline() differences FreeBSD / GNU libc
Date: Tue, 26 Jan 2010 06:21:43 -0700
User-agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv: Gecko/20090812 Thunderbird/ Mnenhy/

[adding bug-gnulib, as the source of tar's getline replacement]

According to noordsij on 1/21/2010 6:37 AM:
> Dear GNU tar maintainer(s) / fBSD gtar port maintainer(s),
> The problem appears to be a difference in getline() behaviour in the fBSD
> and GNU libc.
> fBSD: The
>      caller may provide a pointer to a malloc buffer for the line in
> *linep,
>      and the capacity of that buffer in *linecapp; if *linecapp is 0, then
>      *linep is treated as NULL.
> GNU:  If  *lineptr  is  NULL,  then  getline() will allocate a buffer for
> storing the line, which
>        should be freed by the user program.  (The value in *n is ignored.)

POSIX states:

The application shall ensure that *lineptr is a valid argument that could
be passed to the free() function. If *n is non-zero, the application shall
ensure that *lineptr either points to an object of size at least *n bytes,
or is a null pointer.

> So fBSD libc looks at the value of linecapp, whereas GNU libc looks at the
> value of lineptr, to determine whether to allocate a new buffer or use a
> provided one. In the tar source, linecapp (bufsize) is not initialized,
> lineptr (buf) is.
> The fix is to simply initialize bufsize to 0 as well, to make (line
> 1232-1233):
>   char *buf = 0;
>   size_t bufsize = 0;

FreeBSD is buggy.  Rewording the POSIX requirement slightly: if lineptr is
NULL, then it is irrelevant that linecapp is non-zero.  Gnulib needs to
work around this portability flaw, and guarantee a working getline
implementation even on fBSD, at which point, your patch to tar to
explicitly initialize bufsize to 0 is unnecessary.

That said, your patch to tar doesn't hurt; and besides, some
implementations of getline use linecapp as a hint of how large to make the
initial allocation, so passing uninitialized bufsize will potentially
cause different allocation behavior (although any decent implementation
that uses bufsize as an initial hint should also be prepared to ignore
that hint if it is too far out of bounds, so it should never provoke
ENOMEM by itself).

Don't work too hard, make some time for fun as well!

Eric Blake             address@hidden

Attachment: signature.asc
Description: OpenPGP digital signature

reply via email to

[Prev in Thread] Current Thread [Next in Thread]