about summary refs log tree commit diff
path: root/misc/syslog.c
diff options
context:
space:
mode:
authorAdhemerval Zanella <adhemerval.zanella@linaro.org>2022-08-28 16:52:53 -0300
committerAdhemerval Zanella <adhemerval.zanella@linaro.org>2022-08-30 08:54:52 -0300
commit52a5be0df411ef3ff45c10c7c308cb92993d15b1 (patch)
treec0271ff8400922bf9f559fb10d62cd3d0fb9d62d /misc/syslog.c
parentddcf5a9170a0db5055259118f3090debab248126 (diff)
downloadglibc-52a5be0df411ef3ff45c10c7c308cb92993d15b1.tar.gz
glibc-52a5be0df411ef3ff45c10c7c308cb92993d15b1.tar.xz
glibc-52a5be0df411ef3ff45c10c7c308cb92993d15b1.zip
syslog: Fix large messages (BZ#29536)
The a583b6add407c17cd change did not handle large messages that
would require a heap allocation correctly, where the message itself
is not take in consideration.

This patch fixes it and extend the tst-syslog to check for large
messages as well.

Checked on x86_64-linux-gnu.

Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
Diffstat (limited to 'misc/syslog.c')
-rw-r--r--misc/syslog.c18
1 files changed, 11 insertions, 7 deletions
diff --git a/misc/syslog.c b/misc/syslog.c
index 554089bfc4..b88f66c835 100644
--- a/misc/syslog.c
+++ b/misc/syslog.c
@@ -193,28 +193,32 @@ __vsyslog_internal (int pri, const char *fmt, va_list ap,
       int vl = __vsnprintf_internal (bufs + l, sizeof bufs - l, fmt, apc,
                                      mode_flags);
       if (0 <= vl && vl < sizeof bufs - l)
-        {
-          buf = bufs;
-          bufsize = l + vl;
-        }
+        buf = bufs;
+      bufsize = l + vl;
 
       va_end (apc);
     }
 
   if (buf == NULL)
     {
-      buf = malloc (l * sizeof (char));
+      buf = malloc ((bufsize + 1) * sizeof (char));
       if (buf != NULL)
 	{
 	  /* Tell the cancellation handler to free this buffer.  */
 	  clarg.buf = buf;
 
 	  if (has_ts)
-	    __snprintf (bufs, sizeof bufs,
+	    __snprintf (buf, l + 1,
 			SYSLOG_HEADER (pri, timestamp, &msgoff, pid));
 	  else
-	    __snprintf (bufs, sizeof bufs,
+	    __snprintf (buf, l + 1,
 			SYSLOG_HEADER_WITHOUT_TS (pri, &msgoff));
+
+	  va_list apc;
+	  va_copy (apc, ap);
+	  __vsnprintf_internal (buf + l, bufsize - l + 1, fmt, apc,
+				mode_flags);
+	  va_end (apc);
 	}
       else
         {