From a03950b43cc561107e04217a938f8353b2315592 Mon Sep 17 00:00:00 2001 From: Alex Richardson Date: Wed, 14 Dec 2022 23:55:19 +0000 Subject: [PATCH] GAtomicArray: Ensure metadata does not misalign the payload We have to ensure that the memory location is sufficiently aligned to store any object. This unbreaks the code for CHERI where using gsize results in values that are only aligned to 8 bytes, but we need 16 byte alignment for pointers. This is fully API/ABI compatible since amount of padding before the actual allocation does not change for existing architectures, only for CHERI. Helps: https://gitlab.gnome.org/GNOME/glib/-/issues/2842 --- gobject/gatomicarray.c | 7 ++++--- gobject/gatomicarray.h | 11 ++++++++++- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/gobject/gatomicarray.c b/gobject/gatomicarray.c index 506c666c2..57807f1d7 100644 --- a/gobject/gatomicarray.c +++ b/gobject/gatomicarray.c @@ -76,13 +76,14 @@ freelist_alloc (gsize size, gboolean reuse) } } - real_size = sizeof (gsize) + MAX (size, sizeof (FreeListNode)); + real_size = sizeof (GAtomicArrayMetadata) + MAX (size, sizeof (FreeListNode)); mem = g_slice_alloc (real_size); - mem = ((char *) mem) + sizeof (gsize); + mem = ((char *) mem) + sizeof (GAtomicArrayMetadata); G_ATOMIC_ARRAY_DATA_SIZE (mem) = size; #if ENABLE_VALGRIND - VALGRIND_MALLOCLIKE_BLOCK (mem, real_size - sizeof (gsize), FALSE, FALSE); + VALGRIND_MALLOCLIKE_BLOCK (mem, real_size - sizeof (GAtomicArrayMetadata), + FALSE, FALSE); #endif return mem; diff --git a/gobject/gatomicarray.h b/gobject/gatomicarray.h index f7761cc65..a4fdc0103 100644 --- a/gobject/gatomicarray.h +++ b/gobject/gatomicarray.h @@ -27,7 +27,16 @@ G_BEGIN_DECLS -#define G_ATOMIC_ARRAY_DATA_SIZE(mem) (*((gsize *) (mem) - 1)) +typedef union _GAtomicArrayMetadata +{ + gsize size; + /* We have to ensure that the memory location is sufficiently aligned to + * store any object. With C11 this would be max_align_t, but in practise + * gpointer is sufficient for all known architectures. We could change + * this to `_Alignas(max_align_t) char pad` once we depend on C11. */ + gpointer _alignment_padding; +} GAtomicArrayMetadata; +#define G_ATOMIC_ARRAY_DATA_SIZE(mem) (((GAtomicArrayMetadata *) (mem) - 1)->size) typedef struct _GAtomicArray GAtomicArray; struct _GAtomicArray {