From: Ken Hornstein Date: Sat, 4 Nov 2017 13:59:18 +0000 (-0400) Subject: Use va_copy() to get a copy of va_list, instead of using original. X-Git-Url: https://diplodocus.org/git/nmh/commitdiff_plain/b47b562525f149f175c3d216feea20a6db2e9ff5?hp=56224eac0c7aa1912b4e0de4fe38b664888f0f2b Use va_copy() to get a copy of va_list, instead of using original. netsec_vprintf() can call vsnprintf() twice if the outgoing buffer is full (but it happens rarely in practice, given the way the current code uses it). But if this DOES happen, vsnprintf() will use the same va_list argument twice, and the second time around either it will grab a random bit of memory off of the stack OR it will segfault. So we always use va_copy() to get our own copy of the passed-in va_list and work on that. --- diff --git a/sbr/netsec.c b/sbr/netsec.c index 01c25f5f..0fb41262 100644 --- a/sbr/netsec.c +++ b/sbr/netsec.c @@ -807,6 +807,7 @@ netsec_vprintf(netsec_context *nsc, char **errstr, const char *format, va_list ap) { int rc; + va_list apcopy; /* * Cheat a little. If we can fit the data into our outgoing buffer, @@ -814,8 +815,10 @@ netsec_vprintf(netsec_context *nsc, char **errstr, const char *format, */ retry: + va_copy(apcopy, ap); rc = vsnprintf((char *) nsc->ns_outptr, - nsc->ns_outbufsize - nsc->ns_outbuflen, format, ap); + nsc->ns_outbufsize - nsc->ns_outbuflen, format, apcopy); + va_end(apcopy); if (rc >= (int) (nsc->ns_outbufsize - nsc->ns_outbuflen)) { /*