aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdhemerval Zanella <adhemerval.zanella@linaro.org>2017-09-18 09:26:00 -0300
committerAdhemerval Zanella <adhemerval.zanella@linaro.org>2017-09-25 18:04:22 -0700
commit5f9f31ad129d97e6fc548954c9b97e27dd332600 (patch)
treeb7f30d51192c046e0d23b6a04346d6549c9cb24f
parentccf970c7a77e86f4f5ef8ecc5e637114b1c0136a (diff)
downloadglibc-5f9f31ad129d97e6fc548954c9b97e27dd332600.tar
glibc-5f9f31ad129d97e6fc548954c9b97e27dd332600.tar.gz
glibc-5f9f31ad129d97e6fc548954c9b97e27dd332600.tar.bz2
glibc-5f9f31ad129d97e6fc548954c9b97e27dd332600.zip
scratch_buffer: use union for internal buffer
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
-rw-r--r--ChangeLog6
-rw-r--r--include/scratch_buffer.h6
-rw-r--r--malloc/scratch_buffer_grow_preserve.c4
-rw-r--r--malloc/tst-scratch_buffer.c2
4 files changed, 12 insertions, 6 deletions
diff --git a/ChangeLog b/ChangeLog
index 416d673523..67394882e4 100644
--- 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.
diff --git a/include/scratch_buffer.h b/include/scratch_buffer.h
index bb04662eb2..b19b166080 100644
--- a/include/scratch_buffer.h
+++ b/include/scratch_buffer.h
@@ -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);
}
diff --git a/malloc/scratch_buffer_grow_preserve.c b/malloc/scratch_buffer_grow_preserve.c
index 9268615311..59a922b8a9 100644
--- a/malloc/scratch_buffer_grow_preserve.c
+++ b/malloc/scratch_buffer_grow_preserve.c
@@ -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
{
diff --git a/malloc/tst-scratch_buffer.c b/malloc/tst-scratch_buffer.c
index 5c9f3442ae..86447b6230 100644
--- a/malloc/tst-scratch_buffer.c
+++ b/malloc/tst-scratch_buffer.c
@@ -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);