[gnome-desktop/gnome-40] xkbinfo: only insert new layouts, skip over duplicate ones



commit a39dd0d22411078424f6a84dad1cc0f95783c601
Author: Peter Hutterer <peter hutterer who-t net>
Date:   Thu Apr 22 01:29:18 2021 +0000

    xkbinfo: only insert new layouts, skip over duplicate ones
    
    This matches the behavior to the one in the old code path before
    libxkbregistry.
    
    This also fixes a use-after-free bug when a duplicate layout is present. The
    same layout struct is a member of multiple hashtables, specifically
    priv->layouts_table, priv->layouts_by_language and  priv->layouts_by_country.
    
    When the duplicate layout is added, add_layouts calls g_hash_table_replace
    (priv->layouts_table, l->id, l) which frees the original layout - but the
    layouts_by_{country|language} still have that now-freed layout.
    Immediately afterwards, add_layouts calls add_layout_to_locale_tables () which
    calls add_layout_to_table () which triggers a use-after-free.
    
    Avoid all this by simply skipping any duplicate layout.
    
    Reproducible with
      gsettings set org.gnome.desktop.input-sources show-all-sources true
      valgrind /usr/libexec/gnome-desktop-debug/test-xkb-info
    
    Requires xkeyboard-config <= 2.32, it has a duplicate cm(mmuock) entry
    (one is marked exotic, hence the need for show-all-sources).
    
    Fixes #190
    
    Bug analysis by Barnabás Pőcze (@pobrn)
    
    Signed-off-by: Peter Hutterer <peter hutterer who-t net>
    
    
    (cherry picked from commit aa7e344051170ea47585d3d72b1a36e3991121f9)

 libgnome-desktop/gnome-xkb-info.c | 6 ++++++
 1 file changed, 6 insertions(+)
---
diff --git a/libgnome-desktop/gnome-xkb-info.c b/libgnome-desktop/gnome-xkb-info.c
index b2eca699..f2a3214b 100644
--- a/libgnome-desktop/gnome-xkb-info.c
+++ b/libgnome-desktop/gnome-xkb-info.c
@@ -268,6 +268,12 @@ add_layouts (GnomeXkbInfo        *self,
           l->iso3166Ids = g_slist_prepend (l->iso3166Ids, id);
         }
 
+      if (g_hash_table_contains (priv->layouts_table, l->id))
+        {
+          g_clear_pointer (&l, free_layout);
+          return;
+        }
+
       g_hash_table_replace (priv->layouts_table, l->id, l);
       add_layout_to_locale_tables (l,
                                    priv->layouts_by_language,


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