Tobias, On 5/21/20 2:15 PM, Tobias Stoeckmann wrote: > The function make_message illustrates how to use vsnprintf to determine > the required amount of memory for a specific format and its arguments. > > If make_message is called with a format which will use exactly INT_MAX > characters (excluding '\0'), then the size++ calculation will overflow > the signed integer "size", which is an undefined behaviour in C. > > Since malloc and vsnprintf rightfully take a size_t argument, I decided > to use a size_t variable for size calculation. Therefore, this patched > code uses variables of the same data types as expected by function > arguments. > > Proof of concept (tested on Linux/glibc amd64): > > int main() { make_message("%647s%2147483000s", "", ""); } > > If the code is compiled with address sanitizer (gcc -fsanitize=address) > you can see the following line, assuming that a signed integer overflow > simply leads to INT_MIN: > > ==3094==WARNING: AddressSanitizer failed to allocate 0xffffffff80000000 bytes Thanks for the nicely documented patch. Applied. Cheers, Michael > --- > man3/printf.3 | 15 +++++++++------ > 1 file changed, 9 insertions(+), 6 deletions(-) > > diff --git a/man3/printf.3 b/man3/printf.3 > index 50e136ba6..827d9cbae 100644 > --- a/man3/printf.3 > +++ b/man3/printf.3 > @@ -1132,29 +1132,32 @@ To allocate a sufficiently large string and print into it > char * > make_message(const char *fmt, ...) > { > - int size = 0; > + int n = 0; > + size_t size = 0; > char *p = NULL; > va_list ap; > > /* Determine required size */ > > va_start(ap, fmt); > - size = vsnprintf(p, size, fmt, ap); > + n = vsnprintf(p, size, fmt, ap); > va_end(ap); > > - if (size < 0) > + if (n < 0) > return NULL; > > - size++; /* For '\e0' */ > + /* One extra byte for '\e0' */ > + > + size = (size_t) n + 1; > p = malloc(size); > if (p == NULL) > return NULL; > > va_start(ap, fmt); > - size = vsnprintf(p, size, fmt, ap); > + n = vsnprintf(p, size, fmt, ap); > va_end(ap); > > - if (size < 0) { > + if (n < 0) { > free(p); > return NULL; > } > -- Michael Kerrisk Linux man-pages maintainer; http://www.kernel.org/doc/man-pages/ Linux/UNIX System Programming Training: http://man7.org/training/