[PATCH] libc_fatal: Get rid of alloca

Joe Simmons-Talbott josimmon@redhat.com
Thu Aug 31 12:49:33 GMT 2023


Use scratch_buffers in place of alloca to avoid potential stack overflow.
---
NOTE: I'm not certain that this is the best way to handle allocation
failures by jumping straight to the abort and am open to other
suggestions.

 sysdeps/posix/libc_fatal.c | 27 +++++++++++++++++++++++++--
 1 file changed, 25 insertions(+), 2 deletions(-)

diff --git a/sysdeps/posix/libc_fatal.c b/sysdeps/posix/libc_fatal.c
index 70edcc10c1..f8e2df4157 100644
--- a/sysdeps/posix/libc_fatal.c
+++ b/sysdeps/posix/libc_fatal.c
@@ -21,6 +21,7 @@
 #include <fcntl.h>
 #include <ldsodefs.h>
 #include <paths.h>
+#include <scratch_buffer.h>
 #include <stdarg.h>
 #include <stdbool.h>
 #include <stdio.h>
@@ -58,6 +59,10 @@ __libc_message (const char *fmt, ...)
 {
   va_list ap;
   int fd = -1;
+  struct scratch_buffer sbuf;
+  scratch_buffer_init (&sbuf);
+  int newp_idx = 0;
+  struct str_list *_newp = sbuf.data;
 
   va_start (ap, fmt);
 
@@ -70,6 +75,8 @@ __libc_message (const char *fmt, ...)
 
   struct str_list *list = NULL;
   int nlist = 0;
+  struct scratch_buffer iovec_buf;
+  scratch_buffer_init (&iovec_buf);
 
   const char *cp = fmt;
   while (*cp != '\0')
@@ -100,17 +107,30 @@ __libc_message (const char *fmt, ...)
 	  cp = next;
 	}
 
-      struct str_list *newp = alloca (sizeof (struct str_list));
+      struct str_list *newp = _newp + newp_idx;
+      if ((void *) newp > sbuf.data + sbuf.length)
+        {
+	  if (!scratch_buffer_grow_preserve (&sbuf))
+	    goto fail_out;
+	  _newp = sbuf.data;
+	  newp = _newp + newp_idx;
+	}
       newp->str = str;
       newp->len = len;
       newp->next = list;
       list = newp;
       ++nlist;
+      ++newp_idx;
     }
 
   if (nlist > 0)
     {
-      struct iovec *iov = alloca (nlist * sizeof (struct iovec));
+      if (!scratch_buffer_set_array_size (&iovec_buf,
+			                  nlist, sizeof (struct iovec)))
+	goto fail_out;
+
+      struct iovec *iov = iovec_buf.data;
+
       ssize_t total = 0;
 
       for (int cnt = nlist - 1; cnt >= 0; --cnt)
@@ -146,6 +166,9 @@ __libc_message (const char *fmt, ...)
 
   va_end (ap);
 
+fail_out:
+  scratch_buffer_free (&sbuf);
+  scratch_buffer_free (&iovec_buf);
   /* Kill the application.  */
   abort ();
 }
-- 
2.39.2



More information about the Libc-alpha mailing list