From d8da993a73943390ccda275449eccf90cc10c248 Mon Sep 17 00:00:00 2001 From: Dmitry Podgorny Date: Thu, 8 Sep 2016 14:17:03 +0300 Subject: [PATCH] Don't write outside a buffer boundary When xmpp_vsnprintf() received count == 0 it still performs write to the buffer. This leads to a write outside allocated memory, when xmpp_stanza_to_text() parses a specific stanza. Because of error in _render_update() writing exactly buflen+1 with xmpp_snprintf() is counted as valid operation and next xmpp_snprintf will be performed to a buffer with zero length. This leads to wrong rendering of 1024-length stanzas and invalid write for specific larger stanzas: ==22436== Invalid write of size 1 ==22436== at 0x4E4B3A1: xmpp_vsnprintf (snprintf.c:709) ==22436== by 0x4E4B479: xmpp_snprintf (snprintf.c:722) ==22436== by 0x4E4C011: _render_stanza_recursive (stanza.c:328) ==22436== by 0x4E4C3B3: _render_stanza_recursive (stanza.c:384) ==22436== by 0x4E4C3B3: _render_stanza_recursive (stanza.c:384) ==22436== by 0x4E4C3B3: _render_stanza_recursive (stanza.c:384) ==22436== by 0x4E4C3B3: _render_stanza_recursive (stanza.c:384) ==22436== by 0x4E4C3B3: _render_stanza_recursive (stanza.c:384) ==22436== by 0x4E4C4E5: xmpp_stanza_to_text (stanza.c:435) ==22436== by 0x4E407A8: _handle_stream_stanza (conn.c:1157) ==22436== by 0x4E4EF2B: _end_element (parser_expat.c:157) ==22436== by 0x571005A: doContent (in /usr/lib64/libexpat.so.1.6.2) ==22436== Address 0x63b95b0 is 0 bytes after a block of size 1,024 alloc'd ==22436== at 0x4C2BFE0: malloc (vg_replace_malloc.c:299) ==22436== by 0x4E41947: _malloc (ctx.c:116) ==22436== by 0x4E41A54: xmpp_alloc (ctx.c:204) ==22436== by 0x4E4C4A3: xmpp_stanza_to_text (stanza.c:428) ==22436== by 0x4E407A8: _handle_stream_stanza (conn.c:1157) ==22436== by 0x4E4EF2B: _end_element (parser_expat.c:157) ==22436== by 0x571005A: doContent (in /usr/lib64/libexpat.so.1.6.2) ==22436== by 0x57109FB: contentProcessor (in ... ==22436== by 0x5712A9F: XML_ParseBuffer (in ... ==22436== by 0x4E4F1E7: parser_feed (parser_expat.c:247) ==22436== by 0x4E42BBC: xmpp_run_once (event.c:284) ==22436== by 0x4E42D62: xmpp_run (event.c:336) Fix xmpp_vsnprintf() and _render_update() behaviour. --- src/snprintf.c | 2 +- src/stanza.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/snprintf.c b/src/snprintf.c index e018edb..3e854e5 100644 --- a/src/snprintf.c +++ b/src/snprintf.c @@ -705,7 +705,7 @@ static int dopr_outch (char *buffer, size_t *currlen, size_t maxlen, char c) int xmpp_vsnprintf (char *str, size_t count, const char *fmt, va_list args) { - if (str != NULL) + if (str != NULL && count > 0) str[0] = 0; return dopr(str, count, fmt, args); } diff --git a/src/stanza.c b/src/stanza.c index 38af9ac..036f478 100644 --- a/src/stanza.c +++ b/src/stanza.c @@ -291,7 +291,7 @@ static inline void _render_update(int *written, const int length, { *written += lastwrite; - if (*written > length) { + if (*written >= length) { *left = 0; *ptr = NULL; } else {