diff --git a/ui/gtk/gtk_ui.cc b/ui/gtk/gtk_ui.cc index 43dd02ec8f1be..cad973921fbb1 100644 --- a/ui/gtk/gtk_ui.cc +++ b/ui/gtk/gtk_ui.cc @@ -22,6 +22,7 @@ #include "base/containers/flat_map.h" #include "base/debug/leak_annotations.h" #include "base/environment.h" +#include "base/files/file_path.h" #include "base/functional/bind.h" #include "base/logging.h" #include "base/nix/mime_util_xdg.h" @@ -495,6 +496,30 @@ void GtkUi::GetInactiveSelectionFgColor(SkColor* color) const { gfx::Image GtkUi::GetIconForContentType(const std::string& content_type, int dip_size, float scale) const { + // Under X11 a less-privileged process that retains an X11 socket (e.g. the + // sandboxed Linux GPU process) can become the _XSETTINGS_S0 manager and + // supply an arbitrary Net/IconThemeName, which GDK writes verbatim to + // gtk-icon-theme-name. GTK joins that value onto each icon search-path + // entry without validation, so a value containing "../" lets such a process + // point the icon theme at any on-disk directory and have gdk-pixbuf / + // librsvg decode files from it inside the unsandboxed browser process. + // Reject such theme names, mirroring IsValidCursorThemeName() in + // ui/base/x/x11_cursor_loader.cc. + { + gchar* raw_name = nullptr; + g_object_get(gtk_settings_get_default(), "gtk-icon-theme-name", &raw_name, + nullptr); + std::string theme_name = raw_name ? raw_name : ""; + g_free(raw_name); + base::FilePath theme_path(theme_name); + if (theme_name.empty() || theme_name == "." || theme_path.IsAbsolute() || + theme_path.ReferencesParent() || + theme_path.BaseName() != theme_path) { + LOG(ERROR) << "Rejecting unsafe gtk-icon-theme-name: " << theme_name; + return gfx::Image(); + } + } + // This call doesn't take a reference. GtkIconTheme* theme = GetDefaultIconTheme();