[gcr] gck: Avoid unaligned memory access



commit 259080ea8e8c12652065b0041c779a450abfbddc
Author: Petr Sumbera <petr sumbera oracle com>
Date:   Fri Jan 3 16:16:33 2020 +0100

    gck: Avoid unaligned memory access
    
    When a value in GckAttribute is internally allocated, it embeds a
    refcount (gint) at the beginning the allocated memory.  If refcount
    has a smaller size than the actual value type (e.g., CK_ULONG), it
    causes unaligned memory access when reading the value.
    
    This patch allocates the maximum alignment size for the refcount part
    so that the following value should always aligned.
    
    See merge request GNOME/gcr!26.

 gck/gck-attributes.c | 30 ++++++++++++++++--------------
 1 file changed, 16 insertions(+), 14 deletions(-)
---
diff --git a/gck/gck-attributes.c b/gck/gck-attributes.c
index bb57ffe..f3f04ff 100644
--- a/gck/gck-attributes.c
+++ b/gck/gck-attributes.c
@@ -66,13 +66,15 @@ G_STATIC_ASSERT (sizeof (GckRealBuilder) <= sizeof (GckBuilder));
 
 EGG_SECURE_DECLARE (attributes);
 
+#define MAX_ALIGN 16
+
 static guchar *
 value_take (gpointer data,
             gsize length,
             gboolean secure)
 {
-       gsize len = length + sizeof (gint);
-       gint *value;
+       gsize len = length + MAX_ALIGN;
+       guchar *value;
 
        if (secure)
                value = egg_secure_realloc (data, len);
@@ -80,17 +82,17 @@ value_take (gpointer data,
                value = g_realloc (data, len);
        g_assert (value != NULL);
 
-       memmove (value + 1, value, length);
-       g_atomic_int_set (value, 1);
-       return (guchar *)(value + 1);
+       memmove (value + MAX_ALIGN, value, length);
+       g_atomic_int_set ((gint *)value, 1);
+       return value + MAX_ALIGN;
 }
 
 static guchar *
 value_blank (gsize length,
              gboolean secure)
 {
-       gsize len = length + sizeof (gint);
-       gint *value;
+       gsize len = length + MAX_ALIGN;
+       guchar *value;
 
        if (secure)
                value = egg_secure_alloc (len);
@@ -98,8 +100,8 @@ value_blank (gsize length,
                value = g_malloc (len);
        g_assert (value != NULL);
 
-       g_atomic_int_set (value, 1);
-       return (guchar *)(value + 1);
+       g_atomic_int_set ((gint *)value, 1);
+       return value + MAX_ALIGN;
 }
 
 static guchar *
@@ -117,12 +119,12 @@ value_new (gconstpointer data,
 static guchar *
 value_ref (guchar *data)
 {
-       gint *value = ((gint *)data) - 1;
+       guchar *value = data - MAX_ALIGN;
        gint previous;
 
        g_assert (data != NULL);
 
-       previous = g_atomic_int_add (value, 1);
+       previous = g_atomic_int_add ((gint *)value, 1);
        if (G_UNLIKELY (previous <= 0)) {
                g_warning ("An owned GckAttribute value has been modified outside of the "
                           "gck library or an invalid attribute was passed to gck_builder_add_attribute()");
@@ -133,13 +135,13 @@ value_ref (guchar *data)
 }
 
 static void
-value_unref (gpointer data)
+value_unref (guchar *data)
 {
-       gint *value = ((gint *)data) - 1;
+       guchar *value = data - MAX_ALIGN;
 
        g_assert (data != NULL);
 
-       if (g_atomic_int_dec_and_test (value)) {
+       if (g_atomic_int_dec_and_test ((gint *)value)) {
                if (egg_secure_check (value))
                        egg_secure_free (value);
                else


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]