fcitx/remote-module-use-safe-directory-for-socket-API-sock.patch

112 lines
3.5 KiB
Diff

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