[Xcb-commit] libxcb: 3 commits - configure.ac src tests
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Wed Mar 29 15:30:08 UTC 2023
configure.ac | 10 ---
src/xcb_util.c | 132 +++++++++++++++++++++++++++------------------------
tests/check_public.c | 35 +++++++++++++
3 files changed, 106 insertions(+), 71 deletions(-)
New commits:
commit 8935793f1f3751a6aa9d78955c7d6236177986de
Author: Demi Marie Obenour <demiobenour at gmail.com>
Date: Sat Mar 25 15:27:33 2023 -0400
Add tests for unix socket parsing
Signed-off-by: Demi Marie Obenour <demiobenour at gmail.com>
diff --git a/src/xcb_util.c b/src/xcb_util.c
index bf93568..5b1f495 100644
--- a/src/xcb_util.c
+++ b/src/xcb_util.c
@@ -93,20 +93,25 @@ static int _xcb_parse_display_path_to_socket(const char *name, char **host, char
struct stat sbuf;
char path[PATH_MAX];
size_t len;
- int _screen = 0;
+ int _screen = 0, res;
len = strlen(name);
if (len >= sizeof(path))
return 0;
memcpy(path, name, len + 1);
- if (0 != stat(path, &sbuf)) {
+ res = stat(path, &sbuf);
+ if (0 != res) {
unsigned long lscreen;
- char *dot = strrchr(path, '.'), *endptr;
- if (errno != ENOENT || !dot || dot[1] < '0' || dot[1] > '9')
+ char *dot, *endptr;
+ if (res != -1 || (errno != ENOENT && errno != ENOTDIR))
+ return 0;
+ dot = strrchr(path, '.');
+ if (!dot || dot[1] < '1' || dot[1] > '9')
return 0;
*dot = '\0';
+ errno = 0;
lscreen = strtoul(dot + 1, &endptr, 10);
- if (lscreen > INT_MAX || !endptr || *endptr)
+ if (lscreen > INT_MAX || !endptr || *endptr || errno)
return 0;
if (0 != stat(path, &sbuf))
return 0;
diff --git a/tests/check_public.c b/tests/check_public.c
index aed40c8..3caac1e 100644
--- a/tests/check_public.c
+++ b/tests/check_public.c
@@ -1,6 +1,10 @@
#include <check.h>
+#include <stdio.h>
#include <string.h>
#include <stdlib.h>
+#ifdef __unix__
+#include <unistd.h>
+#endif
#include "check_suites.h"
#include "xcb.h"
#include "xcbext.h"
@@ -97,6 +101,37 @@ static void parse_display_fail(const char *name)
START_TEST(parse_display_unix)
{
+#ifdef __unix__
+ char buf[sizeof "/tmp/xcb-test.XXXXXXX"];
+ char buf2[sizeof(buf) + 7];
+ int r, v;
+ memcpy(buf, "/tmp/xcb-test.XXXXXXX", sizeof buf);
+ v = mkstemp(buf);
+ ck_assert_msg(v >= 0, "cannot create temporary file");
+ parse_display_pass(buf, buf, 0, 0);
+ r = snprintf(buf2, sizeof buf2, "unix:%s", buf);
+ if (r < 5 || r >= (int)sizeof buf2) {
+ ck_assert_msg(0, "snprintf() failed (return value %d)", r);
+ unlink(buf);
+ return;
+ }
+ parse_display_pass(buf2, buf, 0, 0);
+ r = snprintf(buf2, sizeof buf2, "unix:%s.1", buf);
+ if (r < 7 || r >= (int)sizeof buf2) {
+ ck_assert_msg(0, "snprintf() failed (return value %d)", r);
+ unlink(buf);
+ return;
+ }
+ parse_display_pass(buf2, buf, 0, 1);
+ r = snprintf(buf2, sizeof buf2, "%s.1", buf);
+ if (r < 2 || r >= (int)sizeof buf2) {
+ ck_assert_msg(0, "snprintf() failed (return value %d)", r);
+ unlink(buf);
+ return;
+ }
+ parse_display_pass(buf2, buf, 0, 1);
+ unlink(buf);
+#endif
parse_display_pass(":0", "", 0, 0);
parse_display_pass(":1", "", 1, 0);
parse_display_pass(":0.1", "", 0, 1);
commit 095255531b90f0b442e6ca41fb3752a058562d07
Author: Demi Marie Obenour <demiobenour at gmail.com>
Date: Fri Aug 12 22:02:02 2022 -0400
DISPLAY starting with / or unix: is always a socket path
If DISPLAY starts with / or unix:, do not check for anything but a full
filesystem socket path. In particular, abstract AF_UNIX sockets and TCP
sockets will not be used in this case. Also be stricter about parsing
the screen part of /path.screen displays, and bail out after all stat()
errors other than ENOENT.
Signed-off-by: Demi Marie Obenour <demiobenour at gmail.com>
diff --git a/src/xcb_util.c b/src/xcb_util.c
index 7a71efe..bf93568 100644
--- a/src/xcb_util.c
+++ b/src/xcb_util.c
@@ -95,22 +95,22 @@ static int _xcb_parse_display_path_to_socket(const char *name, char **host, char
size_t len;
int _screen = 0;
- if (name[0] != '/')
- return 0;
len = strlen(name);
if (len >= sizeof(path))
return 0;
memcpy(path, name, len + 1);
if (0 != stat(path, &sbuf)) {
- char *dot = strrchr(path, '.');
- if (!dot)
+ unsigned long lscreen;
+ char *dot = strrchr(path, '.'), *endptr;
+ if (errno != ENOENT || !dot || dot[1] < '0' || dot[1] > '9')
return 0;
*dot = '\0';
-
+ lscreen = strtoul(dot + 1, &endptr, 10);
+ if (lscreen > INT_MAX || !endptr || *endptr)
+ return 0;
if (0 != stat(path, &sbuf))
return 0;
-
- _screen = atoi(dot + 1);
+ _screen = (int)lscreen;
}
if (host) {
@@ -149,8 +149,11 @@ static int _xcb_parse_display(const char *name, char **host, char **protocol,
return 0;
/* First check for <path to socket>[.<screen>] */
- if (_xcb_parse_display_path_to_socket(name, host, protocol, displayp, screenp))
- return 1;
+ if (name[0] == '/')
+ return _xcb_parse_display_path_to_socket(name, host, protocol, displayp, screenp);
+
+ if (strncmp(name, "unix:", 5) == 0)
+ return _xcb_parse_display_path_to_socket(name + 5, host, protocol, displayp, screenp);
slash = strrchr(name, '/');
@@ -235,38 +238,45 @@ static int _xcb_open(const char *host, char *protocol, const int display)
size_t filelen;
char *file = NULL;
int actual_filelen;
- struct stat sbuf;
- /* If protocol or host is "unix", fall through to Unix socket code below */
- if ((!protocol || (strcmp("unix",protocol) != 0)) &&
- (*host != '\0') && (strcmp("unix",host) != 0))
- {
- /* display specifies TCP */
- unsigned short port = X_TCP_PORT + display;
- return _xcb_open_tcp(host, protocol, port);
- }
+ if (protocol && strcmp("unix", protocol) == 0 && host && host[0] == '/') {
+ /* Full path to socket provided, ignore everything else */
+ filelen = strlen(host) + 1;
+ if (filelen > INT_MAX)
+ return -1;
+ file = malloc(filelen);
+ if (file == NULL)
+ return -1;
+ memcpy(file, host, filelen);
+ actual_filelen = (int)(filelen - 1);
+ } else {
+ /* If protocol or host is "unix", fall through to Unix socket code below */
+ if ((!protocol || (strcmp("unix",protocol) != 0)) &&
+ (*host != '\0') && (strcmp("unix",host) != 0))
+ {
+ /* display specifies TCP */
+ unsigned short port = X_TCP_PORT + display;
+ return _xcb_open_tcp(host, protocol, port);
+ }
#ifndef _WIN32
#if defined(HAVE_TSOL_LABEL_H) && defined(HAVE_IS_SYSTEM_LABELED)
- /* Check special path for Unix sockets under Solaris Trusted Extensions */
- if (is_system_labeled())
- {
- const char *tsol_base = "/var/tsol/doors/.X11-unix/X";
- char tsol_socket[PATH_MAX];
-
- snprintf(tsol_socket, sizeof(tsol_socket), "%s%d", tsol_base, display);
-
- if (stat(tsol_socket, &sbuf) == 0)
- base = tsol_base;
- }
+ /* Check special path for Unix sockets under Solaris Trusted Extensions */
+ if (is_system_labeled())
+ {
+ const char *tsol_base = "/var/tsol/doors/.X11-unix/X";
+ char tsol_socket[PATH_MAX];
+ struct stat sbuf;
+
+ snprintf(tsol_socket, sizeof(tsol_socket), "%s%d", tsol_base, display);
+
+ if (stat(tsol_socket, &sbuf) == 0)
+ base = tsol_base;
+ else if (errno != ENOENT)
+ return 0;
+ }
#endif
- if (0 == stat(host, &sbuf)) {
- file = strdup(host);
- if(file == NULL)
- return -1;
- filelen = actual_filelen = strlen(file);
- } else {
filelen = strlen(base) + 1 + sizeof(display) * 3 + 1;
file = malloc(filelen);
if(file == NULL)
@@ -274,24 +284,23 @@ static int _xcb_open(const char *host, char *protocol, const int display)
/* display specifies Unix socket */
actual_filelen = snprintf(file, filelen, "%s%d", base, display);
- }
- if(actual_filelen < 0)
- {
- free(file);
- return -1;
- }
- /* snprintf may truncate the file */
- filelen = MIN(actual_filelen, filelen - 1);
+ if(actual_filelen < 0)
+ {
+ free(file);
+ return -1;
+ }
+ /* snprintf may truncate the file */
+ filelen = MIN(actual_filelen, filelen - 1);
#ifdef HAVE_ABSTRACT_SOCKETS
- fd = _xcb_open_abstract(protocol, file, filelen);
- if (fd >= 0 || (errno != ENOENT && errno != ECONNREFUSED))
- {
- free(file);
- return fd;
- }
-
+ fd = _xcb_open_abstract(protocol, file, filelen);
+ if (fd >= 0 || (errno != ENOENT && errno != ECONNREFUSED))
+ {
+ free(file);
+ return fd;
+ }
#endif
+ }
fd = _xcb_open_unix(protocol, file);
free(file);
commit ccdef1a8a5b6956a3fb7115d634db213433dca75
Author: Demi Marie Obenour <demiobenour at gmail.com>
Date: Sun Jul 3 17:57:11 2022 -0400
Allow full paths to sockets on non-macOS
When combined with xorg/lib/libxtrans!7, this allows CVE-2020-25697 to
be mitigated by placing the AF_UNIX socket in a secure directory on the
filesystem.
This enables HAVE_LAUNCHD unconditionally and deletes the configure
switch.
Signed-off-by: Demi Marie Obenour <demiobenour at gmail.com>
diff --git a/configure.ac b/configure.ac
index 3d81a6b..e4a0376 100644
--- a/configure.ac
+++ b/configure.ac
@@ -247,16 +247,6 @@ XCB_EXTENSION(XTest, yes)
XCB_EXTENSION(Xv, yes)
XCB_EXTENSION(XvMC, yes)
-AC_ARG_WITH(launchd, AS_HELP_STRING([--with-launchd], [Build with support for Apple's launchd (default: auto)]), [LAUNCHD=$withval], [LAUNCHD=auto])
-if test "x$LAUNCHD" = xauto; then
- unset LAUNCHD
- AC_CHECK_PROG(LAUNCHD, [launchd], [yes], [no], [$PATH$PATH_SEPARATOR/sbin])
-fi
-
-if test "x$LAUNCHD" = xyes ; then
- AC_DEFINE(HAVE_LAUNCHD, 1, [launchd support available])
-fi
-
AC_ARG_WITH(serverside-support, AS_HELP_STRING([--with-serverside-support], [Build with support for server-side usage of xcb. This is still EXPERIMENTAL! ABI/API may change! (default: no)]), [XCB_SERVERSIDE_SUPPORT=$withval], [XCB_SERVERSIDE_SUPPORT=no])
AM_CONDITIONAL(XCB_SERVERSIDE_SUPPORT, test "x$XCB_SERVERSIDE_SUPPORT" = "xyes")
diff --git a/src/xcb_util.c b/src/xcb_util.c
index 30bcf79..7a71efe 100644
--- a/src/xcb_util.c
+++ b/src/xcb_util.c
@@ -60,9 +60,7 @@
# include <sys/stat.h>
#endif
-#ifdef HAVE_LAUNCHD
#include <sys/stat.h>
-#endif
int xcb_popcount(uint32_t mask)
{
@@ -82,7 +80,6 @@ int xcb_sumof(uint8_t *list, int len)
return s;
}
-#ifdef HAVE_LAUNCHD
/* Return true and parse if name matches <path to socket>[.<screen>]
* Upon success:
* host = <path to socket>
@@ -95,9 +92,15 @@ static int _xcb_parse_display_path_to_socket(const char *name, char **host, char
{
struct stat sbuf;
char path[PATH_MAX];
+ size_t len;
int _screen = 0;
- strlcpy(path, name, sizeof(path));
+ if (name[0] != '/')
+ return 0;
+ len = strlen(name);
+ if (len >= sizeof(path))
+ return 0;
+ memcpy(path, name, len + 1);
if (0 != stat(path, &sbuf)) {
char *dot = strrchr(path, '.');
if (!dot)
@@ -133,7 +136,6 @@ static int _xcb_parse_display_path_to_socket(const char *name, char **host, char
return 1;
}
-#endif
static int _xcb_parse_display(const char *name, char **host, char **protocol,
int *displayp, int *screenp)
@@ -146,11 +148,9 @@ static int _xcb_parse_display(const char *name, char **host, char **protocol,
if(!name)
return 0;
-#ifdef HAVE_LAUNCHD
/* First check for <path to socket>[.<screen>] */
if (_xcb_parse_display_path_to_socket(name, host, protocol, displayp, screenp))
return 1;
-#endif
slash = strrchr(name, '/');
@@ -235,6 +235,7 @@ static int _xcb_open(const char *host, char *protocol, const int display)
size_t filelen;
char *file = NULL;
int actual_filelen;
+ struct stat sbuf;
/* If protocol or host is "unix", fall through to Unix socket code below */
if ((!protocol || (strcmp("unix",protocol) != 0)) &&
@@ -250,7 +251,6 @@ static int _xcb_open(const char *host, char *protocol, const int display)
/* Check special path for Unix sockets under Solaris Trusted Extensions */
if (is_system_labeled())
{
- struct stat sbuf;
const char *tsol_base = "/var/tsol/doors/.X11-unix/X";
char tsol_socket[PATH_MAX];
@@ -261,16 +261,12 @@ static int _xcb_open(const char *host, char *protocol, const int display)
}
#endif
-#ifdef HAVE_LAUNCHD
- struct stat sbuf;
if (0 == stat(host, &sbuf)) {
file = strdup(host);
if(file == NULL)
return -1;
filelen = actual_filelen = strlen(file);
- } else
-#endif
- {
+ } else {
filelen = strlen(base) + 1 + sizeof(display) * 3 + 1;
file = malloc(filelen);
if(file == NULL)
More information about the xcb-commit
mailing list