From b47b562525f149f175c3d216feea20a6db2e9ff5 Mon Sep 17 00:00:00 2001 From: Ken Hornstein Date: Sat, 4 Nov 2017 09:59:18 -0400 Subject: [PATCH] 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. --- sbr/netsec.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) 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)) { /* -- 2.56.0