Support LAUNCHD code on Linux. Enable by default. [v2]

The launchd code allows $DISPLAY to be set to any path name, which
allows placing the X connection socket in a more secure location in
the filesystem than /tmp.

This is intended to help fix the security issue raised here:

    https://www.openwall.com/lists/oss-security/2020/11/09/3
    https://lists.x.org/archives/xorg-devel/2020-November/058626.html

Signed-off-by: Keith Packard <keithp@keithp.com>

----

v2
	Make internal version of strlcpy static so that we don't
	publish this name to applications
This commit is contained in:
Keith Packard 2020-02-05 14:57:18 -08:00
parent 704e0a91b1
commit d005e45254
4 changed files with 70 additions and 4 deletions

View File

@ -173,6 +173,15 @@ dnl check for support for Solaris Trusted Extensions
AC_CHECK_HEADERS([tsol/label.h])
AC_CHECK_FUNCS([is_system_labeled])
dnl check for strlcpy
AC_SEARCH_LIBS(strlcpy, [bsd], [AC_DEFINE(HAVE_STRLCPY, 1, [strlcpy() function is available])],)
case "$LIBS" in
*-lbsd*)
AC_DEFINE(HAVE_LIBBSD, 1, [use -lbsd for bsd string functions])
;;
esac
dnl check for IOV_MAX, and fall back to UIO_MAXIOV on BSDish systems
AC_CHECK_DECL([IOV_MAX], [],
[AC_CHECK_DECL([UIO_MAXIOV], [AC_DEFINE([IOV_MAX], [UIO_MAXIOV])],
@ -247,7 +256,7 @@ 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])
AC_ARG_WITH(launchd, AS_HELP_STRING([--with-launchd], [Build with support for Apple's launchd (default: auto)]), [LAUNCHD=$withval], [LAUNCHD=yes])
if test "x$LAUNCHD" = xauto; then
unset LAUNCHD
AC_CHECK_PROG(LAUNCHD, [launchd], [yes], [no], [$PATH$PATH_SEPARATOR/sbin])

View File

@ -5,7 +5,7 @@ EXTSOURCES = xproto.c \
xc_misc.c
AM_CFLAGS = $(BASE_CFLAGS) $(NEEDED_CFLAGS) $(XDMCP_CFLAGS)
libxcb_la_LIBADD = $(NEEDED_LIBS) $(XDMCP_LIBS)
libxcb_la_LIBADD = $(LIBS) $(NEEDED_LIBS) $(XDMCP_LIBS)
libxcb_la_SOURCES = \
xcb_conn.c xcb_out.c xcb_in.c xcb_ext.c xcb_xid.c \
xcb_list.c xcb_util.c xcb_auth.c c_client.py

45
src/strlcpy.c Normal file
View File

@ -0,0 +1,45 @@
/*
* Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND TODD C. MILLER DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL TODD C. MILLER BE LIABLE
* FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*
* Copy src to string dst of size siz. At most siz-1 characters
* will be copied. Always NUL terminates (unless siz == 0).
* Returns strlen(src); if retval >= siz, truncation occurred.
*/
static size_t
xcb_strlcpy(char *dst, const char *src, size_t siz)
{
register char *d = dst;
register const char *s = src;
register size_t n = siz;
/* Copy as many bytes as will fit */
if (n != 0 && --n != 0) {
do {
if ((*d++ = *s++) == 0)
break;
} while (--n != 0);
}
/* Not enough room in dst, add NUL and traverse rest of src */
if (n == 0) {
if (siz != 0)
*d = '\0'; /* NUL-terminate dst */
while (*s++);
}
return s - src - 1; /* count does not include NUL */
}

View File

@ -83,6 +83,16 @@ int xcb_sumof(uint8_t *list, int len)
}
#ifdef HAVE_LAUNCHD
#ifdef HAVE_STRLCPY
# ifdef HAVE_LIBBSD
# include <bsd/string.h> /* for strlcpy */
# endif
# define xcb_strlcpy(dst, src, size) strlcpy(dst, src, size)
#else
# include "strlcpy.c"
#endif
/* Return true and parse if name matches <path to socket>[.<screen>]
* Upon success:
* host = <path to socket>
@ -97,7 +107,7 @@ static int _xcb_parse_display_path_to_socket(const char *name, char **host, char
char path[PATH_MAX];
int _screen = 0;
strlcpy(path, name, sizeof(path));
xcb_strlcpy(path, name, sizeof(path));
if (0 != stat(path, &sbuf)) {
char *dot = strrchr(path, '.');
if (!dot)
@ -230,6 +240,9 @@ static int _xcb_open(const char *host, char *protocol, const int display)
static const char unix_base[] = "/usr/spool/sockets/X11/";
#else
static const char unix_base[] = "/tmp/.X11-unix/X";
#endif
#ifdef HAVE_LAUNCHD
struct stat sbuf;
#endif
const char *base = unix_base;
size_t filelen;
@ -262,7 +275,6 @@ 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)