[RFC v1] libio/: Add [v]aprintf()

Alejandro Colomar alx@kernel.org
Wed Mar 18 01:17:42 GMT 2026


Hi Adhemerval,

On 2026-03-17T16:56:24-0300, Adhemerval Zanella Netto wrote:
> 
> 
> On 17/03/26 16:40, Alejandro Colomar wrote:
> > Hi Adhemerval,
> > 
> > On 2026-03-17T16:26:06-0300, Adhemerval Zanella Netto wrote:
> >>
> >>> 	Projects have come up with APIs for this over time.  GNU and the
> >>> 	BSDs have it as asprintf(3), but there seems to be consensus
> >>> 	that this API isn't very well designed; evidence of this is that
> >>> 	the behavior is slightly different in the various
> >>> 	implementations, and has changes through history.
> >>
> >> Could you add more details of what is wrong with the current asprintf glibc
> >> implementation, besides the initial designed limitation ('int' return i
> >> nstead of ssize_t)?
> >>
> >> We don't have any bugs against asprintf on glibc bugzilla.
> > 
> > Here are three issues of asprintf(3) from the top of my head:
> > 
> > -  Quite often, it's used together with strdup(3) in some conditional.
> >    Compare:
> > 
> > 	if (cond) {
> > 		dup = strdup(s)
> > 		if (dup == NULL)
> > 			goto fail;
> > 	} else {
> > 		if (asprintf(&dup, "...", s, ...) < 0)
> > 			goto fail;
> > 	}
> >    vs
> > 	if (cond)
> > 		dup = strdup(s);
> > 	else
> > 		dup = aprintf("...", s, ...);
> > 	if (dup == NULL)
> > 		goto fail;
> > 
> >    The code using aprintf(3) is much simpler and more readable.  This
> >    means it has less chances of having bugs.
> > 
> >    And even in uses not tied to strdup(3), the double-pointer weirdness
> >    make it unnecessarily complex.
> > 
> > -  Some BSDs guarantee that asprintf(3) sets the pointer to NULL on
> >    error.  When porting BSD code to GNU, that could result in bugs
> >    (reding an uninitialized pointer).  I expect this to be unlikely,
> >    because why would one ever use the pointer after the call failed, but
> >    not impossible.

Actually, while working on the documentation of aprintf(3), I was
git-blame(1)ing the current documentation of asprintf(3), and I found
that people have actually been bitten by this.  It seems to be a real
issue.

	commit cb4692ce1edd5a81c2521de49dfef6125141d1c7
	Author: Florian Weimer <fweimer@redhat.com>
	Date:   2024-12-27 09:17:41 +0100

	    libio: asprintf should write NULL upon failure
	    
	    This was suggested most recently by Solar Designer, noting
	    that code replacing vsprintf with vasprintf in a security fix
	    was subtly wrong:
	    
	      Re: GStreamer Security Advisory 2024-0003: Orc compiler
	      stack-based buffer overflow
	      <https://www.openwall.com/lists/oss-security/2024/07/26/2>
	    
	    Previous libc-alpha discussions:
	    
	      I: [PATCH] asprintf error handling fix
	      <https://inbox.sourceware.org/libc-alpha/20011205185828.GA8376@ldv.office.alt-linux.org/>
	    
	      asprintf() issue
	      <https://inbox.sourceware.org/libc-alpha/CANSoFxt-cdc-+C4u-rTENMtY4X9RpRSuv+axDswSPxbDgag8_Q@mail.gmail.com/>
	    
	    I don't think we need a compatibility symbol for this.  As the
	    GStreamer example shows, this change is much more likely to fix bugs
	    than cause compatibility issues.
	    
	    Suggested-by: Dmitry V. Levin <ldv@altlinux.org>
	    Suggested-by: Archie Cobbs <archie.cobbs@gmail.com>
	    Suggested-by: Solar Designer <solar@openwall.com>
	    Reviewed-by: Sam James <sam@gentoo.org>

I've added these people to CC.

> > 
> > -  aprintf(3), by returning the newly allocated pointer, allows using
> >    [[gnu::malloc(free)]], which would improve static analysis, being
> >    able to detect leaks, double-free's, and other related bugs.
> 
> I would say this the only compelling reason to provide this symbol, since
> the first is a more a stylist one (and subject to endless discussion), and
> second I would consider a user error instead of a glibc one.

I tend to agree, but users make mistakes if APIs allow them to, and the
asprintf(3) API was unnecessarily promoting them.  aprintf(3) is free of
such issues, by design.


Have a lovely night!
Alex

> 
> > 
> >> On 17/03/26 15:59, Alejandro Colomar wrote:
> >>> Signed-off-by: Alejandro Colomar <alx@kernel.org>
> >>> ---
> >>>
> >>> Hi Paul, Joseph,
> >>>
> >>> Since nobody replied, I guess people are not strongly opposed to it, but
> >>> they probably want to see a patch before spending time with this.
> >>>
> >>> Thus, I've written a patch (or a draft of a patch).
> >>>
> >>> This is the first time I add a function to glibc, and I find it quite
> >>> difficult, so I'll need some help.  I've added the most obvious pieces:
> >>> the prototypes and the implementation.  However, this doesn't work at
> >>> all, so I guess I'm missing stuff.  Would you mind helping me figure out
> >>> what I'm missing (or what's wrong)?
> >>>
> >>> I tried building this simple test program, but I get linker errors:
> >>
> >> You need to export the symbol by adding a version tag and its name on
> >> stdio-common/Versions.
> > 
> > Thanks!  I'll try.
> > 
> >> I don't have a strong opinion about this, albeit since gnulib is already
> >> providing and that committee has shown interest I would way for C standard
> >> inclusion. 
> > 
> > I don't think we want that.  The committee is bad at choosing names, and
> > would probably end up choosing a bad name.  Now that we're in time to
> > pick a name before the committee decides, we should do it, and then tell
> > the committee about it so that it uses the same name.
> > 
> > In fact, gnulib added it as aprintf(3) precisely for that reason.
> 
> I would refrain to make this kind of judgement ("bad at choosing names") because
> it only adds contention on discussing a technical inclusion.
> 
> Before adding this it would be helpful to hear other maintainers, but I inclined
> to consider this addition.
> 

-- 
<https://www.alejandro-colomar.es>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <https://sourceware.org/pipermail/libc-alpha/attachments/20260318/2abaa9ae/attachment.sig>


More information about the Libc-alpha mailing list