From bf560369f2401e2cdd16f962f248e98c890835d0 Mon Sep 17 00:00:00 2001 From: Lauri Kasanen Date: Thu, 27 Oct 2016 16:51:29 +0300 Subject: [PATCH] recent-manager: Add a limit to the list's size This fixes a DOS where any app can cause all running gtk apps to use arbitrary amounts of memory. Originally reported against mate-panel, where running a big slideshow in eye-of-mate caused increasing RAM usage in mate-panel. v2: Hardcode the value Signed-off-by: Lauri Kasanen https://bugzilla.gnome.org/show_bug.cgi?id=773587 --- gtk/gtkrecentmanager.c | 43 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 40 insertions(+), 3 deletions(-) diff --git a/gtk/gtkrecentmanager.c b/gtk/gtkrecentmanager.c index 1157eec3ea..fe5f03f2ba 100644 --- a/gtk/gtkrecentmanager.c +++ b/gtk/gtkrecentmanager.c @@ -113,6 +113,9 @@ /* return all items by default */ #define DEFAULT_LIMIT -1 +/* limit the size of the list */ +#define MAX_LIST_SIZE 1000 + /* keep in sync with xdgmime */ #define GTK_RECENT_DEFAULT_MIME "application/octet-stream" @@ -211,6 +214,9 @@ static void gtk_recent_manager_set_filename (GtkRecentManager *manag const gchar *filename); static void gtk_recent_manager_clamp_to_age (GtkRecentManager *manager, gint age); +static void gtk_recent_manager_clamp_to_size (GtkRecentManager *manager, + const gint size); + static void gtk_recent_manager_enabled_changed (GtkRecentManager *manager); @@ -462,6 +468,7 @@ gtk_recent_manager_real_changed (GtkRecentManager *manager) { GtkSettings *settings; gint age; + gint max_size = MAX_LIST_SIZE; gboolean enabled; settings = gtk_settings_get_default (); @@ -476,14 +483,19 @@ gtk_recent_manager_real_changed (GtkRecentManager *manager) enabled = TRUE; } - if (age == 0 || !enabled) + if (age == 0 || max_size == 0 || !enabled) { g_bookmark_file_free (priv->recent_items); priv->recent_items = g_bookmark_file_new (); priv->size = 0; } - else if (age > 0) - gtk_recent_manager_clamp_to_age (manager, age); + else + { + if (age > 0) + gtk_recent_manager_clamp_to_age (manager, age); + if (max_size > 0) + gtk_recent_manager_clamp_to_size (manager, max_size); + } } if (priv->filename != NULL) @@ -1455,6 +1467,31 @@ gtk_recent_manager_clamp_to_age (GtkRecentManager *manager, g_strfreev (uris); } +static void +gtk_recent_manager_clamp_to_size (GtkRecentManager *manager, + const gint size) +{ + GtkRecentManagerPrivate *priv = manager->priv; + gchar **uris; + gsize n_uris, i; + + if (G_UNLIKELY (!priv->recent_items) || G_UNLIKELY (size < 0)) + return; + + uris = g_bookmark_file_get_uris (priv->recent_items, &n_uris); + + if (n_uris < size) + return; + + for (i = 0; i < n_uris - size; i++) + { + const gchar *uri = uris[i]; + g_bookmark_file_remove_item (priv->recent_items, uri, NULL); + } + + g_strfreev (uris); +} + /***************** * GtkRecentInfo * *****************/