summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Sturmlechner <asturm@gentoo.org>2020-10-04 13:56:38 +0200
committerAndreas Sturmlechner <asturm@gentoo.org>2020-10-04 17:54:08 +0200
commit804a1b3955488d8b00768d15a2748a97ca615eb6 (patch)
treec7e9f21c9d54e4c0a01b5d1d68a7c2c779d6e5d5 /kde-plasma/kwin
parentkde-apps/ark: Cleanup vulnerable 20.04.3-r1 (diff)
downloadgentoo-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.patch162
-rw-r--r--kde-plasma/kwin/kwin-5.19.5-r1.ebuild113
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
+}