]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
scratch_buffer: use union for internal buffer
authorAdhemerval Zanella <adhemerval.zanella@linaro.org>
Mon, 18 Sep 2017 12:26:00 +0000 (09:26 -0300)
committerAdhemerval Zanella <adhemerval.zanella@linaro.org>
Tue, 26 Sep 2017 01:04:22 +0000 (18:04 -0700)
Problem reported by Florian Weimer [1] and solution suggested by
Andreas Schwab [2].  It also set the same buffer size independent
of architecture max_align_t size.

Checked on x86_64-linux-gnu and i686-linux-gnu.

* lib/malloc/scratch_buffer.h (struct scratch_buffer):
Use an union instead of a max_align_t array for __space,
so that __space is the same size on all platforms.
* malloc/scratch_buffer_grow_preserve.c
(__libc_scratch_buffer_grow_preserve): Likewise.

[1] https://sourceware.org/ml/libc-alpha/2017-09/msg00693.html
[2] https://sourceware.org/ml/libc-alpha/2017-09/msg00695.html

ChangeLog
include/scratch_buffer.h
malloc/scratch_buffer_grow_preserve.c
malloc/tst-scratch_buffer.c

index 416d6735232ff8b2c4032cc93a88017571ef38de..67394882e4242d8f7df681035c1b156db1874379 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
 2017-09-25  Adhemerval Zanella  <adhemerval.zanella@linaro.org>
 
+       * lib/malloc/scratch_buffer.h (struct scratch_buffer):
+       Use an union instead of a max_align_t array for __space,
+       so that __space is the same size on all platforms.
+       * malloc/scratch_buffer_grow_preserve.c
+       (__libc_scratch_buffer_grow_preserve): Likewise.
+
        [BZ #22183]
        * include/gnu-versions.h (_GNU_GLOB_INTERFACE_VERSION): Increase
        version to 2.
index bb04662eb22e9653e3431a49eeda5ccbc24cf687..b19b16608067a09cddc91f3f905f5142deb65bab 100644 (file)
@@ -66,7 +66,7 @@
 struct scratch_buffer {
   void *data;    /* Pointer to the beginning of the scratch area.  */
   size_t length; /* Allocated space at the data pointer, in bytes.  */
-  max_align_t __space[(1023 + sizeof (max_align_t)) / sizeof (max_align_t)];
+  union { max_align_t __align; char __c[1024]; } __space;
 };
 
 /* Initializes *BUFFER so that BUFFER->data points to BUFFER->__space
@@ -74,7 +74,7 @@ struct scratch_buffer {
 static inline void
 scratch_buffer_init (struct scratch_buffer *buffer)
 {
-  buffer->data = buffer->__space;
+  buffer->data = buffer->__space.__c;
   buffer->length = sizeof (buffer->__space);
 }
 
@@ -82,7 +82,7 @@ scratch_buffer_init (struct scratch_buffer *buffer)
 static inline void
 scratch_buffer_free (struct scratch_buffer *buffer)
 {
-  if (buffer->data != buffer->__space)
+  if (buffer->data != buffer->__space.__c)
     free (buffer->data);
 }
 
index 9268615311f59664c76c6c831f72e1fcef509844..59a922b8a9e2845de525327369038bfe46a98ab0 100644 (file)
@@ -30,14 +30,14 @@ __libc_scratch_buffer_grow_preserve (struct scratch_buffer *buffer)
   size_t new_length = 2 * buffer->length;
   void *new_ptr;
 
-  if (buffer->data == buffer->__space)
+  if (buffer->data == buffer->__space.__c)
     {
       /* Move buffer to the heap.  No overflow is possible because
         buffer->length describes a small buffer on the stack.  */
       new_ptr = malloc (new_length);
       if (new_ptr == NULL)
        return false;
-      memcpy (new_ptr, buffer->__space, buffer->length);
+      memcpy (new_ptr, buffer->__space.__c, buffer->length);
     }
   else
     {
index 5c9f3442ae8d6ef9627ed56a0f071ba9cb2d4ce7..86447b62303b519dcf3a3cfb3d67019a92c65a21 100644 (file)
@@ -59,7 +59,7 @@ array_size_must_fail (size_t a, size_t b)
                  pass, a, b);
          return false;
        }
-      if (buf.data != buf.__space)
+      if (buf.data != buf.__space.__c)
        {
          printf ("scratch_buffer_set_array_size did not free: %d %zu %zu\n",
                  pass, a, b);