!9 fix CVE-2024-36041

From: @zhangxianting 
Reviewed-by: @open-bot 
Signed-off-by: @open-bot
This commit is contained in:
openeuler-ci-bot 2024-07-10 02:09:10 +00:00 committed by Gitee
commit 2ebc468e05
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
3 changed files with 541 additions and 1 deletions

View File

@ -0,0 +1,127 @@
From da843d3fdb143ed44094c8e6246cfb8305f6f09f Mon Sep 17 00:00:00 2001
From: David Edmundson <kde@davidedmundson.co.uk>
Date: Sat, 13 Apr 2024 23:07:19 +0100
Subject: [PATCH] Authenticate local clients
ksmserver currently authenticates remote clients, but allows local
connections through.
This is a security risk that can allow another user on the same system
to access the user's session management session without authentication.
Co-authored-by: Fabian Vogt <fabian@ritter-vogt.de>
---
ksmserver/server.cpp | 57 ++++----------------------------------------
1 file changed, 5 insertions(+), 52 deletions(-)
diff --git a/ksmserver/server.cpp b/ksmserver/server.cpp
index 8a408cf73b..62bb8fb74d 100644
--- a/ksmserver/server.cpp
+++ b/ksmserver/server.cpp
@@ -158,15 +158,6 @@ static QTemporaryFile *remTempFile = nullptr;
static IceListenObj *listenObjs = nullptr;
int numTransports = 0;
-static bool only_local = 0;
-
-static Bool HostBasedAuthProc(char * /*hostname*/)
-{
- if (only_local)
- return true;
- else
- return false;
-}
Status KSMRegisterClientProc(SmsConn /* smsConn */, SmPointer managerData, char *previousId)
{
@@ -311,33 +302,6 @@ static void write_iceauth(FILE *addfp, FILE *removefp, IceAuthDataEntry *entry)
#define MAGIC_COOKIE_LEN 16
-Status SetAuthentication_local(int count, IceListenObj *listenObjs)
-{
- int i;
- for (i = 0; i < count; i++) {
- char *prot = IceGetListenConnectionString(listenObjs[i]);
- if (!prot)
- continue;
- char *host = strchr(prot, '/');
- char *sock = nullptr;
- if (host) {
- *host = 0;
- host++;
- sock = strchr(host, ':');
- if (sock) {
- *sock = 0;
- sock++;
- }
- }
- qCDebug(KSMSERVER) << "KSMServer: SetAProc_loc: conn " << (unsigned)i << ", prot=" << prot << ", file=" << sock;
- if (sock && !strcmp(prot, "local")) {
- chmod(sock, 0700);
- }
- IceSetHostBasedAuthProc(listenObjs[i], HostBasedAuthProc);
- free(prot);
- }
- return 1;
-}
Status SetAuthentication(int count, IceListenObj *listenObjs, IceAuthDataEntry **authDataEntries)
{
@@ -372,8 +336,6 @@ Status SetAuthentication(int count, IceListenObj *listenObjs, IceAuthDataEntry *
write_iceauth(addAuthFile, remAuthFile, &(*authDataEntries)[i + 1]);
IceSetPaAuthData(2, &(*authDataEntries)[i]);
-
- IceSetHostBasedAuthProc(listenObjs[i / 2], HostBasedAuthProc);
}
fclose(addAuthFile);
fclose(remAuthFile);
@@ -397,9 +359,6 @@ Status SetAuthentication(int count, IceListenObj *listenObjs, IceAuthDataEntry *
void FreeAuthenticationData(int count, IceAuthDataEntry *authDataEntries)
{
/* Each transport has entries for ICE and XSMP */
- if (only_local)
- return;
-
for (int i = 0; i < count * 2; i++) {
free(authDataEntries[i].network_id);
free(authDataEntries[i].auth_data);
@@ -542,16 +501,14 @@ KSMServer::KSMServer(InitFlags flags)
clientInteracting = nullptr;
xonCommand = config.readEntry("xonCommand", "xon");
- only_local = flags.testFlag(InitFlag::OnlyLocal);
#ifdef HAVE__ICETRANSNOLISTEN
- if (only_local)
+ if (flags.testFlag(InitFlag::OnlyLocal)) {
_IceTransNoListen("tcp");
-#else
- only_local = false;
+ }
#endif
char errormsg[256];
- if (!SmsInitialize((char *)KSMVendorString, (char *)KSMReleaseString, KSMNewClientProc, (SmPointer)this, HostBasedAuthProc, 256, errormsg)) {
+ if (!SmsInitialize((char *)KSMVendorString, (char *)KSMReleaseString, KSMNewClientProc, (SmPointer)this, nullptr, 256, errormsg)) {
qCWarning(KSMSERVER, "KSMServer: could not register XSM protocol");
}
@@ -594,12 +551,8 @@ KSMServer::KSMServer(InitFlags flags)
free(session_manager);
}
- if (only_local) {
- if (!SetAuthentication_local(numTransports, listenObjs))
- qFatal("KSMSERVER: authentication setup failed.");
- } else {
- if (!SetAuthentication(numTransports, listenObjs, &authDataEntries))
- qFatal("KSMSERVER: authentication setup failed.");
+ if (!SetAuthentication(numTransports, listenObjs, &authDataEntries)) {
+ qFatal("KSMSERVER: authentication setup failed.");
}
IceAddConnectionWatch(KSMWatchProc, (IcePointer)this);
--
GitLab

View File

@ -0,0 +1,404 @@
From 1d5aa1d27bff87b2d242ed759cfb2ce15a5c3de7 Mon Sep 17 00:00:00 2001
From: David Edmundson <kde@davidedmundson.co.uk>
Date: Sat, 13 Apr 2024 23:30:34 +0100
Subject: [PATCH] Remove iceauth dependency
Previously the tool iceauth was used to write authentication to and from
the iceauthority file, running a set of commands to manipulate the file.
This external dependency is not often installed, which may create a
problem
now that all paths go through authentication. If iceauth is not
currently installed
ksmserver will assert rendering the session useless.
This patch writes and manages the file directly removing the need for
external tools.
Co-authored-by: Fabian Vogt <fabian@ritter-vogt.de>
---
ksmserver/server.cpp | 281 ++++++++++++++++++++++---------------------
ksmserver/server.h | 2 +
2 files changed, 148 insertions(+), 135 deletions(-)
diff --git a/ksmserver/server.cpp b/ksmserver/server.cpp
index 62bb8fb74d..f88de40dba 100644
--- a/ksmserver/server.cpp
+++ b/ksmserver/server.cpp
@@ -54,6 +54,7 @@
#include <QFile>
#include <QPushButton>
#include <QRegularExpression>
+#include <QScopeGuard>
#include <QSocketNotifier>
#include <QStandardPaths>
@@ -287,37 +288,34 @@ static void fprintfhex(FILE *fp, unsigned int len, char *cp)
}
}
-/*
- * We use temporary files which contain commands to add/remove entries from
- * the .ICEauthority file.
- */
-static void write_iceauth(FILE *addfp, FILE *removefp, IceAuthDataEntry *entry)
-{
- fprintf(addfp, "add %s \"\" %s %s ", entry->protocol_name, entry->network_id, entry->auth_name);
- fprintfhex(addfp, entry->auth_data_length, entry->auth_data);
- fprintf(addfp, "\n");
-
- fprintf(removefp, "remove protoname=%s protodata=\"\" netid=%s authname=%s\n", entry->protocol_name, entry->network_id, entry->auth_name);
-}
-
#define MAGIC_COOKIE_LEN 16
-
Status SetAuthentication(int count, IceListenObj *listenObjs, IceAuthDataEntry **authDataEntries)
{
- QTemporaryFile addTempFile;
- remTempFile = new QTemporaryFile;
+ char *filename = IceAuthFileName();
+ FILE *fp;
- if (!addTempFile.open() || !remTempFile->open())
+ if (IceLockAuthFile(filename, 10, 2, 600) != IceAuthLockSuccess) {
+ qWarning() << "Could not lock ICEAuthority file";
return 0;
+ }
+ auto cleanup = qScopeGuard([filename]() {
+ IceUnlockAuthFile(filename);
+ });
- if ((*authDataEntries = (IceAuthDataEntry *)malloc(count * 2 * sizeof(IceAuthDataEntry))) == nullptr)
+ if ((fp = fopen(filename, "ab")) == NULL) {
+ qWarning() << "Could not open ICEAuthority file";
return 0;
+ }
- FILE *addAuthFile = fopen(QFile::encodeName(addTempFile.fileName()).constData(), "r+");
- FILE *remAuthFile = fopen(QFile::encodeName(remTempFile->fileName()).constData(), "r+");
+ if ((*authDataEntries = (IceAuthDataEntry *)malloc(count * 2 * sizeof(IceAuthDataEntry))) == nullptr) {
+ (void)fclose(fp);
+ return 0;
+ }
for (int i = 0; i < numTransports * 2; i += 2) {
+ // ICE Auth Data
+
(*authDataEntries)[i].network_id = IceGetListenConnectionString(listenObjs[i / 2]);
(*authDataEntries)[i].protocol_name = (char *)"ICE";
(*authDataEntries)[i].auth_name = (char *)"MIT-MAGIC-COOKIE-1";
@@ -325,6 +323,23 @@ Status SetAuthentication(int count, IceListenObj *listenObjs, IceAuthDataEntry *
(*authDataEntries)[i].auth_data = IceGenerateMagicCookie(MAGIC_COOKIE_LEN);
(*authDataEntries)[i].auth_data_length = MAGIC_COOKIE_LEN;
+ // ICE Auth File
+ {
+ IceAuthFileEntry *file_entry = (IceAuthFileEntry *)malloc(sizeof(IceAuthFileEntry));
+ file_entry->protocol_name = strdup("ICE");
+ file_entry->protocol_data = NULL;
+ file_entry->protocol_data_length = 0;
+ file_entry->network_id = IceGetListenConnectionString(listenObjs[i / 2]);
+ file_entry->auth_name = strdup("MIT-MAGIC-COOKIE-1");
+ file_entry->auth_data = strdup((*authDataEntries)[i].auth_data);
+ file_entry->auth_data_length = MAGIC_COOKIE_LEN;
+ if (IceWriteAuthFileEntry(fp, file_entry) != 0) {
+ qWarning("Failed to write ice auth file entry");
+ }
+ IceFreeAuthFileEntry(file_entry);
+ }
+
+ // XSMP Auth Data
(*authDataEntries)[i + 1].network_id = IceGetListenConnectionString(listenObjs[i / 2]);
(*authDataEntries)[i + 1].protocol_name = (char *)"XSMP";
(*authDataEntries)[i + 1].auth_name = (char *)"MIT-MAGIC-COOKIE-1";
@@ -332,141 +347,127 @@ Status SetAuthentication(int count, IceListenObj *listenObjs, IceAuthDataEntry *
(*authDataEntries)[i + 1].auth_data = IceGenerateMagicCookie(MAGIC_COOKIE_LEN);
(*authDataEntries)[i + 1].auth_data_length = MAGIC_COOKIE_LEN;
- write_iceauth(addAuthFile, remAuthFile, &(*authDataEntries)[i]);
- write_iceauth(addAuthFile, remAuthFile, &(*authDataEntries)[i + 1]);
+ // XSMP Auth file
+ {
+ IceAuthFileEntry *file_entry = (IceAuthFileEntry *)malloc(sizeof(IceAuthFileEntry));
+ file_entry->protocol_name = strdup("XSMP");
+ file_entry->protocol_data = NULL;
+ file_entry->protocol_data_length = 0;
+ file_entry->network_id = IceGetListenConnectionString(listenObjs[i / 2]);
+ file_entry->auth_name = strdup("MIT-MAGIC-COOKIE-1");
+ file_entry->auth_data = strdup((*authDataEntries)[i + 1].auth_data);
+ file_entry->auth_data_length = MAGIC_COOKIE_LEN;
+ if (IceWriteAuthFileEntry(fp, file_entry) != 0) {
+ qWarning("Failed to write xsmp ice auth file entry");
+ }
+ IceFreeAuthFileEntry(file_entry);
+ }
IceSetPaAuthData(2, &(*authDataEntries)[i]);
}
- fclose(addAuthFile);
- fclose(remAuthFile);
-
- QString iceAuth = QStandardPaths::findExecutable(QStringLiteral("iceauth"));
- if (iceAuth.isEmpty()) {
- qCWarning(KSMSERVER, "KSMServer: could not find iceauth");
- return 0;
- }
-
- KProcess p;
- p << iceAuth << QStringLiteral("source") << addTempFile.fileName();
- p.execute();
return (1);
}
-/*
- * Free up authentication data.
- */
-void FreeAuthenticationData(int count, IceAuthDataEntry *authDataEntries)
-{
- /* Each transport has entries for ICE and XSMP */
- for (int i = 0; i < count * 2; i++) {
- free(authDataEntries[i].network_id);
- free(authDataEntries[i].auth_data);
- }
-
- free(authDataEntries);
-
- QString iceAuth = QStandardPaths::findExecutable(QStringLiteral("iceauth"));
- if (iceAuth.isEmpty()) {
- qCWarning(KSMSERVER, "KSMServer: could not find iceauth");
- return;
- }
+ /*
+ * Free up authentication data.
+ */
+ void FreeAuthenticationData(int count, IceAuthDataEntry *authDataEntries)
+ {
+ /* Each transport has entries for ICE and XSMP */
+ for (int i = 0; i < count * 2; i++) {
+ free(authDataEntries[i].network_id);
+ free(authDataEntries[i].auth_data);
+ }
- if (remTempFile) {
- KProcess p;
- p << iceAuth << QStringLiteral("source") << remTempFile->fileName();
- p.execute();
- }
+ free(authDataEntries);
+ }
- delete remTempFile;
- remTempFile = nullptr;
-}
+ static int Xio_ErrorHandler(Display *)
+ {
+ qCWarning(KSMSERVER, "ksmserver: Fatal IO error: client killed");
-static int Xio_ErrorHandler(Display *)
-{
- qCWarning(KSMSERVER, "ksmserver: Fatal IO error: client killed");
+ // Don't do anything that might require the X connection
+ if (the_server) {
+ KSMServer *server = the_server;
+ the_server = nullptr;
+ server->cleanUp();
+ // Don't delete server!!
+ }
- // Don't do anything that might require the X connection
- if (the_server) {
- KSMServer *server = the_server;
- the_server = nullptr;
- server->cleanUp();
- // Don't delete server!!
- }
+ exit(0); // Don't report error, it's not our fault.
+ return 0; // Bogus return value, notreached
+ }
- exit(0); // Don't report error, it's not our fault.
- return 0; // Bogus return value, notreached
-}
+ void KSMServer::setupXIOErrorHandler()
+ {
+ XSetIOErrorHandler(Xio_ErrorHandler);
+ }
-void KSMServer::setupXIOErrorHandler()
-{
- XSetIOErrorHandler(Xio_ErrorHandler);
-}
+ static int wake_up_socket = -1;
+ static void sighandler(int sig)
+ {
+ if (sig == SIGHUP) {
+ signal(SIGHUP, sighandler);
+ return;
+ }
-static int wake_up_socket = -1;
-static void sighandler(int sig)
-{
- if (sig == SIGHUP) {
- signal(SIGHUP, sighandler);
- return;
- }
+ char ch = 0;
+ (void)::write(wake_up_socket, &ch, 1);
+ }
- char ch = 0;
- (void)::write(wake_up_socket, &ch, 1);
-}
+ void KSMWatchProc(IceConn iceConn, IcePointer client_data, Bool opening, IcePointer * watch_data)
+ {
+ KSMServer *ds = (KSMServer *)client_data;
-void KSMWatchProc(IceConn iceConn, IcePointer client_data, Bool opening, IcePointer *watch_data)
-{
- KSMServer *ds = (KSMServer *)client_data;
+ if (opening) {
+ *watch_data = (IcePointer)ds->watchConnection(iceConn);
+ } else {
+ ds->removeConnection((KSMConnection *)*watch_data);
+ }
+ }
- if (opening) {
- *watch_data = (IcePointer)ds->watchConnection(iceConn);
- } else {
- ds->removeConnection((KSMConnection *)*watch_data);
- }
-}
+ static Status KSMNewClientProc(SmsConn conn, SmPointer manager_data, unsigned long *mask_ret, SmsCallbacks *cb, char **failure_reason_ret)
+ {
+ *failure_reason_ret = nullptr;
-static Status KSMNewClientProc(SmsConn conn, SmPointer manager_data, unsigned long *mask_ret, SmsCallbacks *cb, char **failure_reason_ret)
-{
- *failure_reason_ret = nullptr;
+ void *client = ((KSMServer *)manager_data)->newClient(conn);
+ if (client == NULL) {
+ const char *errstr = "Connection rejected: ksmserver is shutting down";
+ qCWarning(KSMSERVER, "%s", errstr);
- void *client = ((KSMServer *)manager_data)->newClient(conn);
- if (client == NULL) {
- const char *errstr = "Connection rejected: ksmserver is shutting down";
- qCWarning(KSMSERVER, "%s", errstr);
+ if ((*failure_reason_ret = (char *)malloc(strlen(errstr) + 1)) != NULL) {
+ strcpy(*failure_reason_ret, errstr);
+ }
+ return 0;
+ }
- if ((*failure_reason_ret = (char *)malloc(strlen(errstr) + 1)) != NULL) {
- strcpy(*failure_reason_ret, errstr);
+ cb->register_client.callback = KSMRegisterClientProc;
+ cb->register_client.manager_data = client;
+ cb->interact_request.callback = KSMInteractRequestProc;
+ cb->interact_request.manager_data = client;
+ cb->interact_done.callback = KSMInteractDoneProc;
+ cb->interact_done.manager_data = client;
+ cb->save_yourself_request.callback = KSMSaveYourselfRequestProc;
+ cb->save_yourself_request.manager_data = client;
+ cb->save_yourself_phase2_request.callback = KSMSaveYourselfPhase2RequestProc;
+ cb->save_yourself_phase2_request.manager_data = client;
+ cb->save_yourself_done.callback = KSMSaveYourselfDoneProc;
+ cb->save_yourself_done.manager_data = client;
+ cb->close_connection.callback = KSMCloseConnectionProc;
+ cb->close_connection.manager_data = client;
+ cb->set_properties.callback = KSMSetPropertiesProc;
+ cb->set_properties.manager_data = client;
+ cb->delete_properties.callback = KSMDeletePropertiesProc;
+ cb->delete_properties.manager_data = client;
+ cb->get_properties.callback = KSMGetPropertiesProc;
+ cb->get_properties.manager_data = client;
+
+ *mask_ret = SmsRegisterClientProcMask | SmsInteractRequestProcMask | SmsInteractDoneProcMask | SmsSaveYourselfRequestProcMask
+ | SmsSaveYourselfP2RequestProcMask | SmsSaveYourselfDoneProcMask | SmsCloseConnectionProcMask | SmsSetPropertiesProcMask
+ | SmsDeletePropertiesProcMask | SmsGetPropertiesProcMask;
+ return 1;
}
- return 0;
- }
-
- cb->register_client.callback = KSMRegisterClientProc;
- cb->register_client.manager_data = client;
- cb->interact_request.callback = KSMInteractRequestProc;
- cb->interact_request.manager_data = client;
- cb->interact_done.callback = KSMInteractDoneProc;
- cb->interact_done.manager_data = client;
- cb->save_yourself_request.callback = KSMSaveYourselfRequestProc;
- cb->save_yourself_request.manager_data = client;
- cb->save_yourself_phase2_request.callback = KSMSaveYourselfPhase2RequestProc;
- cb->save_yourself_phase2_request.manager_data = client;
- cb->save_yourself_done.callback = KSMSaveYourselfDoneProc;
- cb->save_yourself_done.manager_data = client;
- cb->close_connection.callback = KSMCloseConnectionProc;
- cb->close_connection.manager_data = client;
- cb->set_properties.callback = KSMSetPropertiesProc;
- cb->set_properties.manager_data = client;
- cb->delete_properties.callback = KSMDeletePropertiesProc;
- cb->delete_properties.manager_data = client;
- cb->get_properties.callback = KSMGetPropertiesProc;
- cb->get_properties.manager_data = client;
-
- *mask_ret = SmsRegisterClientProcMask | SmsInteractRequestProcMask | SmsInteractDoneProcMask | SmsSaveYourselfRequestProcMask
- | SmsSaveYourselfP2RequestProcMask | SmsSaveYourselfDoneProcMask | SmsCloseConnectionProcMask | SmsSetPropertiesProcMask | SmsDeletePropertiesProcMask
- | SmsGetPropertiesProcMask;
- return 1;
-}
#ifdef HAVE__ICETRANSNOLISTEN
extern "C" int _IceTransNoListen(const char *protocol);
@@ -490,6 +491,12 @@ KSMServer::KSMServer(InitFlags flags)
QSocketNotifier *n = new QSocketNotifier(sockets[1], QSocketNotifier::Read, this);
qApp->connect(n, &QSocketNotifier::activated, &QApplication::quit);
+ const QString runtimeDirectory = QStandardPaths::writableLocation(QStandardPaths::RuntimeLocation);
+ iceAuthFile.setFileTemplate(runtimeDirectory + QStringLiteral("/iceauth_XXXXXX"));
+ if (!iceAuthFile.open())
+ qFatal("Failed to create ICEauthority file");
+ setenv("ICEAUTHORITY", qPrintable(iceAuthFile.fileName()), true);
+
new KSMServerInterfaceAdaptor(this);
QDBusConnection::sessionBus().registerObject(QStringLiteral("/KSMServer"), this);
the_server = this;
@@ -545,7 +552,11 @@ KSMServer::KSMServer(InitFlags flags)
fclose(f);
setenv("SESSION_MANAGER", session_manager, true);
- auto updateEnvJob = new UpdateLaunchEnvJob(QStringLiteral("SESSION_MANAGER"), QString::fromLatin1(session_manager));
+ QProcessEnvironment newEnv;
+ newEnv.insert(QStringLiteral("SESSION_MANAGER"), QString::fromLatin1(session_manager));
+ newEnv.insert(QStringLiteral("ICEAUTHORITY"), iceAuthFile.fileName());
+
+ auto updateEnvJob = new UpdateLaunchEnvJob(newEnv);
updateEnvJob->exec();
free(session_manager);
diff --git a/ksmserver/server.h b/ksmserver/server.h
index b8904ff0c3..b40629131d 100644
--- a/ksmserver/server.h
+++ b/ksmserver/server.h
@@ -25,6 +25,7 @@ extern "C" {
#include <QDBusMessage>
#include <QObject>
#include <QStringList>
+#include <QTemporaryFile>
#include <KConfigGroup>
#include <QMap>
@@ -223,5 +224,6 @@ private:
OrgKdeKWinSessionInterface *m_kwinInterface;
int sockets[2];
+ QTemporaryFile iceAuthFile;
friend bool readFromPipe(int pipe);
};
--
GitLab

View File

@ -11,7 +11,7 @@
Name: plasma-workspace
Summary: Plasma workspace, applications and applets
Version: 5.27.10
Release: 1
Release: 2
License: GPLv2+
URL: https://invent.kde.org/plasma/%{name}
@ -43,6 +43,10 @@ Patch107: plasma-workspace-5.25.90-enable-lock-logout-action.patch
# Hide virtual keyboard indicator on sddm.
# Do not remove this as it breaks Fedora's QA policy
Patch108: hide-virtual-keyboard-indicator-on-sddm.patch
# https://invent.kde.org/plasma/plasma-workspace/-/commit/da843d3fdb143ed44094c8e6246cfb8305f6f09f
Patch109: Authenticate-local-clients.patch
# https://invent.kde.org/plasma/plasma-workspace/-/commit/1d5aa1d27bff87b2d242ed759cfb2ce15a5c3de7
Patch110: Remove-iceauth-dependency.patch
# udev
BuildRequires: zlib-devel
@ -332,6 +336,8 @@ Requires: xsetroot
%patch106 -p1
%patch107 -p1
%patch108 -p1
%patch109 -p1
%patch110 -p1
%build
mkdir %{_target_platform}
@ -591,6 +597,9 @@ setsebool -P selinuxuser_execmod 1
%endif
%changelog
* Mon Jul 08 2024 zhangxianting <zhangxianting@uniontech.com> - 5.27.10-2
- CVE-2024-36041
* Tue Jan 09 2024 jiangxinyu <jiangxinyu@kylinos.cn> - 5.27.10-1
- Update package to version 5.27.10