]> git.sur5r.net Git - i3/i3/commitdiff
log: avoid buffer overflow in vlog 1944/head
authorNils Schneider <nils@nilsschneider.net>
Mon, 21 Sep 2015 12:27:22 +0000 (14:27 +0200)
committerNils Schneider <nils@nilsschneider.net>
Mon, 21 Sep 2015 12:27:22 +0000 (14:27 +0200)
`vlog()` can not handle log messages longer than 4096 bytes. However, the
message generated in `store_restart_layout()` is likely to exceed this
as it contains a long JSON string.

This has caused a few SEGFAULTS during restarts for me when running with
`-d all`.

Fix this by truncating the message to 4096 bytes and punching in a newline at
the end.

src/log.c

index 7cf988438063ca5df2aaacce329e7d1e35224cb6..856330b6d4a8ea4ebe0c353d5aecd906296fd921 100644 (file)
--- a/src/log.c
+++ b/src/log.c
@@ -246,6 +246,15 @@ static void vlog(const bool print, const char *fmt, va_list args) {
         len += vsnprintf(message + len, sizeof(message) - len, fmt, args);
         if (len >= sizeof(message)) {
             fprintf(stderr, "BUG: single log message > 4k\n");
+
+            /* vsnprintf returns the number of bytes that *would have been written*,
+             * not the actual amount written. Thus, limit len to sizeof(message) to avoid
+             * memory corruption and outputting garbage later.  */
+            len = sizeof(message);
+
+            /* Punch in a newline so the next log message is not dangling at
+             * the end of the truncated message. */
+            message[len - 2] = '\n';
         }
 
         /* If there is no space for the current message in the ringbuffer, we