[PATCH v3] libio: asprintf should write NULL upon failure

Solar Designer solar@openwall.com
Sun Aug 11 23:34:40 GMT 2024


On Sat, Aug 03, 2024 at 06:31:01PM +0200, Solar Designer wrote:
> Cc: Alan Coopersmith who helped get this into POSIX.
> 
> On Sat, Aug 03, 2024 at 01:08:37PM +0200, Florian Weimer wrote:
> > * Solar Designer:
> > 
> > >> +++ b/manual/stdio.texi
> > >> @@ -2524,7 +2524,9 @@ Allocation}) to hold the output, instead of putting the output in a
> > >>  buffer you allocate in advance.  The @var{ptr} argument should be the
> > >>  address of a @code{char *} object, and a successful call to
> > >>  @code{asprintf} stores a pointer to the newly allocated string at that
> > >> -location.
> > >> +location.  Current versions of @theglibc{} write a null pointer to
> > >> +@samp{*@var{ptr}} upon failure, but this is not required by the
> > >> +standard, and previous versions did not modify the pointer value.
> > >
> > > This makes it sound as if previous versions always did not modify the
> > > pointer value, but e.g. 2.34 would sometimes leave the pointer value
> > > unmodified and other times reset it to NULL.  I suggest replacing "did
> > > not modify the pointer value." with "sometimes left the pointer value
> > > unmodified.  Callers are required to check the function's return
> > > value."
> > 
> > I reviewed the older implementations, and I think we can say this, which
> > I think is more helpful to the programmer:
> > 
> > ???
> > Current and future versions of @theglibc{} write a null pointer to
> > @samp{*@var{ptr}} upon failure.  To achieve similar behavior with
> > previous versions, initialize @samp{*@var{ptr}} to a null pointer before
> > calling @code{asprintf}.
> > ???
> > 
> > What do you think?  Based on my review, even in the older
> > implementations, we never wrote a non-null pointer, proceeded to free
> > it, and then returned failure.  All the reallocation work was kept track
> > of in internal pointers, and the ptr argument was only used after the
> > format string had been processed.
> 
> On one hand, I agree this is probably right for glibc - at least I'm not
> aware of a counter-example.
> 
> On the other hand, it isn't sound advice to give to people writing code
> that might run on non-glibc.  POSIX doesn't guarantee any of this.
> 
> We could maybe include a wording closer to POSIX, which says:
> 
> "For asprintf(), if memory allocation was not possible, or if some other
> error occurs, the function shall return a negative value, and the
> contents of the location referenced by ptr are undefined, but shall not
> refer to allocated memory."
> 
> where by "shall not refer to allocated memory" I think they actually
> mean that asprintf() does not leak memory on error.
> 
> My current suggestion is a slight extension of my previous one:
> 
> Current versions of @theglibc{} write a null pointer to
> @samp{*@var{ptr}} upon failure, but this is not required by the
> standard, and previous versions sometimes left the pointer value
> unmodified.  Code portable across @theglibc{} versions and other
> systems should rely solely on the function's return value as
> indicator of success or failure.  Negative return value means the
> call has failed, the pointer value is undefined, and no memory is
> allocated.

What's the status on this?  I didn't mean to delay getting the code
change merged by my comments on the documentation.

Alexander


More information about the Libc-alpha mailing list