diff options
author | Andreas Sturmlechner <asturm@gentoo.org> | 2020-10-04 13:56:38 +0200 |
---|---|---|
committer | Andreas Sturmlechner <asturm@gentoo.org> | 2020-10-04 17:54:08 +0200 |
commit | 804a1b3955488d8b00768d15a2748a97ca615eb6 (patch) | |
tree | c7e9f21c9d54e4c0a01b5d1d68a7c2c779d6e5d5 /kde-plasma/kwin | |
parent | kde-apps/ark: Cleanup vulnerable 20.04.3-r1 (diff) | |
download | gentoo-804a1b3955488d8b00768d15a2748a97ca615eb6.tar.gz gentoo-804a1b3955488d8b00768d15a2748a97ca615eb6.tar.bz2 gentoo-804a1b3955488d8b00768d15a2748a97ca615eb6.zip |
kde-plasma/kwin: Make removal of X11 event filters safe
KDE-Bug: https://bugs.kde.org/show_bug.cgi?id=423319
Package-Manager: Portage-3.0.8, Repoman-3.0.1
Signed-off-by: Andreas Sturmlechner <asturm@gentoo.org>
Diffstat (limited to 'kde-plasma/kwin')
-rw-r--r-- | kde-plasma/kwin/files/kwin-5.19.5-safe-removal-of-X11-event-filters.patch | 162 | ||||
-rw-r--r-- | kde-plasma/kwin/kwin-5.19.5-r1.ebuild | 113 |
2 files changed, 275 insertions, 0 deletions
diff --git a/kde-plasma/kwin/files/kwin-5.19.5-safe-removal-of-X11-event-filters.patch b/kde-plasma/kwin/files/kwin-5.19.5-safe-removal-of-X11-event-filters.patch new file mode 100644 index 000000000000..7eeccf6e8c5f --- /dev/null +++ b/kde-plasma/kwin/files/kwin-5.19.5-safe-removal-of-X11-event-filters.patch @@ -0,0 +1,162 @@ +From c5880833d94330d022c4b6fc84c175aadeaf9632 Mon Sep 17 00:00:00 2001 +From: Vlad Zahorodnii <vlad.zahorodnii@kde.org> +Date: Tue, 22 Sep 2020 08:53:17 +0000 +Subject: [PATCH] x11: Make removal of X11 event filters safe + +If an X11 event filter has been activated and it unregisters another X11 +event filter, then the window manager may crash because the foreach macro +in Workspace::workspaceEvent() makes a copy of m_genericEventFilters or +m_eventFilters and we can call the event() method for an already defunct +filter. + +With this change, X11 event filters can be safely removed and installed +at any particular moment. + +BUG: 423319 + + +(cherry picked from commit a433fb08a3a9255802405a17dd4c8270c68fcb25) +--- + events.cpp | 52 +++++++++++++++++++++++++++++++++++++++++---------- + workspace.cpp | 10 ++++++++++ + workspace.h | 17 +++++++++++++++-- + 3 files changed, 67 insertions(+), 12 deletions(-) + +diff --git a/events.cpp b/events.cpp +index eb3572d13..2e8885d76 100644 +--- a/events.cpp ++++ b/events.cpp +@@ -165,18 +165,34 @@ QVector<QByteArray> s_xcbEerrors({ + + void Workspace::registerEventFilter(X11EventFilter *filter) + { +- if (filter->isGenericEvent()) +- m_genericEventFilters.append(filter); +- else +- m_eventFilters.append(filter); ++ if (filter->isGenericEvent()) { ++ m_genericEventFilters.append(new X11EventFilterContainer(filter)); ++ } else { ++ m_eventFilters.append(new X11EventFilterContainer(filter)); ++ } ++} ++ ++static X11EventFilterContainer *takeEventFilter(X11EventFilter *eventFilter, ++ QList<QPointer<X11EventFilterContainer>> &list) ++{ ++ for (int i = 0; i < list.count(); ++i) { ++ X11EventFilterContainer *container = list.at(i); ++ if (container->filter() == eventFilter) { ++ return list.takeAt(i); ++ } ++ } ++ return nullptr; + } + + void Workspace::unregisterEventFilter(X11EventFilter *filter) + { +- if (filter->isGenericEvent()) +- m_genericEventFilters.removeOne(filter); +- else +- m_eventFilters.removeOne(filter); ++ X11EventFilterContainer *container = nullptr; ++ if (filter->isGenericEvent()) { ++ container = takeEventFilter(filter, m_genericEventFilters); ++ } else { ++ container = takeEventFilter(filter, m_eventFilters); ++ } ++ delete container; + } + + +@@ -219,13 +235,29 @@ bool Workspace::workspaceEvent(xcb_generic_event_t *e) + if (eventType == XCB_GE_GENERIC) { + xcb_ge_generic_event_t *ge = reinterpret_cast<xcb_ge_generic_event_t *>(e); + +- foreach (X11EventFilter *filter, m_genericEventFilters) { ++ // We need to make a shadow copy of the event filter list because an activated event ++ // filter may mutate it by removing or installing another event filter. ++ const auto eventFilters = m_genericEventFilters; ++ ++ for (X11EventFilterContainer *container : eventFilters) { ++ if (!container) { ++ continue; ++ } ++ X11EventFilter *filter = container->filter(); + if (filter->extension() == ge->extension && filter->genericEventTypes().contains(ge->event_type) && filter->event(e)) { + return true; + } + } + } else { +- foreach (X11EventFilter *filter, m_eventFilters) { ++ // We need to make a shadow copy of the event filter list because an activated event ++ // filter may mutate it by removing or installing another event filter. ++ const auto eventFilters = m_eventFilters; ++ ++ for (X11EventFilterContainer *container : eventFilters) { ++ if (!container) { ++ continue; ++ } ++ X11EventFilter *filter = container->filter(); + if (filter->eventTypes().contains(eventType) && filter->event(e)) { + return true; + } +diff --git a/workspace.cpp b/workspace.cpp +index a87a622e9..fd3634b16 100644 +--- a/workspace.cpp ++++ b/workspace.cpp +@@ -66,6 +66,16 @@ namespace KWin + extern int screen_number; + extern bool is_multihead; + ++X11EventFilterContainer::X11EventFilterContainer(X11EventFilter *filter) ++ : m_filter(filter) ++{ ++} ++ ++X11EventFilter *X11EventFilterContainer::filter() const ++{ ++ return m_filter; ++} ++ + ColorMapper::ColorMapper(QObject *parent) + : QObject(parent) + , m_default(kwinApp()->x11DefaultScreen()->default_colormap) +diff --git a/workspace.h b/workspace.h +index 489d7bae4..61fb215a8 100644 +--- a/workspace.h ++++ b/workspace.h +@@ -55,6 +55,19 @@ class X11Client; + class X11EventFilter; + enum class Predicate; + ++class X11EventFilterContainer : public QObject ++{ ++ Q_OBJECT ++ ++public: ++ explicit X11EventFilterContainer(X11EventFilter *filter); ++ ++ X11EventFilter *filter() const; ++ ++private: ++ X11EventFilter *m_filter; ++}; ++ + class KWIN_EXPORT Workspace : public QObject + { + Q_OBJECT +@@ -654,8 +667,8 @@ private: + + QScopedPointer<KillWindow> m_windowKiller; + +- QList<X11EventFilter *> m_eventFilters; +- QList<X11EventFilter *> m_genericEventFilters; ++ QList<QPointer<X11EventFilterContainer>> m_eventFilters; ++ QList<QPointer<X11EventFilterContainer>> m_genericEventFilters; + QScopedPointer<X11EventFilter> m_movingClientFilter; + QScopedPointer<X11EventFilter> m_syncAlarmFilter; + +-- +GitLab + diff --git a/kde-plasma/kwin/kwin-5.19.5-r1.ebuild b/kde-plasma/kwin/kwin-5.19.5-r1.ebuild new file mode 100644 index 000000000000..d3058de64429 --- /dev/null +++ b/kde-plasma/kwin/kwin-5.19.5-r1.ebuild @@ -0,0 +1,113 @@ +# Copyright 1999-2020 Gentoo Authors +# Distributed under the terms of the GNU General Public License v2 + +EAPI=7 + +ECM_HANDBOOK="optional" +ECM_TEST="optional" +KFMIN=5.71.0 +PVCUT=$(ver_cut 1-3) +QTMIN=5.14.2 +VIRTUALX_REQUIRED="test" +inherit ecm kde.org + +DESCRIPTION="Flexible, composited Window Manager for windowing systems on Linux" + +LICENSE="GPL-2+" +SLOT="5" +KEYWORDS="~amd64 ~arm ~arm64 ~ppc64 ~x86" +IUSE="caps gles2-only multimedia" + +COMMON_DEPEND=" + >=dev-libs/libinput-1.14 + >=dev-libs/wayland-1.2 + >=dev-qt/qtdbus-${QTMIN}:5 + >=dev-qt/qtdeclarative-${QTMIN}:5 + >=dev-qt/qtgui-${QTMIN}:5=[gles2-only=] + >=dev-qt/qtscript-${QTMIN}:5 + >=dev-qt/qtsensors-${QTMIN}:5 + >=dev-qt/qtwidgets-${QTMIN}:5 + >=dev-qt/qtx11extras-${QTMIN}:5 + >=kde-frameworks/kactivities-${KFMIN}:5 + >=kde-frameworks/kauth-${KFMIN}:5 + >=kde-frameworks/kcmutils-${KFMIN}:5 + >=kde-frameworks/kcompletion-${KFMIN}:5 + >=kde-frameworks/kconfig-${KFMIN}:5 + >=kde-frameworks/kconfigwidgets-${KFMIN}:5 + >=kde-frameworks/kcoreaddons-${KFMIN}:5 + >=kde-frameworks/kcrash-${KFMIN}:5 + >=kde-frameworks/kdeclarative-${KFMIN}:5 + >=kde-frameworks/kglobalaccel-${KFMIN}:5= + >=kde-frameworks/ki18n-${KFMIN}:5 + >=kde-frameworks/kiconthemes-${KFMIN}:5 + >=kde-frameworks/kidletime-${KFMIN}:5= + >=kde-frameworks/kio-${KFMIN}:5 + >=kde-frameworks/knewstuff-${KFMIN}:5 + >=kde-frameworks/knotifications-${KFMIN}:5 + >=kde-frameworks/kpackage-${KFMIN}:5 + >=kde-frameworks/kservice-${KFMIN}:5 + >=kde-frameworks/ktextwidgets-${KFMIN}:5 + >=kde-frameworks/kwayland-${KFMIN}:5 + >=kde-frameworks/kwidgetsaddons-${KFMIN}:5 + >=kde-frameworks/kwindowsystem-${KFMIN}:5[X] + >=kde-frameworks/kxmlgui-${KFMIN}:5 + >=kde-frameworks/plasma-${KFMIN}:5 + >=kde-plasma/breeze-${PVCUT}:5 + >=kde-plasma/kdecoration-${PVCUT}:5 + >=kde-plasma/kscreenlocker-${PVCUT}:5 + >=kde-plasma/kwayland-server-${PVCUT}:5 + media-libs/fontconfig + media-libs/freetype + media-libs/libepoxy + media-libs/mesa[egl,gbm,wayland,X(+)] + virtual/libudev:= + x11-libs/libICE + x11-libs/libSM + x11-libs/libX11 + x11-libs/libXi + x11-libs/libdrm + >=x11-libs/libxcb-1.10 + >=x11-libs/libxkbcommon-0.7.0 + x11-libs/xcb-util-cursor + x11-libs/xcb-util-image + x11-libs/xcb-util-keysyms + x11-libs/xcb-util-wm + caps? ( sys-libs/libcap ) + gles2-only? ( media-libs/mesa[gles2] ) +" +# TODO: sys-apps/hwdata? not packaged yet; commit 33a1777a, Gentoo-bug 717216 +RDEPEND="${COMMON_DEPEND} + >=dev-qt/qtquickcontrols-${QTMIN}:5 + >=dev-qt/qtquickcontrols2-${QTMIN}:5 + >=dev-qt/qtvirtualkeyboard-${QTMIN}:5 + >=kde-frameworks/kirigami-${KFMIN}:5 + >=kde-frameworks/kitemmodels-${KFMIN}:5[qml] + multimedia? ( >=dev-qt/qtmultimedia-${QTMIN}:5[gstreamer,qml] ) +" +DEPEND="${COMMON_DEPEND} + >=dev-qt/designer-${QTMIN}:5 + >=dev-qt/qtconcurrent-${QTMIN}:5 + x11-base/xorg-proto +" +PDEPEND=" + >=kde-plasma/kde-cli-tools-${PVCUT}:5 +" + +RESTRICT+=" test" + +PATCHES=( + "${FILESDIR}"/${P}-safe-removal-of-X11-event-filters.patch # KDE-Bug 423319 +) + +src_prepare() { + ecm_src_prepare + use multimedia || eapply "${FILESDIR}/${PN}-5.16.80-gstreamer-optional.patch" +} + +src_configure() { + local mycmakeargs=( + $(cmake_use_find_package caps Libcap) + ) + + ecm_src_configure +} |