Subject: Re: lib/35401
To: None <lib-bug-people@netbsd.org, gnats-admin@netbsd.org,>
From: Felix von Leitner <felix-bsd@fefe.de>
List: netbsd-bugs
Date: 01/11/2007 23:00:04
The following reply was made to PR lib/35401; it has been noted by GNATS.

From: Felix von Leitner <felix-bsd@fefe.de>
To: Thorsten Glaser <tg@mirbsd.de>
Cc: gnats-bugs@NetBSD.org, Benny Siegert <bsiegert@MirBSD.org>
Subject: Re: lib/35401
Date: Thu, 11 Jan 2007 22:11:17 +0100

 Thus spake Thorsten Glaser (tg@mirbsd.de):
 > (Adding Felix himself to the discussion, maybe he's got
 > some more ideas.)
 
 Uh, I might be missing some context here.
 
 > >Since errno is not set, I think this isn't recognized as an error (even
 > >with negative return value).  Could be naughty, couldn't it?
 > According to (my) TFM, only -1 is an error.
 
 Nope.  Single Unix Spec v3 says:
 
      If an output error was encountered, these functions shall return a
      negative value.
 
 > >For what it's worth, this has undefined behaviour even though it probably just
 > >works with the current GCC.
 > Hm, "in theory" true, but "our" integers are 32 bits, and
 > the new value is either larger or equal, or it isn't.
 
 > The point of my patch is not to check if it's below zero,
 > but - and that is the actual thing mentioned by fefe - if
 > it is smaller. If you continue to play the game, you will
 > find ways to make asprintf() allocate less memory than is
 > needed.
 
 Don't get to caught up with the negative thing.  I just used that to
 illustrate the problem.  I could just as well give you
 
   sprintf(NULL,0,"%*d %*d  ",0x7fffffff,1,0x7fffffff,1)
 
 and in this case it would wrap to a positive value.  If you then use
 that to allocate the destination buffer for a sprintf, you are 0wned.
 
 Also, if you find a way to make asprintf allocate less memory than it
 needs, that's a bug that needs to be fixed.
 
 > Setting errno to ERANGE sounds feasible, though.
 
 Susv3 doesn't say anything about setting errno.
 
 Please note that checking for negativity is not sufficient.  For
 example, assuming width is unsigned (or negative and that's not
 checked before adding, which is really the same case to the CPU),
 
   "0123456789 %*d",0xffffffff
 
 Stupid example, but I hope you get the idea.  You have to check if the
 new value (after adding) is larger than the previous one.  If it isn't,
 you just had an int overflow.
 
 Felix