gldriver: Fix a possible use-after-free
authorMohammed Sadiq <sadiq@sadiqpk.org>
Mon, 26 Jun 2023 02:35:52 +0000 (08:05 +0530)
committerMohammed Sadiq <sadiq@sadiqpk.org>
Tue, 27 Jun 2023 17:15:07 +0000 (22:45 +0530)
g_hash_table_insert() frees the given key if it already exists
in the hashtable.  But since we use the same pointer in the
following line, it will result in use-after-free.

So instead, insert the key only if it doesn't exist.

gsk/gl/gskgldriver.c

index cc27a89ef6d9aa2d0f994e0be3c9b6f7e93d38f1..225cae6920912980e78848cace4b92ffaf4ade7c 100644 (file)
@@ -686,17 +686,21 @@ gsk_gl_driver_cache_texture (GskGLDriver         *self,
                              const GskTextureKey *key,
                              guint                texture_id)
 {
-  GskTextureKey *k;
-
   g_assert (GSK_IS_GL_DRIVER (self));
   g_assert (key != NULL);
   g_assert (texture_id > 0);
   g_assert (g_hash_table_contains (self->textures, GUINT_TO_POINTER (texture_id)));
 
-  k = g_memdup (key, sizeof *key);
+  if (!g_hash_table_contains (self->key_to_texture_id, key))
+    {
+      GskTextureKey *k;
+
+      k = g_memdup (key, sizeof *key);
 
-  g_hash_table_insert (self->key_to_texture_id, k, GUINT_TO_POINTER (texture_id));
-  g_hash_table_insert (self->texture_id_to_key, GUINT_TO_POINTER (texture_id), k);
+      g_assert (!g_hash_table_contains (self->texture_id_to_key, GUINT_TO_POINTER (texture_id)));
+      g_hash_table_insert (self->key_to_texture_id, k, GUINT_TO_POINTER (texture_id));
+      g_hash_table_insert (self->texture_id_to_key, GUINT_TO_POINTER (texture_id), k);
+    }
 }
 
 /**