File 0001-panellayouter-use-QTemporaryFile-for-applyLayout-bsc.patch of Package opensuse-welcome.18038
From 3c344ad7f71d9b67fa8299bfeb3641f5f5d9e6d7 Mon Sep 17 00:00:00 2001
From: Matthias Gerstner <matthias.gerstner@suse.de>
Date: Tue, 1 Aug 2023 13:14:28 +0200
Subject: [PATCH] panellayouter: use QTemporaryFile for applyLayout()
(bsc#1213708, CVE-2023-32184)
This fixes a security issue, details of which will only be made
available once updates are in place in openSUSE.
Place the Python helper script into the file system and package it. Let
the script accept the path to a layout tarball as parameter. Write the
application resource into a QTemporaryFile to make it accessible to the
helper script.
---
data/xfce-apply-layout.py | 36 ++++++++++++++++++++++++
meson.build | 6 +++-
src/include/panellayouter.h | 7 -----
src/meson.build | 3 +-
src/panellayouter.cpp | 55 ++++++++++++++-----------------------
5 files changed, 63 insertions(+), 44 deletions(-)
create mode 100755 data/xfce-apply-layout.py
diff --git a/data/xfce-apply-layout.py b/data/xfce-apply-layout.py
new file mode 100755
index 0000000..cb95cc9
--- /dev/null
+++ b/data/xfce-apply-layout.py
@@ -0,0 +1,36 @@
+#!/usr/bin/python3
+
+import argparse
+import gi
+import sys
+
+sys.path.append('/usr/share/xfce4-panel-profiles/xfce4-panel-profiles/')
+from gi.repository import Gio
+from panelconfig import PanelConfig
+
+parser = argparse.ArgumentParser(
+ description="Applies a new XFCE desktop layout")
+parser.add_argument("layout", help="Path to a XFCE panel layout bzip2 file in from <prefix>/share/xfce4-panel-profiles/layouts")
+
+args = parser.parse_args()
+
+session_bus = Gio.BusType.SESSION
+cancellable = None
+connection = Gio.bus_get_sync(session_bus, cancellable)
+
+proxy_property = 0
+interface_properties_array = None
+destination = 'org.xfce.Xfconf'
+path = '/org/xfce/Xfconf'
+interface = destination
+
+xfconf = Gio.DBusProxy.new_sync(
+ connection,
+ proxy_property,
+ interface_properties_array,
+ destination,
+ path,
+ interface,
+ cancellable)
+
+PanelConfig.from_file(args.layout).to_xfconf(xfconf)
diff --git a/meson.build b/meson.build
index a3bb3ef..84f46f4 100644
--- a/meson.build
+++ b/meson.build
@@ -6,6 +6,9 @@ qresource_files = ['data/qrc/qml.qrc', 'data/qrc/css.qrc', 'data/qrc/fonts.qrc',
processed_files = qt5.preprocess(moc_headers: ['src/include/enabler.h', 'src/include/launcher.h', 'src/include/sysinfo.h', 'src/include/panellayouter.h'],
include_directories: inc,
qresources: qresource_files)
+
+share_dir = join_paths(get_option('prefix'), get_option('datadir'), 'openSUSE-Welcome')
+
subdir('src')
install_data('data/org.opensuse.opensuse_welcome.desktop', install_dir: join_paths(get_option('prefix'), get_option('datadir'), 'applications'))
@@ -13,6 +16,7 @@ install_data('data/org.opensuse.opensuse_welcome.desktop', install_dir: join_pat
install_data('data/org.opensuse.opensuse_welcome.appdata.xml', install_dir: join_paths(get_option('prefix'), get_option('datadir'), 'metainfo'))
install_data('data/org.opensuse.opensuse_welcome.svg', install_dir: join_paths(get_option('prefix'), get_option('datadir'), 'icons/hicolor/scalable/apps'))
install_data('data/org.opensuse.opensuse_welcome-symbolic.svg', install_dir: join_paths(get_option('prefix'), get_option('datadir'), 'icons/hicolor/symbolic/apps'))
+install_data('data/xfce-apply-layout.py', install_dir: share_dir)
meson.add_install_script('data/cleanup.sh')
-meson.add_install_script('data/i18n.sh', join_paths(get_option('prefix'), get_option('datadir'), 'openSUSE-Welcome', 'i18n'))
+meson.add_install_script('data/i18n.sh', join_paths(share_dir, 'i18n'))
diff --git a/src/include/panellayouter.h b/src/include/panellayouter.h
index 55142f6..2f8925b 100644
--- a/src/include/panellayouter.h
+++ b/src/include/panellayouter.h
@@ -14,13 +14,6 @@ public:
Q_INVOKABLE void setFont(const QString &theme);
Q_INVOKABLE void runCommand(const QString &cmd);
Q_INVOKABLE void setLook(const QString &look);
-
-private:
- QString m_script;
-
-signals:
-
-public slots:
};
#endif // PANELLAYOUTER_H
diff --git a/src/meson.build b/src/meson.build
index eb98cc2..d0272e2 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -5,4 +5,5 @@ welcome = executable('opensuse-welcome',
processed_files,
include_directories : inc,
dependencies: qt5_dep,
- install: true)
\ No newline at end of file
+ cpp_args: '-DWELCOME_SHARE_DIR="@0@"'.format(share_dir),
+ install: true)
diff --git a/src/panellayouter.cpp b/src/panellayouter.cpp
index 82dbf15..e624f5d 100644
--- a/src/panellayouter.cpp
+++ b/src/panellayouter.cpp
@@ -1,49 +1,34 @@
#include "panellayouter.h"
+#include <memory>
#include <QFile>
#include <QProcess>
+#include <QTemporaryFile>
PanelLayouter::PanelLayouter(QObject *parent) : QObject(parent)
{
- m_script = R"(
-import sys
-sys.path.append('/usr/share/xfce4-panel-profiles/xfce4-panel-profiles/')
-import gi
-
-from panelconfig import PanelConfig
-from gi.repository import Gio
-
-session_bus = Gio.BusType.SESSION
-cancellable = None
-connection = Gio.bus_get_sync(session_bus, cancellable)
-
-proxy_property = 0
-interface_properties_array = None
-destination = 'org.xfce.Xfconf'
-path = '/org/xfce/Xfconf'
-interface = destination
-
-xfconf = Gio.DBusProxy.new_sync(
- connection,
- proxy_property,
- interface_properties_array,
- destination,
- path,
- interface,
- cancellable)
-
-PanelConfig.from_file("/tmp/layout").to_xfconf(xfconf)
-)";
}
void PanelLayouter::applyLayout(const QString &path)
{
- if (QFile::exists("/tmp/layout"))
- QFile::remove("/tmp/layout");
+ const QString SHARE_DIR(QStringLiteral(WELCOME_SHARE_DIR));
+ const QString APPLY_LAYOUT_SCRIPT = SHARE_DIR + QStringLiteral("/xfce-apply-layout.py");
+ // `path` is only an internal application resource, embedded into the
+ // executable. We need to actually place it on disk for the helper script
+ // to use it.
+ //
+ // this is not well documented, but createNativeFile returns a heap
+ // allocated file object that we need to cleanup.
+ std::unique_ptr<QTemporaryFile> file(QTemporaryFile::createNativeFile(path));
+
+ if (!file)
+ // should never happen
+ return;
- QFile layout(path);
- layout.copy("/tmp/layout");
+ const auto result = QProcess::execute(APPLY_LAYOUT_SCRIPT, {file->fileName()});
- QProcess::startDetached("/usr/bin/python3", {"-c", m_script});
+ if (result != 0) {
+ // TODO: something went wrong, display error message?
+ }
}
void PanelLayouter::setTheme(const QString &theme)
@@ -86,4 +71,4 @@ void PanelLayouter::setLook(const QString &look)
this->setFont("Cantarell 11");
this->setIconTheme("Adwaita");
}
-}
\ No newline at end of file
+}
--
2.41.0