diff --git a/ui/gtk/gtk_ui.cc b/ui/gtk/gtk_ui.cc index 43dd02ec8f1be..7622b54665b41 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" @@ -104,6 +105,36 @@ namespace { constexpr double kDefaultDPI = 96; +// gtk-theme-name and gtk-icon-theme-name are populated verbatim from XSETTINGS +// (Net/ThemeName, Net/IconThemeName), which on X11 may be controlled by any +// process holding an X11 socket — including the sandboxed GPU process. GTK's +// theme/icon-theme loaders use the value as a path component without +// validation, so a value like "../../../../Downloads" path-traverses into an +// attacker-writable directory and feeds attacker-controlled SVG/CSS into the +// browser process. Reset to a safe default if the value is not a single, +// well-formed path component. +void SanitizeGtkSettingsThemeName(GtkSettings* settings, const char* prop) { + gchar* val = nullptr; + g_object_get(settings, prop, &val, nullptr); + bool ok = false; + if (val) { + base::FilePath p(val); + ok = *val && p != base::FilePath(".") && !p.IsAbsolute() && + !p.ReferencesParent() && p.BaseName() == p; + } + if (!ok) { + LOG(WARNING) << "Rejecting unsafe GtkSettings " << prop << "=\"" + << (val ? val : "(null)") << "\""; + g_object_set(settings, prop, "Adwaita", nullptr); + } + g_free(val); +} + +void SanitizeGtkSettingsThemeNames(GtkSettings* settings) { + SanitizeGtkSettingsThemeName(settings, "gtk-theme-name"); + SanitizeGtkSettingsThemeName(settings, "gtk-icon-theme-name"); +} + // The unknown content type. constexpr char kUnknownContentType[] = "application/octet-stream"; @@ -382,6 +413,7 @@ bool GtkUi::Initialize() { } } + SanitizeGtkSettingsThemeNames(settings); LoadGtkValues(); // We must build this after GTK gets initialized. @@ -822,6 +854,7 @@ gfx::Size GtkUi::GetPdfPaperSize(printing::PrintingContextLinux* context) { #endif void GtkUi::OnThemeChanged(GtkSettings* settings, GtkParamSpec* param) { + SanitizeGtkSettingsThemeNames(settings); colors_.clear(); custom_frame_colors_.clear(); native_frame_colors_.clear();