File remote-module-use-safe-directory-for-socket-API-sock.patch of Package fcitx

From 27208dc130124d650c94c3579bd7eea072f90d3b Mon Sep 17 00:00:00 2001
From: Matthias Gerstner <matthias.gerstner@suse.de>
Date: Thu, 24 Aug 2023 11:12:25 +0200
Subject: [PATCH] remote module: use safe directory for socket API socket

Placing this into /tmp opens a local DoS attack vector, allowing other
uses to pre-create this path and thereby making it impossible for fctx
to start.

Use a safe directory in $XDG_RUNTIME_DIR or $HOME, instead.
---
 src/module/remote/remote.c |  7 +++++--
 src/module/remote/remote.h | 31 +++++++++++++++++++++++++++++++
 tools/cli/fcitx-remote.c   |  4 ++--
 3 files changed, 38 insertions(+), 4 deletions(-)
 create mode 100644 src/module/remote/remote.h

diff --git a/src/module/remote/remote.c b/src/module/remote/remote.c
index eda44972..486b405b 100644
--- a/src/module/remote/remote.c
+++ b/src/module/remote/remote.c
@@ -36,6 +36,7 @@
 #include "fcitx/frontend.h"
 #include "fcitx/instance.h"
 #include "fcitx-utils/utils.h"
+#include "module/remote/remote.h"
 
 #define MAX_IMNAME_LEN 30
 
@@ -63,8 +64,10 @@ void* RemoteCreate(FcitxInstance* instance)
     FcitxRemote* remote = fcitx_utils_malloc0(sizeof(FcitxRemote));
     remote->owner = instance;
 
-    char *socketfile;
-    asprintf(&socketfile, "/tmp/fcitx-socket-:%d", fcitx_utils_get_display_number());
+    const char *socketfile = GetRemoteSocketPath(fcitx_utils_get_display_number());
+    if (!socketfile)
+        return NULL;
+
     remote->socket_fd = CreateSocket(socketfile);
     if (remote->socket_fd < 0) {
         FcitxLog(ERROR, _("Can't open socket %s: %s"), socketfile, strerror(errno));
diff --git a/src/module/remote/remote.h b/src/module/remote/remote.h
new file mode 100644
index 00000000..ee52c980
--- /dev/null
+++ b/src/module/remote/remote.h
@@ -0,0 +1,31 @@
+#include <stdlib.h>
+
+// returns a safe path name for a socket to use in the remote module and
+// remote utility.
+// if no safe directory can be determined this returns NULL and no remote
+// socket must be setup
+// otherwise a malloc'd string is returned that needs to be free()'d by the
+// caller when it isn't needed any longer.
+static inline const char* GetRemoteSocketPath(int display_nr)
+{
+    const char *hidden = "";
+    const char *dir = getenv("XDG_RUNTIME_DIR");
+    if (!dir) {
+        dir = getenv("HOME");
+        // if it is placed in the home directory then add a "." prefix to the
+        // basename to make it hidden
+        hidden = ".";
+    }
+    if (!dir) {
+        // no safe directory found
+        return NULL;
+    }
+
+    char *path = NULL;
+
+    if (asprintf(&path, "%s/%sfcitx-socket-:%d", dir, hidden, fcitx_utils_get_display_number()) < 0)
+        // formatting error
+        return NULL;
+
+    return path;
+}
diff --git a/tools/cli/fcitx-remote.c b/tools/cli/fcitx-remote.c
index 5e06ea76..80677100 100644
--- a/tools/cli/fcitx-remote.c
+++ b/tools/cli/fcitx-remote.c
@@ -36,6 +36,7 @@
 #include <limits.h>
 #include "fcitx/frontend.h"
 #include "fcitx-utils/utils.h"
+#include "module/remote/remote.h"
 
 int create_socket(const char *name)
 {
@@ -82,7 +83,6 @@ void usage(FILE* fp)
 
 int main(int argc, char *argv[])
 {
-    char *socketfile = NULL;
     int socket_fd;
 
     int o = 0;
@@ -124,7 +124,7 @@ int main(int argc, char *argv[])
         }
     }
 
-    asprintf(&socketfile, "/tmp/fcitx-socket-:%d", fcitx_utils_get_display_number());
+    const char *socketfile = GetRemoteSocketPath(fcitx_utils_get_display_number());
 
     socket_fd = create_socket(socketfile);
 
-- 
2.41.0

openSUSE Build Service is sponsored by