From 9434e8d69f76d7859ed7b18edc5a62450ad8d040 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Antonin=20D=C3=A9cimo?= Date: Fri, 11 Mar 2022 14:08:49 +0100 Subject: [PATCH] Check that XDG base directories paths are absolute MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The [spec][1] reads: > All paths set in these environment variables must be absolute. If an > implementation encounters a relative path in any of these variables it should > consider the path invalid and ignore it. and > If $XDG_DATA_HOME is either not set or empty, a default equal to > $HOME/.local/share should be used. Testing that the path is absolute also entails that is is non-empty. [1]: https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html Signed-off-by: Antonin Décimo --- cursor/os-compatibility.c | 2 +- cursor/xcursor.c | 2 +- src/wayland-client.c | 4 ++-- src/wayland-server.c | 7 ++++--- tests/compositor-introspection-test.c | 2 +- tests/protocol-logger-test.c | 2 +- tests/socket-test.c | 2 +- tests/test-runner.c | 4 ++-- 8 files changed, 13 insertions(+), 12 deletions(-) diff --git a/cursor/os-compatibility.c b/cursor/os-compatibility.c index 207e4911..07452a57 100644 --- a/cursor/os-compatibility.c +++ b/cursor/os-compatibility.c @@ -136,7 +136,7 @@ os_create_anonymous_file(off_t size) #endif { path = getenv("XDG_RUNTIME_DIR"); - if (!path) { + if (!path || path[0] != '/') { errno = ENOENT; return -1; } diff --git a/cursor/xcursor.c b/cursor/xcursor.c index 8107b7c5..43a5292c 100644 --- a/cursor/xcursor.c +++ b/cursor/xcursor.c @@ -515,7 +515,7 @@ xcursor_library_path(void) return strdup(env_var); env_var = getenv("XDG_DATA_HOME"); - if (!env_var) + if (!env_var || env_var[0] != '/') env_var = XDG_DATA_HOME_FALLBACK; suffix = CURSORDIR ":" XCURSORPATH; diff --git a/src/wayland-client.c b/src/wayland-client.c index 75692e6e..659c1325 100644 --- a/src/wayland-client.c +++ b/src/wayland-client.c @@ -1076,8 +1076,8 @@ connect_to_socket(const char *name) path_is_absolute = name[0] == '/'; runtime_dir = getenv("XDG_RUNTIME_DIR"); - if (!runtime_dir && !path_is_absolute) { - wl_log("error: XDG_RUNTIME_DIR not set in the environment.\n"); + if (((!runtime_dir || runtime_dir[0] != '/') && !path_is_absolute)) { + wl_log("error: XDG_RUNTIME_DIR is invalid or not set in the environment.\n"); /* to prevent programs reporting * "failed to create display: Success" */ errno = ENOENT; diff --git a/src/wayland-server.c b/src/wayland-server.c index 93e42c7a..00cfc27a 100644 --- a/src/wayland-server.c +++ b/src/wayland-server.c @@ -1557,8 +1557,9 @@ wl_socket_init_for_display_name(struct wl_socket *s, const char *name) if (name[0] != '/') { runtime_dir = getenv("XDG_RUNTIME_DIR"); - if (!runtime_dir) { - wl_log("error: XDG_RUNTIME_DIR not set in the environment\n"); + if (!runtime_dir || runtime_dir[0] != '/') { + wl_log("error: XDG_RUNTIME_DIR is invalid or not set in" + " the environment\n"); /* to prevent programs reporting * "failed to add socket: Success" */ @@ -1718,7 +1719,7 @@ wl_display_add_socket_fd(struct wl_display *display, int sock_fd) * * If the socket name is a relative path, the Unix socket will be created in * the directory pointed to by environment variable XDG_RUNTIME_DIR. If - * XDG_RUNTIME_DIR is not set, then this function fails and returns -1. + * XDG_RUNTIME_DIR is invalid or not set, then this function fails and returns -1. * * If the socket name is an absolute path, then it is used as-is for the * the Unix socket. diff --git a/tests/compositor-introspection-test.c b/tests/compositor-introspection-test.c index 83194ce2..064d2530 100644 --- a/tests/compositor-introspection-test.c +++ b/tests/compositor-introspection-test.c @@ -40,7 +40,7 @@ static const char * require_xdg_runtime_dir(void) { char *val = getenv("XDG_RUNTIME_DIR"); - assert(val && "set $XDG_RUNTIME_DIR to run this test"); + assert(val && val[0] == '/' && "set $XDG_RUNTIME_DIR to run this test"); return val; } diff --git a/tests/protocol-logger-test.c b/tests/protocol-logger-test.c index 80c74aae..a0ebd22a 100644 --- a/tests/protocol-logger-test.c +++ b/tests/protocol-logger-test.c @@ -40,7 +40,7 @@ static const char * require_xdg_runtime_dir(void) { char *val = getenv("XDG_RUNTIME_DIR"); - assert(val && "set $XDG_RUNTIME_DIR to run this test"); + assert(val && val[0] == '/' && "set $XDG_RUNTIME_DIR to run this test"); return val; } diff --git a/tests/socket-test.c b/tests/socket-test.c index 8d39edce..78743dc3 100644 --- a/tests/socket-test.c +++ b/tests/socket-test.c @@ -51,7 +51,7 @@ static const char * require_xdg_runtime_dir(void) { char *val = getenv("XDG_RUNTIME_DIR"); - assert(val && "set $XDG_RUNTIME_DIR to run this test"); + assert(val && val[0] == '/' && "set $XDG_RUNTIME_DIR to run this test"); return val; } diff --git a/tests/test-runner.c b/tests/test-runner.c index c0247b57..d07dab15 100644 --- a/tests/test-runner.c +++ b/tests/test-runner.c @@ -180,7 +180,7 @@ set_xdg_runtime_dir(void) xrd_env = getenv("XDG_RUNTIME_DIR"); /* if XDG_RUNTIME_DIR is not set in environ, fallback to /tmp */ assert((snprintf(xdg_runtime_dir, PATH_MAX, "%s/wayland-tests-XXXXXX", - xrd_env ? xrd_env : "/tmp") < PATH_MAX) + (xrd_env && xrd_env[0] == '/') ? xrd_env : "/tmp") < PATH_MAX) && "test error: XDG_RUNTIME_DIR too long"); assert(mkdtemp(xdg_runtime_dir) && "test error: mkdtemp failed"); @@ -200,7 +200,7 @@ static void rmdir_xdg_runtime_dir(void) { const char *xrd_env = getenv("XDG_RUNTIME_DIR"); - assert(xrd_env && "No XDG_RUNTIME_DIR set"); + assert(xrd_env && xrd_env[0] == '/' && "No XDG_RUNTIME_DIR set"); /* rmdir may fail if some test didn't do clean up */ if (rmdir(xrd_env) == -1)