diff options
44 files changed, 748 insertions, 239 deletions
diff --git a/fontconfig/README b/fontconfig/README index d2288a559..8b34edcae 100644 --- a/fontconfig/README +++ b/fontconfig/README @@ -1,12 +1,65 @@ Fontconfig Font configuration and customization library - Version 2.11 - 2013-10-11 + Version 2.11.1 + 2014-03-24 Check INSTALL for compilation and installation instructions. Report bugs to https://bugs.freedesktop.org in the fontconfig module. +2.11.1 + +Akira TAGOH (31): + do not build test-migration for Win32 + Fix build issue on Debian/kFreeBSD 7.0 + Update ax_pthread.m4 to the latest version + Fix the dynamic loading issue on NetBSD + Use stat() if there are no d_type in struct dirent + Fix a build issue on Solaris 10 + Change the default weight on match to FC_WEIGHT_NORMAL + Warn if no <test> nor <edit> elements in <match> + Correct DTD + Re-scan font directories only when it contains subdirs + Fix typo + Bug 72086 - Check for gperf in autogen.sh + Simplify to validate the availability of posix_fadvise + Simplify to validate the availability of scandir + Fix a typo + Fix a build issue on platforms where doesn't support readlink() + Improve the performance issue on rescanning directories + Bug 73686 - confdir is not set correctly in fontconfig.pc + Update zh_hk.orth + clean up the unused files + Add missing license headers + Update the use of autotools' macro + Fix a crash issue when empty strings are set to the BDF properties + Add a doc for FcDirCacheRescan + Add missing #include <sys/statvfs.h> in fcstat.c + Fix incompatible API on AIX with random_r and initstate_r + Fallback to lstat() in case the filesystem doesn't support d_type in struct dirent + Update doc to include the version info of `since when' + Bug 73291 - poppler does not show fl ligature + Add README describes the criteria to add/modify the orthography files + Fix autoconf warning, warning: AC_COMPILE_IFELSE was called before AC_USE_SYSTEM_EXTENSIONS + +Alan Coopersmith (3): + Leave room for null terminators in arrays + Avoid memory leak when NULL path passed to FcStrBuildFilename + Avoid null pointer dereference in FcNameParse if malloc fails + +Behdad Esfahbod (1): + Bug 72380 - Never drop first font when trimming + +Frederic Crozat (2): + Fix inversion between Tinos and Cousine in the comment + Add metric aliases for additional Google ChromeOS fonts + +Jehan (1): + Defaulting <cachedir> to LOCAL_APPDATA_FONTCONFIG_CACHE for Win32 build + +Ross Burton (1): + fc-cache: --sysroot option takes an argument + 2.11 Akira TAGOH (15): diff --git a/fontconfig/configure.ac b/fontconfig/configure.ac index 331bd32aa..1086a9a55 100644 --- a/fontconfig/configure.ac +++ b/fontconfig/configure.ac @@ -33,34 +33,10 @@ dnl This is the package version number, not the shared library dnl version. This same version number must appear in fontconfig/fontconfig.h dnl Yes, it is a pain to synchronize version numbers. Unfortunately, it's dnl not possible to extract the version number here from fontconfig.h -AC_INIT([fontconfig], [2.11.0], [https://bugs.freedesktop.org/enter_bug.cgi?product=fontconfig]) +AC_INIT([fontconfig], [2.11.1], [https://bugs.freedesktop.org/enter_bug.cgi?product=fontconfig]) AM_INIT_AUTOMAKE([1.11 parallel-tests dist-bzip2]) m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])]) -dnl Initialize libtool -LT_PREREQ([2.2]) -LT_INIT([disable-static win32-dll]) - -dnl libtool versioning - -dnl bump revision when fixing bugs -dnl bump current and age, reset revision to zero when adding APIs -dnl bump current, leave age, reset revision to zero when changing/removing APIS -LIBT_CURRENT=9 -LIBT_REVISION=0 -AC_SUBST(LIBT_CURRENT) -AC_SUBST(LIBT_REVISION) -LIBT_AGE=8 - -LIBT_VERSION_INFO="$LIBT_CURRENT:$LIBT_REVISION:$LIBT_AGE" -AC_SUBST(LIBT_VERSION_INFO) - -LIBT_CURRENT_MINUS_AGE=`expr $LIBT_CURRENT - $LIBT_AGE` -AC_SUBST(LIBT_CURRENT_MINUS_AGE) - -PKGCONFIG_REQUIRES= -PKGCONFIG_REQUIRES_PRIVATELY= - dnl ========================================================================== AC_CONFIG_HEADERS(config.h) @@ -87,6 +63,30 @@ else AC_MSG_RESULT($_predefined_rm) fi +dnl Initialize libtool +LT_PREREQ([2.2]) +LT_INIT([disable-static win32-dll]) + +dnl libtool versioning + +dnl bump revision when fixing bugs +dnl bump current and age, reset revision to zero when adding APIs +dnl bump current, leave age, reset revision to zero when changing/removing APIS +LIBT_CURRENT=9 +LIBT_REVISION=0 +AC_SUBST(LIBT_CURRENT) +AC_SUBST(LIBT_REVISION) +LIBT_AGE=8 + +LIBT_VERSION_INFO="$LIBT_CURRENT:$LIBT_REVISION:$LIBT_AGE" +AC_SUBST(LIBT_VERSION_INFO) + +LIBT_CURRENT_MINUS_AGE=`expr $LIBT_CURRENT - $LIBT_AGE` +AC_SUBST(LIBT_CURRENT_MINUS_AGE) + +PKGCONFIG_REQUIRES= +PKGCONFIG_REQUIRES_PRIVATELY= + dnl ========================================================================== case "$host" in diff --git a/fontconfig/fontconfig/fontconfig.h b/fontconfig/fontconfig/fontconfig.h index 1a283a1ce..225825127 100644 --- a/fontconfig/fontconfig/fontconfig.h +++ b/fontconfig/fontconfig/fontconfig.h @@ -52,7 +52,7 @@ typedef int FcBool; #define FC_MAJOR 2 #define FC_MINOR 11 -#define FC_REVISION 0 +#define FC_REVISION 1 #define FC_VERSION ((FC_MAJOR * 10000) + (FC_MINOR * 100) + (FC_REVISION)) diff --git a/libX11/libX11.def b/libX11/libX11.def index 9d2977e93..c9d4100e5 100644 --- a/libX11/libX11.def +++ b/libX11/libX11.def @@ -149,6 +149,7 @@ EXPORTS XGetVisualInfo
XGetWindowAttributes
XGetWindowProperty
+ XGetWMClientMachine
XGetWMHints
XGetWMName
XGetWMNormalHints
@@ -357,4 +358,4 @@ EXPORTS XwcTextListToTextProperty
XwcTextPropertyToTextList
XWithdrawWindow
- XWMGeometry
\ No newline at end of file + XWMGeometry
diff --git a/libxcb/Makefile.am b/libxcb/Makefile.am index 387c2f28e..e9124892b 100644 --- a/libxcb/Makefile.am +++ b/libxcb/Makefile.am @@ -86,8 +86,14 @@ pkgconfig_DATA += xcb-xvmc.pc endif +AM_TESTS_ENVIRONMENT = \ + AM_SRCDIR=${srcdir} + +TESTS=check-pc-requires + EXTRA_DIST = \ tools/README \ tools/api_conv.pl \ tools/constants \ -autogen.sh +autogen.sh \ +$(TESTS) diff --git a/libxcb/check-pc-requires b/libxcb/check-pc-requires new file mode 100644 index 000000000..0fd9c6597 --- /dev/null +++ b/libxcb/check-pc-requires @@ -0,0 +1,70 @@ +#!/bin/sh + +case "$AM_SRCDIR" in +"") + AM_SRCDIR="." + ;; +*) + ;; +esac + +fix=n +status=0 +case "$1" in +"-fix") + fix=y + ;; +esac + +for inc in src/*.h; do + package=xcb-`basename $inc .h` + pcin="$AM_SRCDIR"/$package.pc.in + if [ -f $pcin ]; then + included=`grep '# *include' $inc | + sed -e 's/[^<"]*[<"]//' -e 's/[>"]//' | + grep -v 'xcb.h\|xproto.h'` + requires=`grep '^Requires:' $pcin` + missing="" + for i in $included; do + ibase=`basename $i .h` + r="xcb-$ibase" + rpcin="$AM_SRCDIR"/$r.pc.in + if [ -f $rpcin ]; then + m="$r" + for has in $requires; do + if [ $has = $r ]; then + m="" + fi + done + case "$m" in + "") + ;; + *) + case "$missing" in + "") + missing=$m + ;; + *) + missing="$missing $m" + ;; + esac + ;; + esac + fi + done + case "$missing" in + "") + ;; + *) + if [ "$fix" = "y" ]; then + echo $package adding dependency on $missing + sed -i '/^Requires:/s/$/ '"$missing"'/' $pcin + else + echo $package missing $missing + status=1 + fi + ;; + esac + fi +done +exit $status diff --git a/libxcb/src/c_client.py b/libxcb/src/c_client.py index 9430c005a..af1337ec0 100644 --- a/libxcb/src/c_client.py +++ b/libxcb/src/c_client.py @@ -191,7 +191,7 @@ def c_open(self): _c('#define ALIGNOF(type) offsetof(struct { char dummy; type member; }, member)') if _ns.is_ext: - for (n, h) in self.imports: + for (n, h) in self.direct_imports: _hc('#include "%s.h"', h) _h('') diff --git a/libxcb/xcb-present.pc.in b/libxcb/xcb-present.pc.in index 848ac02ef..e2eccc489 100644 --- a/libxcb/xcb-present.pc.in +++ b/libxcb/xcb-present.pc.in @@ -6,6 +6,6 @@ includedir=@includedir@ Name: XCB Present Description: XCB Present Extension Version: @PACKAGE_VERSION@ -Requires: xcb +Requires: xcb xcb-randr xcb-xfixes xcb-sync Libs: -L${libdir} -lxcb-present Cflags: -I${includedir} diff --git a/libxcb/xcb-randr.pc.in b/libxcb/xcb-randr.pc.in index ac7f35d97..09c3d12e2 100644 --- a/libxcb/xcb-randr.pc.in +++ b/libxcb/xcb-randr.pc.in @@ -6,6 +6,6 @@ includedir=@includedir@ Name: XCB RandR Description: XCB RandR Extension Version: @PACKAGE_VERSION@ -Requires: xcb +Requires: xcb xcb-render Libs: -L${libdir} -lxcb-randr Cflags: -I${includedir} diff --git a/libxcb/xcb-xinput.pc.in b/libxcb/xcb-xinput.pc.in index ec3122947..ff34ab470 100644 --- a/libxcb/xcb-xinput.pc.in +++ b/libxcb/xcb-xinput.pc.in @@ -6,6 +6,6 @@ includedir=@includedir@ Name: XCB XInput Description: XCB XInput Extension (EXPERIMENTAL) Version: @PACKAGE_VERSION@ -Requires: xcb +Requires: xcb xcb-xfixes Libs: -L${libdir} -lxcb-xinput Cflags: -I${includedir} diff --git a/mesalib/src/mesa/main/fbobject.c b/mesalib/src/mesa/main/fbobject.c index dfe2f1e93..107919f0b 100644 --- a/mesalib/src/mesa/main/fbobject.c +++ b/mesalib/src/mesa/main/fbobject.c @@ -1080,6 +1080,12 @@ _mesa_test_framebuffer_completeness(struct gl_context *ctx, fb->MaxNumLayers = max_layer_count; + if (numImages == 0) { + fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT; + fbo_incomplete(ctx, "no attachments", -1); + return; + } + if (_mesa_is_desktop_gl(ctx) && !ctx->Extensions.ARB_ES2_compatibility) { /* Check that all DrawBuffers are present */ for (j = 0; j < ctx->Const.MaxDrawBuffers; j++) { @@ -1108,12 +1114,6 @@ _mesa_test_framebuffer_completeness(struct gl_context *ctx, } } - if (numImages == 0) { - fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT; - fbo_incomplete(ctx, "no attachments", -1); - return; - } - /* Provisionally set status = COMPLETE ... */ fb->_Status = GL_FRAMEBUFFER_COMPLETE_EXT; @@ -2004,8 +2004,9 @@ check_begin_texture_render(struct gl_context *ctx, struct gl_framebuffer *fb) static void check_end_texture_render(struct gl_context *ctx, struct gl_framebuffer *fb) { - if (_mesa_is_winsys_fbo(fb)) - return; /* can't render to texture with winsys framebuffers */ + /* Skip if we know NeedsFinishRenderTexture won't be set. */ + if (_mesa_is_winsys_fbo(fb) && !ctx->Driver.BindRenderbufferTexImage) + return; if (ctx->Driver.FinishRenderTexture) { GLuint i; diff --git a/mesalib/src/mesa/main/formats.c b/mesalib/src/mesa/main/formats.c index c3e80491d..e74625f23 100644 --- a/mesalib/src/mesa/main/formats.c +++ b/mesalib/src/mesa/main/formats.c @@ -3124,9 +3124,9 @@ _mesa_format_matches_format_and_type(mesa_format mesa_format, case MESA_FORMAT_L_UNORM16: return format == GL_LUMINANCE && type == GL_UNSIGNED_SHORT && !swapBytes; case MESA_FORMAT_I_UNORM8: - return format == GL_INTENSITY && type == GL_UNSIGNED_BYTE; + return format == GL_RED && type == GL_UNSIGNED_BYTE; case MESA_FORMAT_I_UNORM16: - return format == GL_INTENSITY && type == GL_UNSIGNED_SHORT && !swapBytes; + return format == GL_RED && type == GL_UNSIGNED_SHORT && !swapBytes; case MESA_FORMAT_YCBCR: return format == GL_YCBCR_MESA && @@ -3218,9 +3218,9 @@ _mesa_format_matches_format_and_type(mesa_format mesa_format, return format == GL_LUMINANCE_ALPHA && type == GL_HALF_FLOAT && !swapBytes; case MESA_FORMAT_I_FLOAT32: - return format == GL_INTENSITY && type == GL_FLOAT && !swapBytes; + return format == GL_RED && type == GL_FLOAT && !swapBytes; case MESA_FORMAT_I_FLOAT16: - return format == GL_INTENSITY && type == GL_HALF_FLOAT && !swapBytes; + return format == GL_RED && type == GL_HALF_FLOAT && !swapBytes; case MESA_FORMAT_R_FLOAT32: return format == GL_RED && type == GL_FLOAT && !swapBytes; @@ -3248,13 +3248,17 @@ _mesa_format_matches_format_and_type(mesa_format mesa_format, return format == GL_ALPHA_INTEGER && type == GL_INT && !swapBytes; case MESA_FORMAT_I_UINT8: + return format == GL_RED_INTEGER && type == GL_UNSIGNED_BYTE; case MESA_FORMAT_I_UINT16: + return format == GL_RED_INTEGER && type == GL_UNSIGNED_SHORT && !swapBytes; case MESA_FORMAT_I_UINT32: + return format == GL_RED_INTEGER && type == GL_UNSIGNED_INT && !swapBytes; case MESA_FORMAT_I_SINT8: + return format == GL_RED_INTEGER && type == GL_BYTE; case MESA_FORMAT_I_SINT16: + return format == GL_RED_INTEGER && type == GL_SHORT && !swapBytes; case MESA_FORMAT_I_SINT32: - /* GL_INTENSITY_INTEGER_EXT doesn't exist. */ - return GL_FALSE; + return format == GL_RED_INTEGER && type == GL_INT && !swapBytes; case MESA_FORMAT_L_UINT8: return format == GL_LUMINANCE_INTEGER_EXT && type == GL_UNSIGNED_BYTE; @@ -3421,7 +3425,7 @@ _mesa_format_matches_format_and_type(mesa_format mesa_format, return format == GL_LUMINANCE_ALPHA && type == GL_BYTE && littleEndian && !swapBytes; case MESA_FORMAT_I_SNORM8: - return format == GL_INTENSITY && type == GL_BYTE; + return format == GL_RED && type == GL_BYTE; case MESA_FORMAT_A_SNORM16: return format == GL_ALPHA && type == GL_SHORT && !swapBytes; case MESA_FORMAT_L_SNORM16: @@ -3430,7 +3434,7 @@ _mesa_format_matches_format_and_type(mesa_format mesa_format, return format == GL_LUMINANCE_ALPHA && type == GL_SHORT && littleEndian && !swapBytes; case MESA_FORMAT_I_SNORM16: - return format == GL_INTENSITY && type == GL_SHORT && littleEndian && + return format == GL_RED && type == GL_SHORT && littleEndian && !swapBytes; case MESA_FORMAT_B10G10R10A2_UINT: diff --git a/mesalib/src/mesa/state_tracker/st_atom_texture.c b/mesalib/src/mesa/state_tracker/st_atom_texture.c index 3557a3fbe..75e6face4 100644 --- a/mesalib/src/mesa/state_tracker/st_atom_texture.c +++ b/mesalib/src/mesa/state_tracker/st_atom_texture.c @@ -198,6 +198,16 @@ st_get_texture_sampler_view_from_stobj(struct st_texture_object *stObj, if (!stObj->sampler_view) { stObj->sampler_view = st_create_texture_sampler_view_from_stobj(pipe, stObj, samp, format); + + } else if (stObj->sampler_view->context != pipe) { + /* Recreate view in correct context, use existing view as template */ + /* XXX: This isn't optimal, we should try to use more than one view. + Otherwise we create/destroy the view all the time + */ + struct pipe_sampler_view *sv = + pipe->create_sampler_view(pipe, stObj->pt, stObj->sampler_view); + pipe_sampler_view_reference(&stObj->sampler_view, NULL); + stObj->sampler_view = sv; } return stObj->sampler_view; diff --git a/xorg-server/config/config.c b/xorg-server/config/config.c index 883402bb5..97b621b89 100644 --- a/xorg-server/config/config.c +++ b/xorg-server/config/config.c @@ -132,10 +132,7 @@ config_odev_allocate_attribute_list(void) { struct OdevAttributes *attriblist; - attriblist = malloc(sizeof(struct OdevAttributes)); - if (!attriblist) - return NULL; - + attriblist = XNFalloc(sizeof(struct OdevAttributes)); xorg_list_init(&attriblist->list); return attriblist; } @@ -168,10 +165,7 @@ config_odev_find_or_add_attribute(struct OdevAttributes *attribs, int attrib) if (oa) return oa; - oa = calloc(1, sizeof(struct OdevAttribute)); - if (!oa) - return oa; - + oa = XNFcalloc(sizeof(struct OdevAttribute)); oa->attrib_id = attrib; xorg_list_append(&oa->member, &attribs->list); @@ -185,11 +179,8 @@ config_odev_add_attribute(struct OdevAttributes *attribs, int attrib, struct OdevAttribute *oa; oa = config_odev_find_or_add_attribute(attribs, attrib); - if (!oa) - return FALSE; - free(oa->attrib_name); - oa->attrib_name = strdup(attrib_name); + oa->attrib_name = XNFstrdup(attrib_name); oa->attrib_type = ODEV_ATTRIB_STRING; return TRUE; } @@ -201,9 +192,6 @@ config_odev_add_int_attribute(struct OdevAttributes *attribs, int attrib, struct OdevAttribute *oa; oa = config_odev_find_or_add_attribute(attribs, attrib); - if (!oa) - return FALSE; - oa->attrib_value = attrib_value; oa->attrib_type = ODEV_ATTRIB_INT; return TRUE; diff --git a/xorg-server/config/udev.c b/xorg-server/config/udev.c index d88abaaa1..a1b72c13b 100644 --- a/xorg-server/config/udev.c +++ b/xorg-server/config/udev.c @@ -55,7 +55,7 @@ static struct udev_monitor *udev_monitor; #ifdef CONFIG_UDEV_KMS -static Bool +static void config_udev_odev_setup_attribs(const char *path, const char *syspath, int major, int minor, config_odev_probe_proc_ptr probe_callback); @@ -457,40 +457,20 @@ config_udev_fini(void) #ifdef CONFIG_UDEV_KMS -static Bool +static void config_udev_odev_setup_attribs(const char *path, const char *syspath, int major, int minor, config_odev_probe_proc_ptr probe_callback) { struct OdevAttributes *attribs = config_odev_allocate_attribute_list(); - int ret; - - if (!attribs) - return FALSE; - - ret = config_odev_add_attribute(attribs, ODEV_ATTRIB_PATH, path); - if (ret == FALSE) - goto fail; - - ret = config_odev_add_attribute(attribs, ODEV_ATTRIB_SYSPATH, syspath); - if (ret == FALSE) - goto fail; - - ret = config_odev_add_int_attribute(attribs, ODEV_ATTRIB_MAJOR, major); - if (ret == FALSE) - goto fail; - ret = config_odev_add_int_attribute(attribs, ODEV_ATTRIB_MINOR, minor); - if (ret == FALSE) - goto fail; + config_odev_add_attribute(attribs, ODEV_ATTRIB_PATH, path); + config_odev_add_attribute(attribs, ODEV_ATTRIB_SYSPATH, syspath); + config_odev_add_int_attribute(attribs, ODEV_ATTRIB_MAJOR, major); + config_odev_add_int_attribute(attribs, ODEV_ATTRIB_MINOR, minor); /* ownership of attribs is passed to probe layer */ probe_callback(attribs); - return TRUE; -fail: - config_odev_free_attributes(attribs); - free(attribs); - return FALSE; } void diff --git a/xorg-server/configure.ac b/xorg-server/configure.ac index 162c0cf3c..a75ba8f69 100644 --- a/xorg-server/configure.ac +++ b/xorg-server/configure.ac @@ -133,7 +133,8 @@ AM_CONDITIONAL(SPECIAL_DTRACE_OBJECTS, [test "x$SPECIAL_DTRACE_OBJECTS" = "xyes" AC_HEADER_DIRENT AC_HEADER_STDC -AC_CHECK_HEADERS([fcntl.h stdlib.h string.h unistd.h dlfcn.h stropts.h fnmatch.h sys/utsname.h]) +AC_CHECK_HEADERS([fcntl.h stdlib.h string.h unistd.h dlfcn.h stropts.h \ + fnmatch.h sys/mkdev.h sys/utsname.h]) dnl Checks for typedefs, structures, and compiler characteristics. AC_C_CONST @@ -491,17 +492,14 @@ XORG_FONTSUBDIR(FONTTYPE1DIR, fonttype1dir, Type1) XORG_FONTSUBDIR(FONT75DPIDIR, font75dpidir, 75dpi) XORG_FONTSUBDIR(FONT100DPIDIR, font100dpidir, 100dpi) -dnl Uses --default-font-path if set, otherwise checks for /etc/X11/fontpath.d, -dnl otherwise uses standard subdirectories of FONTROOTDIR. When cross -dnl compiling, assume default font path uses standard FONTROOTDIR directories. +dnl Uses --with-default-font-path if set, otherwise uses standard +dnl subdirectories of FONTROOTDIR. Some distros set the default font path to +dnl "catalogue:/etc/X11/fontpath.d,built-ins" DEFAULT_FONT_PATH="${FONTMISCDIR}/,${FONTTTFDIR}/,${FONTOTFDIR}/,${FONTTYPE1DIR}/,${FONT100DPIDIR}/,${FONT75DPIDIR}/" -if test "$cross_compiling" != yes; then - AC_CHECK_FILE([${sysconfdir}/X11/fontpath.d], - [DEFAULT_FONT_PATH='catalogue:${sysconfdir}/X11/fontpath.d'], - [case $host_os in - darwin*) DEFAULT_FONT_PATH="${DEFAULT_FONT_PATH},/Library/Fonts,/System/Library/Fonts" ;; - esac]) -fi +case $host_os in + darwin*) DEFAULT_FONT_PATH="${DEFAULT_FONT_PATH},/Library/Fonts,/System/Library/Fonts" ;; +esac + AC_ARG_WITH(default-font-path, AS_HELP_STRING([--with-default-font-path=PATH], [Comma separated list of font dirs]), [ FONTPATH="$withval" ], [ FONTPATH="${DEFAULT_FONT_PATH}" ]) @@ -627,6 +625,7 @@ AC_ARG_ENABLE(pciaccess, AS_HELP_STRING([--enable-pciaccess], [Build Xorg with p AC_ARG_ENABLE(linux_acpi, AS_HELP_STRING([--disable-linux-acpi], [Disable building ACPI support on Linux (if available).]), [enable_linux_acpi=$enableval], [enable_linux_acpi=yes]) AC_ARG_ENABLE(linux_apm, AS_HELP_STRING([--disable-linux-apm], [Disable building APM support on Linux (if available).]), [enable_linux_apm=$enableval], [enable_linux_apm=yes]) AC_ARG_ENABLE(systemd-logind, AC_HELP_STRING([--enable-systemd-logind], [Build systemd-logind support (default: auto)]), [SYSTEMD_LOGIND=$enableval], [SYSTEMD_LOGIND=auto]) +AC_ARG_ENABLE(suid-wrapper, AC_HELP_STRING([--enable-suid-wrapper], [Build suid-root wrapper for legacy driver support on rootless xserver systems (default: no)]), [SUID_WRAPPER=$enableval], [SUID_WRAPPER=no]) dnl DDXes. AC_ARG_ENABLE(xorg, AS_HELP_STRING([--enable-xorg], [Build Xorg server (default: auto)]), [XORG=$enableval], [XORG=auto]) @@ -924,6 +923,16 @@ if test "x$SYSTEMD_LOGIND" = xyes; then fi AM_CONDITIONAL(SYSTEMD_LOGIND, [test "x$SYSTEMD_LOGIND" = xyes]) +if test "x$SUID_WRAPPER" = xyes; then + dnl The wrapper uses libdrm headers, so ensure they are available + PKG_CHECK_MODULES([LIBDRM], $LIBDRM) + dnl This is a define so that if some platforms want to put the wrapper + dnl somewhere else this can be easily changed + AC_DEFINE_DIR(SUID_WRAPPER_DIR, libexecdir, [Where to install Xorg.bin and Xorg.wrap]) + SETUID="no" +fi +AM_CONDITIONAL(SUID_WRAPPER, [test "x$SUID_WRAPPER" = xyes]) + if test "x$NEED_DBUS" = xyes; then AC_DEFINE(NEED_DBUS, 1, [Enable D-Bus core]) fi @@ -2116,7 +2125,6 @@ fi AC_MSG_RESULT([$XWIN]) if test "x$XWIN" = xyes; then - AC_DEFINE_DIR(SYSCONFDIR, sysconfdir, [Location of system.XWinrc]) AC_DEFINE_DIR(DEFAULT_LOGDIR, logdir, [Default log location]) AC_DEFINE_UNQUOTED(XORG_VERSION_CURRENT, [$VENDOR_RELEASE], [Current Xorg version]) AC_DEFINE_UNQUOTED(__VENDORDWEBSUPPORT__, ["$VENDOR_WEB"], [Vendor web address for support]) @@ -2440,6 +2448,7 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ [ Enable GNU and other extensions to the C environment for glibc])]) AC_DEFINE_DIR(PROJECTROOT, prefix, [Overall prefix]) +AC_DEFINE_DIR(SYSCONFDIR, sysconfdir, [sysconfdir]) AC_SUBST([RELEASE_DATE]) BUILD_DATE="`date +'%Y%m%d'`" @@ -2499,6 +2508,7 @@ dri3/Makefile present/Makefile hw/Makefile hw/xfree86/Makefile +hw/xfree86/Xorg.sh hw/xfree86/common/Makefile hw/xfree86/common/xf86Build.h hw/xfree86/ddc/Makefile diff --git a/xorg-server/hw/xfree86/Makefile.am b/xorg-server/hw/xfree86/Makefile.am index 73e1b4c1f..a315bbc17 100644 --- a/xorg-server/hw/xfree86/Makefile.am +++ b/xorg-server/hw/xfree86/Makefile.am @@ -81,9 +81,15 @@ Xorg_DEPENDENCIES = $(LOCAL_LIBS) Xorg_LDFLAGS = $(LD_EXPORT_SYMBOLS_FLAG) +if SUID_WRAPPER +wrapdir = $(SUID_WRAPPER_DIR) +wrap_PROGRAMS = Xorg.wrap +Xorg_wrap_SOURCES = xorg-wrapper.c +endif + BUILT_SOURCES = xorg.conf.example DISTCLEANFILES = xorg.conf.example -EXTRA_DIST = xorgconf.cpp +EXTRA_DIST = xorgconf.cpp Xorg.sh.in # Without logdir, X will post an error on the terminal and will not start install-data-local: @@ -98,6 +104,11 @@ if INSTALL_SETUID chown root $(DESTDIR)$(bindir)/Xorg chmod u+s $(DESTDIR)$(bindir)/Xorg endif +if SUID_WRAPPER + mv $(DESTDIR)$(bindir)/Xorg $(DESTDIR)$(SUID_WRAPPER_DIR)/Xorg.bin + ${INSTALL} -m 755 Xorg.sh $(DESTDIR)$(bindir)/Xorg + -chown root $(DESTDIR)$(SUID_WRAPPER_DIR)/Xorg.wrap && chmod u+s $(DESTDIR)$(SUID_WRAPPER_DIR)/Xorg.wrap +endif uninstall-local: if CYGWIN @@ -119,7 +130,7 @@ xorg.conf.example: xorgconf.cpp relink: $(AM_V_at)rm -f Xorg$(EXEEXT) && $(MAKE) Xorg$(EXEEXT) -CLEANFILES = sdksyms.c sdksyms.dep +CLEANFILES = sdksyms.c sdksyms.dep Xorg.sh EXTRA_DIST += sdksyms.sh sdksyms.dep sdksyms.c: sdksyms.sh diff --git a/xorg-server/hw/xfree86/Xorg.sh.in b/xorg-server/hw/xfree86/Xorg.sh.in new file mode 100644 index 000000000..cef4859c8 --- /dev/null +++ b/xorg-server/hw/xfree86/Xorg.sh.in @@ -0,0 +1,11 @@ +#!/bin/sh +# +# Execute Xorg.wrap if it exists otherwise execute Xorg.bin directly. +# This allows distros to put the suid wrapper in a separate package. + +basedir=@SUID_WRAPPER_DIR@ +if [ -x "$basedir"/Xorg.wrap ]; then + exec "$basedir"/Xorg.wrap "$@" +else + exec "$basedir"/Xorg.bin "$@" +fi diff --git a/xorg-server/hw/xfree86/common/xf86Xinput.c b/xorg-server/hw/xfree86/common/xf86Xinput.c index 36b92a9f7..bc6b73f91 100644 --- a/xorg-server/hw/xfree86/common/xf86Xinput.c +++ b/xorg-server/hw/xfree86/common/xf86Xinput.c @@ -81,8 +81,12 @@ #include <stdarg.h> #include <stdint.h> /* for int64_t */ +#include <sys/types.h> #include <sys/stat.h> #include <unistd.h> +#ifdef HAVE_SYS_MKDEV_H +#include <sys/mkdev.h> /* for major() & minor() on Solaris */ +#endif #include "mi.h" @@ -766,6 +770,11 @@ xf86DeleteInput(InputInfoPtr pInp, int flags) FreeInputAttributes(pInp->attrs); + if (pInp->flags & XI86_SERVER_FD) { + systemd_logind_release_fd(pInp->major, pInp->minor); + close(pInp->fd); + } + /* Remove the entry from the list. */ if (pInp == xf86InputDevs) xf86InputDevs = pInp->next; @@ -779,11 +788,6 @@ xf86DeleteInput(InputInfoPtr pInp, int flags) /* Else the entry wasn't in the xf86InputDevs list (ignore this). */ } - if (pInp->flags & XI86_SERVER_FD) { - systemd_logind_release_fd(pInp->major, pInp->minor); - close(pInp->fd); - } - free((void *) pInp->driver); free((void *) pInp->name); xf86optionListFree(pInp->options); diff --git a/xorg-server/hw/xfree86/common/xf86platformBus.h b/xorg-server/hw/xfree86/common/xf86platformBus.h index 78b5a5bea..5dee4e0e0 100644 --- a/xorg-server/hw/xfree86/common/xf86platformBus.h +++ b/xorg-server/hw/xfree86/common/xf86platformBus.h @@ -54,11 +54,12 @@ xf86_add_platform_device(struct OdevAttributes *attribs, Bool unowned); extern int xf86_remove_platform_device(int dev_index); extern Bool +xf86_get_platform_device_unowned(int index); +/* Note starting with xserver 1.16 these 2 functions never fail */ +extern Bool xf86_add_platform_device_attrib(int index, int attrib_id, char *attrib_str); extern Bool xf86_add_platform_device_int_attrib(int index, int attrib_id, int attrib_value); -extern Bool -xf86_get_platform_device_unowned(int index); extern int xf86platformAddDevice(int index); diff --git a/xorg-server/hw/xfree86/man/Makefile.am b/xorg-server/hw/xfree86/man/Makefile.am index 80e22cbab..f41d26c4e 100644 --- a/xorg-server/hw/xfree86/man/Makefile.am +++ b/xorg-server/hw/xfree86/man/Makefile.am @@ -1,3 +1,8 @@ include $(top_srcdir)/manpages.am appman_PRE = Xorg.man fileman_PRE = xorg.conf.man xorg.conf.d.man + +if SUID_WRAPPER +appman_PRE += Xorg.wrap.man +fileman_PRE += Xwrapper.config.man +endif diff --git a/xorg-server/hw/xfree86/man/Xorg.wrap.man b/xorg-server/hw/xfree86/man/Xorg.wrap.man new file mode 100644 index 000000000..f2153e35b --- /dev/null +++ b/xorg-server/hw/xfree86/man/Xorg.wrap.man @@ -0,0 +1,67 @@ +.\" Xwrapper.wrap.1 +.\" +.\" Copyright 2014 Red Hat, Inc. +.\" +.\" Permission to use, copy, modify, distribute, and sell this software and its +.\" documentation for any purpose is hereby granted without fee, provided that +.\" the above copyright notice appear in all copies and that both that +.\" copyright notice and this permission notice appear in supporting +.\" documentation. +.\" +.\" The above copyright notice and this permission notice shall be included +.\" in all copies or substantial portions of the Software. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +.\" OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +.\" MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +.\" IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR +.\" OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +.\" ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +.\" OTHER DEALINGS IN THE SOFTWARE. +.\" +.\" Except as contained in this notice, the name of The Open Group shall +.\" not be used in advertising or otherwise to promote the sale, use or +.\" other dealings in this Software without prior written authorization +.\" from The Open Group. +.\" +.\" shorthand for double quote that works everywhere. +.ds q \N'34' +.TH Xorg.wrap 1 __xorgversion__ +.SH NAME +Xorg.wrap \- Xorg X server binary wrapper +.SH DESCRIPTION +The Xorg X server may need root rights to function properly. To start the +Xorg X server with these rights your system is using a suid root wrapper +installed as __suid_wrapper_dir__/Xorg.wrap which will execute the real +X server which is installed as __suid_wrapper_dir__/Xorg.bin . +.PP +By default Xorg.wrap will autodetect if root rights are necessary, and +if not it will drop its elevated rights before starting the real X server. +By default Xorg.wrap will only allow executing the real X server from login +sessions on a physical console. + +.SH CONFIG FILE +Xorg.wrap's default behavior can be overridden from the +\fI__sysconfdir__/X11/Xwrapper.config\fP config file. Lines starting with a +\fB#\fP in Xwrapper.config are considered comments and will be ignored. Any +other non empty lines must take the form of \fBkey\fP = \fIvalue\fP. +.TP 8 +\fBallowed_users\fP = \fIrootonly\fP|\fIconsole\fP|\fIanybody\fP +Specify which users may start the X server through the wrapper. Use +\fIrootonly\fP to only allow root, use \fIconsole\fP to only allow users +logged into a physical console, and use \fIanybody\fP to allow anybody. +The default is \fIconsole\fP. +.TP 8 +\fBneeds_root_rights\fP = \fIyes\fP|\fIno\fP|\fIauto\fP +Configure if the wrapper should drop its elevated (root) rights before starting +the X server. Use \fIyes\fP to force execution as root, \fIno\fP to force +execution with all suid rights dropped, and \fIauto\fP to letter the wrapper +auto-detect. The default is \fIauto\fP. +.PP +When auto-detecting the wrapper will drop rights if kms graphics are available +and not drop them if no kms graphics are detected. If a system has multiple +graphics cards and some are not kms capable auto-detection may fail, +in this case manual configuration should be used. + +.SH "SEE ALSO" +Xorg X server information: \fIXorg\fP(1) diff --git a/xorg-server/hw/xfree86/man/Xwrapper.config.man b/xorg-server/hw/xfree86/man/Xwrapper.config.man new file mode 100644 index 000000000..800947c55 --- /dev/null +++ b/xorg-server/hw/xfree86/man/Xwrapper.config.man @@ -0,0 +1 @@ +.so man1/Xorg.wrap.1 diff --git a/xorg-server/hw/xfree86/os-support/linux/lnx_platform.c b/xorg-server/hw/xfree86/os-support/linux/lnx_platform.c index 109a9a774..dbd7aa0aa 100644 --- a/xorg-server/hw/xfree86/os-support/linux/lnx_platform.c +++ b/xorg-server/hw/xfree86/os-support/linux/lnx_platform.c @@ -40,10 +40,7 @@ get_drm_info(struct OdevAttributes *attribs, char *path, int delayed_index) systemd_logind_release_fd(major, minor); return FALSE; } - if (!config_odev_add_int_attribute(attribs, ODEV_ATTRIB_FD, fd)) { - systemd_logind_release_fd(major, minor); - return FALSE; - } + config_odev_add_int_attribute(attribs, ODEV_ATTRIB_FD, fd); server_fd = TRUE; } diff --git a/xorg-server/hw/xfree86/os-support/linux/systemd-logind.c b/xorg-server/hw/xfree86/os-support/linux/systemd-logind.c index a8406d8be..62858b062 100644 --- a/xorg-server/hw/xfree86/os-support/linux/systemd-logind.c +++ b/xorg-server/hw/xfree86/os-support/linux/systemd-logind.c @@ -51,11 +51,43 @@ struct systemd_logind_info { static struct systemd_logind_info logind_info; +static InputInfoPtr +systemd_logind_find_info_ptr_by_devnum(InputInfoPtr start, + int major, int minor) +{ + InputInfoPtr pInfo; + + for (pInfo = start; pInfo; pInfo = pInfo->next) + if (pInfo->major == major && pInfo->minor == minor && + (pInfo->flags & XI86_SERVER_FD)) + return pInfo; + + return NULL; +} + +static void +systemd_logind_set_input_fd_for_all_devs(int major, int minor, int fd, + Bool enable) +{ + InputInfoPtr pInfo; + + pInfo = systemd_logind_find_info_ptr_by_devnum(xf86InputDevs, major, minor); + while (pInfo) { + pInfo->fd = fd; + pInfo->options = xf86ReplaceIntOption(pInfo->options, "fd", fd); + if (enable) + xf86EnableInputDeviceForVTSwitch(pInfo); + + pInfo = systemd_logind_find_info_ptr_by_devnum(pInfo->next, major, minor); + } +} + int systemd_logind_take_fd(int _major, int _minor, const char *path, Bool *paused_ret) { struct systemd_logind_info *info = &logind_info; + InputInfoPtr pInfo; DBusError error; DBusMessage *msg = NULL; DBusMessage *reply = NULL; @@ -71,6 +103,16 @@ systemd_logind_take_fd(int _major, int _minor, const char *path, if (strstr(path, "mouse")) return -1; + /* Check if we already have an InputInfo entry with this major, minor + * (shared device-nodes happen ie with Wacom tablets). */ + pInfo = systemd_logind_find_info_ptr_by_devnum(xf86InputDevs, major, minor); + if (pInfo) { + LogMessage(X_INFO, "systemd-logind: returning pre-existing fd for %s %u:%u\n", + path, major, minor); + *paused_ret = FALSE; + return pInfo->fd; + } + dbus_error_init(&error); msg = dbus_message_new_method_call("org.freedesktop.login1", info->session, @@ -123,15 +165,31 @@ void systemd_logind_release_fd(int _major, int _minor) { struct systemd_logind_info *info = &logind_info; + InputInfoPtr pInfo; DBusError error; DBusMessage *msg = NULL; DBusMessage *reply = NULL; dbus_int32_t major = _major; dbus_int32_t minor = _minor; + int matches = 0; if (!info->session || major == 0) return; + /* Only release the fd if there is only 1 InputInfo left for this major + * and minor, otherwise other InputInfo's are still referencing the fd. */ + pInfo = systemd_logind_find_info_ptr_by_devnum(xf86InputDevs, major, minor); + while (pInfo) { + matches++; + pInfo = systemd_logind_find_info_ptr_by_devnum(pInfo->next, major, minor); + } + if (matches > 1) { + LogMessage(X_INFO, "systemd-logind: not releasing fd for %u:%u, still in use\n", major, minor); + return; + } + + LogMessage(X_INFO, "systemd-logind: releasing fd for %u:%u\n", major, minor); + dbus_error_init(&error); msg = dbus_message_new_method_call("org.freedesktop.login1", info->session, @@ -203,19 +261,6 @@ systemd_logind_vtenter(void) xf86InputEnableVTProbe(); } -static InputInfoPtr -systemd_logind_find_info_ptr_by_devnum(int major, int minor) -{ - InputInfoPtr pInfo; - - for (pInfo = xf86InputDevs; pInfo; pInfo = pInfo->next) - if (pInfo->major == major && pInfo->minor == minor && - (pInfo->flags & XI86_SERVER_FD)) - return pInfo; - - return NULL; -} - static void systemd_logind_ack_pause(struct systemd_logind_info *info, dbus_int32_t minor, dbus_int32_t major) @@ -320,7 +365,8 @@ message_filter(DBusConnection * connection, DBusMessage * message, void *data) pdev = xf86_find_platform_device_by_devnum(major, minor); if (!pdev) - pInfo = systemd_logind_find_info_ptr_by_devnum(major, minor); + pInfo = systemd_logind_find_info_ptr_by_devnum(xf86InputDevs, + major, minor); if (!pdev && !pInfo) { LogMessage(X_WARNING, "systemd-logind: could not find dev %u:%u\n", major, minor); @@ -335,8 +381,7 @@ message_filter(DBusConnection * connection, DBusMessage * message, void *data) pdev->flags |= XF86_PDEV_PAUSED; else { close(pInfo->fd); - pInfo->fd = -1; - pInfo->options = xf86ReplaceIntOption(pInfo->options, "fd", -1); + systemd_logind_set_input_fd_for_all_devs(major, minor, -1, FALSE); } if (ack) systemd_logind_ack_pause(info, major, minor); @@ -345,15 +390,12 @@ message_filter(DBusConnection * connection, DBusMessage * message, void *data) /* info->vt_active gets set by systemd_logind_vtenter() */ info->active = TRUE; - if (pdev) { + if (pdev) pdev->flags &= ~XF86_PDEV_PAUSED; - } - else { - pInfo->fd = fd; - pInfo->options = xf86ReplaceIntOption(pInfo->options, "fd", fd); - if (info->vt_active) - xf86EnableInputDeviceForVTSwitch(pInfo); - } + else + systemd_logind_set_input_fd_for_all_devs(major, minor, fd, + info->vt_active); + /* Always call vtenter(), in case there are only legacy video devs */ systemd_logind_vtenter(); } diff --git a/xorg-server/hw/xfree86/xorg-wrapper.c b/xorg-server/hw/xfree86/xorg-wrapper.c new file mode 100644 index 000000000..90c8c11ef --- /dev/null +++ b/xorg-server/hw/xfree86/xorg-wrapper.c @@ -0,0 +1,231 @@ +/* + * Copyright © 2014 Red Hat, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Author: Hans de Goede <hdegoede@redhat.com> + */ + +#include "dix-config.h" + +#include <fcntl.h> +#include <limits.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/ioctl.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <unistd.h> +#include <drm/drm.h> +#include <xf86drm.h> /* For DRM_DEV_NAME */ + +#define CONFIG_FILE SYSCONFDIR "/X11/Xwrapper.config" + +enum { ROOT_ONLY, CONSOLE_ONLY, ANYBODY }; + +/* KISS non locale / LANG parsing isspace version */ +static int is_space(char c) +{ + return c == ' ' || c == '\t' || c == '\n'; +} + +static char *strip(char *s) +{ + int i; + + /* Strip leading whitespace */ + while (s[0] && is_space(s[0])) + s++; + + /* Strip trailing whitespace */ + i = strlen(s) - 1; + while (i >= 0 && is_space(s[i])) { + s[i] = 0; + i--; + } + + return s; +} + +static void parse_config(int *allowed, int *needs_root_rights) +{ + FILE *f; + char buf[1024]; + char *stripped, *equals, *key, *value; + int line = 0; + + f = fopen(CONFIG_FILE, "r"); + if (!f) + return; + + while (fgets(buf, sizeof(buf), f)) { + line++; + + /* Skip comments and empty lines */ + stripped = strip(buf); + if (stripped[0] == '#' || stripped[0] == 0) + continue; + + /* Split in a key + value pair */ + equals = strchr(stripped, '='); + if (!equals) { + fprintf(stderr, "Syntax error at %s line %d\n", CONFIG_FILE, line); + exit(1); + } + *equals = 0; + key = strip(stripped); /* To remove trailing whitespace from key */ + value = strip(equals + 1); /* To remove leading whitespace from val */ + if (!key[0]) { + fprintf(stderr, "Missing key at %s line %d\n", CONFIG_FILE, line); + exit(1); + } + if (!value[0]) { + fprintf(stderr, "Missing value at %s line %d\n", CONFIG_FILE, line); + exit(1); + } + + /* And finally process */ + if (strcmp(key, "allowed_users") == 0) { + if (strcmp(value, "rootonly") == 0) + *allowed = ROOT_ONLY; + else if (strcmp(value, "console") == 0) + *allowed = CONSOLE_ONLY; + else if (strcmp(value, "anybody") == 0) + *allowed = ANYBODY; + else { + fprintf(stderr, + "Invalid value '%s' for 'allowed_users' at %s line %d\n", + value, CONFIG_FILE, line); + exit(1); + } + } + else if (strcmp(key, "needs_root_rights") == 0) { + if (strcmp(value, "yes") == 0) + *needs_root_rights = 1; + else if (strcmp(value, "no") == 0) + *needs_root_rights = 0; + else if (strcmp(value, "auto") == 0) + *needs_root_rights = -1; + else { + fprintf(stderr, + "Invalid value '%s' for 'needs_root_rights' at %s line %d\n", + value, CONFIG_FILE, line); + exit(1); + } + } + else if (strcmp(key, "nice_value") == 0) { + /* Backward compatibility with older Debian Xwrapper, ignore */ + } + else { + fprintf(stderr, "Invalid key '%s' at %s line %d\n", key, + CONFIG_FILE, line); + exit(1); + } + } + fclose(f); +} + +int main(int argc, char *argv[]) +{ + struct drm_mode_card_res res; + struct stat st; + char buf[PATH_MAX]; + int i, r, fd; + int kms_cards = 0; + int total_cards = 0; + int allowed = CONSOLE_ONLY; + int needs_root_rights = -1; + + parse_config(&allowed, &needs_root_rights); + + /* For non root users check if they are allowed to run the X server */ + if (getuid() != 0) { + switch (allowed) { + case ROOT_ONLY: + /* Already checked above */ + fprintf(stderr, "%s: Only root is allowed to run the X server\n", argv[0]); + exit(1); + break; + case CONSOLE_ONLY: + /* Some of stdin / stdout / stderr maybe redirected to a file */ + for (i = STDIN_FILENO; i <= STDERR_FILENO; i++) { + r = fstat(i, &st); + if (r == 0 && S_ISCHR(st.st_mode) && major(st.st_rdev) == 4) + break; + } + if (i > STDERR_FILENO) { + fprintf(stderr, "%s: Only console users are allowed to run the X server\n", argv[0]); + exit(1); + } + break; + case ANYBODY: + break; + } + } + + /* Detect if we need root rights, except when overriden by the config */ + if (needs_root_rights == -1) { + for (i = 0; i < 16; i++) { + snprintf(buf, sizeof(buf), DRM_DEV_NAME, DRM_DIR_NAME, i); + fd = open(buf, O_RDWR); + if (fd == -1) + continue; + + total_cards++; + + memset(&res, 0, sizeof(struct drm_mode_card_res)); + r = ioctl(fd, DRM_IOCTL_MODE_GETRESOURCES, &res); + if (r == 0 && res.count_connectors > 0) + kms_cards++; + + close(fd); + } + } + + /* If we've found cards, and all cards support kms, drop root rights */ + if (needs_root_rights == 0 || (total_cards && kms_cards == total_cards)) { + gid_t realgid = getgid(); + uid_t realuid = getuid(); + + if (setresgid(-1, realgid, realgid) != 0) { + perror("Could not drop setgid privileges"); + exit(1); + } + if (setresuid(-1, realuid, realuid) != 0) { + perror("Could not drop setuid privileges"); + exit(1); + } + } + + snprintf(buf, sizeof(buf), "%s/Xorg.bin", SUID_WRAPPER_DIR); + + /* Check if the server is executable by our real uid */ + if (access(buf, X_OK) != 0) { + perror("Missing execute permissions for " SUID_WRAPPER_DIR "Xorg.bin"); + exit(1); + } + + argv[0] = buf; + (void) execv(argv[0], argv); + perror("Failed to execute " SUID_WRAPPER_DIR "/Xorg.bin"); + exit(1); +} diff --git a/xorg-server/hw/xwin/InitInput.c b/xorg-server/hw/xwin/InitInput.c index e7f402f80..40f4b9b9d 100644 --- a/xorg-server/hw/xwin/InitInput.c +++ b/xorg-server/hw/xwin/InitInput.c @@ -99,15 +99,11 @@ InitInput(int argc, char *argv[]) } #endif - rc = AllocDevicePair(serverClient, "Windows", - &g_pwinPointer, - &g_pwinKeyboard, - winMouseProc, - winKeybdProc, - FALSE); - - if (rc != Success) - FatalError("Failed to init vcxsrv default devices.\n"); + if (AllocDevicePair(serverClient, "Windows", + &g_pwinPointer, &g_pwinKeyboard, + winMouseProc, winKeybdProc, + FALSE) != Success) + FatalError("InitInput - Failed to allocate slave devices.\n"); mieqInit(); diff --git a/xorg-server/hw/xwin/InitOutput.c b/xorg-server/hw/xwin/InitOutput.c index 7a4f8446d..df670ff0e 100644 --- a/xorg-server/hw/xwin/InitOutput.c +++ b/xorg-server/hw/xwin/InitOutput.c @@ -262,12 +262,10 @@ ddxGiveUp(enum ExitCode error) PostQuitMessage(0); { - int iReturn; + int iReturn = pthread_mutex_unlock(&g_pmTerminating); winDebug("ddxGiveUp - Releasing termination mutex\n"); - iReturn = pthread_mutex_unlock(&g_pmTerminating); - if (iReturn != 0) { ErrorF("winMsgWindowProc - pthread_mutex_unlock () failed: %d\n", iReturn); @@ -420,8 +418,7 @@ winFixupPaths(void) { /* Open fontpath configuration file */ #if defined WIN32 && defined __MINGW32__ -qsdf qsdf qsdf qsdf - static Bool once = False; + static Bool once = False; char buffer[MAX_PATH]; snprintf(buffer, sizeof(buffer), "%s\\font-dirs", basedir); buffer[sizeof(buffer)-1] = 0; @@ -429,7 +426,6 @@ qsdf qsdf qsdf qsdf if (once) fontdirs = NULL; else once = True; #else -qsdfqsdf qsdf qsdf FILE *fontdirs = fopen(ETCX11DIR "/font-dirs", "rt"); #endif if (fontdirs != NULL) { @@ -809,6 +805,9 @@ winUseMsg(void) ErrorF("-fullscreen\n" "\tRun the server in fullscreen mode.\n"); + ErrorF("-hostintitle\n" + "\tIn multiwindow mode, add remote host names to window titles.\n"); + ErrorF("-ignoreinput\n" "\tIgnore keyboard and mouse input.\n"); #ifdef XWIN_MULTIWINDOWINTWM diff --git a/xorg-server/hw/xwin/man/XWin.man b/xorg-server/hw/xwin/man/XWin.man index 18ee667d4..c71f6a154 100644 --- a/xorg-server/hw/xwin/man/XWin.man +++ b/xorg-server/hw/xwin/man/XWin.man @@ -165,6 +165,12 @@ The maximum dimensions of the screen are the dimensions of the \fIWindows\fP vir on its own is equivalent to \fB\-resize=randr\fP .RE +.SH OPTIONS FOR MULTIWINDOW MODE +.TP 8 +.B \-hostintitle +Add the host name to the window title for X applications which are running +on remote hosts, when that information is available and it's useful to do so. + .SH OPTIONS CONTROLLING WINDOWS INTEGRATION .TP 8 .B \-[no]clipboard diff --git a/xorg-server/hw/xwin/winauth.c b/xorg-server/hw/xwin/winauth.c index 5c46c7022..4e6c3814f 100644 --- a/xorg-server/hw/xwin/winauth.c +++ b/xorg-server/hw/xwin/winauth.c @@ -114,9 +114,9 @@ MitGenerateCookie(unsigned data_length, static XID GenerateAuthorization(unsigned name_length, - char *name, + const char *name, unsigned data_length, - char *data, + const char *data, unsigned *data_length_return, char **data_return) { return MitGenerateCookie(data_length, data, diff --git a/xorg-server/hw/xwin/windialogs.c b/xorg-server/hw/xwin/windialogs.c index 3e3bd401c..bb48af0ab 100644 --- a/xorg-server/hw/xwin/windialogs.c +++ b/xorg-server/hw/xwin/windialogs.c @@ -568,10 +568,7 @@ winAboutDlgProc(HWND hwndDialog, UINT message, WPARAM wParam, LPARAM lParam) winInitDialog(hwndDialog); /* Override the URL buttons */ - winOverrideURLButton(hwndDialog, ID_ABOUT_CHANGELOG); winOverrideURLButton(hwndDialog, ID_ABOUT_WEBSITE); - winOverrideURLButton(hwndDialog, ID_ABOUT_UG); - winOverrideURLButton(hwndDialog, ID_ABOUT_FAQ); return TRUE; @@ -602,30 +599,10 @@ winAboutDlgProc(HWND hwndDialog, UINT message, WPARAM wParam, LPARAM lParam) PostMessage(s_pScreenPriv->hwndScreen, WM_NULL, 0, 0); /* Restore window procedures for URL buttons */ - winUnoverrideURLButton(hwndDialog, ID_ABOUT_CHANGELOG); winUnoverrideURLButton(hwndDialog, ID_ABOUT_WEBSITE); - winUnoverrideURLButton(hwndDialog, ID_ABOUT_UG); - winUnoverrideURLButton(hwndDialog, ID_ABOUT_FAQ); return TRUE; - case ID_ABOUT_CHANGELOG: - { - INT_PTR iReturn; - - const char *pszWinPath = "http://x.cygwin.com/" - "devel/server/changelog.html"; - - iReturn = (INT_PTR) ShellExecute(NULL, - "open", - pszWinPath, NULL, NULL, SW_MAXIMIZE); - if (iReturn < 32) { - ErrorF("winAboutDlgProc - WM_COMMAND - ID_ABOUT_CHANGELOG - " - "ShellExecute failed: %d\n", (int)iReturn); - } - } - return TRUE; - case ID_ABOUT_WEBSITE: { const char *pszPath = __VENDORDWEBSUPPORT__; @@ -641,36 +618,6 @@ winAboutDlgProc(HWND hwndDialog, UINT message, WPARAM wParam, LPARAM lParam) } } return TRUE; - - case ID_ABOUT_UG: - { - const char *pszPath = "http://x.cygwin.com/docs/ug/"; - INT_PTR iReturn; - - iReturn = (INT_PTR) ShellExecute(NULL, - "open", - pszPath, NULL, NULL, SW_MAXIMIZE); - if (iReturn < 32) { - ErrorF("winAboutDlgProc - WM_COMMAND - ID_ABOUT_UG - " - "ShellExecute failed: %d\n", (int)iReturn); - } - } - return TRUE; - - case ID_ABOUT_FAQ: - { - const char *pszPath = "http://x.cygwin.com/docs/faq/"; - INT_PTR iReturn; - - iReturn = (INT_PTR) ShellExecute(NULL, - "open", - pszPath, NULL, NULL, SW_MAXIMIZE); - if (iReturn < 32) { - ErrorF("winAboutDlgProc - WM_COMMAND - ID_ABOUT_FAQ - " - "ShellExecute failed: %d\n", (int)iReturn); - } - } - return TRUE; } break; @@ -684,10 +631,7 @@ winAboutDlgProc(HWND hwndDialog, UINT message, WPARAM wParam, LPARAM lParam) PostMessage(s_pScreenPriv->hwndScreen, WM_NULL, 0, 0); /* Restore window procedures for URL buttons */ - winUnoverrideURLButton(hwndDialog, ID_ABOUT_CHANGELOG); winUnoverrideURLButton(hwndDialog, ID_ABOUT_WEBSITE); - winUnoverrideURLButton(hwndDialog, ID_ABOUT_UG); - winUnoverrideURLButton(hwndDialog, ID_ABOUT_FAQ); return TRUE; } diff --git a/xorg-server/hw/xwin/winglobals.c b/xorg-server/hw/xwin/winglobals.c index 59287cadb..54e5e0ba2 100644 --- a/xorg-server/hw/xwin/winglobals.c +++ b/xorg-server/hw/xwin/winglobals.c @@ -79,6 +79,7 @@ Bool g_fSoftwareCursor = FALSE; Bool g_fSilentDupError = FALSE; Bool g_fNativeGl = TRUE; Bool g_fswrastwgl = FALSE; +Bool g_fHostInTitle = FALSE; pthread_mutex_t g_pmTerminating = PTHREAD_MUTEX_INITIALIZER; #ifdef XWIN_CLIPBOARD diff --git a/xorg-server/hw/xwin/winglobals.h b/xorg-server/hw/xwin/winglobals.h index 75707b460..722569bf9 100644 --- a/xorg-server/hw/xwin/winglobals.h +++ b/xorg-server/hw/xwin/winglobals.h @@ -54,7 +54,8 @@ extern Bool g_fXdmcpEnabled; extern Bool g_fNoHelpMessageBox; extern Bool g_fSilentDupError; extern Bool g_fNativeGl; -extern Bool g_fswrastwgl; +extern Bool g_fswrastwgl; +extern Bool g_fHostInTitle; extern HWND g_hDlgDepthChange; extern HWND g_hDlgExit; diff --git a/xorg-server/hw/xwin/winmultiwindowicons.c b/xorg-server/hw/xwin/winmultiwindowicons.c index 74d0af1ba..5ffc24278 100644 --- a/xorg-server/hw/xwin/winmultiwindowicons.c +++ b/xorg-server/hw/xwin/winmultiwindowicons.c @@ -374,13 +374,12 @@ winXIconToHICON(Display * pDisplay, Window id, int iconSize) unsigned char *mask, *image = NULL, *imageMask; unsigned char *dst, *src; int planes, bpp, i; - int biggest_size = 0; + unsigned int biggest_size = 0; HDC hDC; ICONINFO ii; XWMHints *hints; HICON hIcon = NULL; uint32_t *biggest_icon = NULL; - static Atom _XA_NET_WM_ICON; static int generation; uint32_t *icon, *icon_data = NULL; @@ -407,10 +406,25 @@ winXIconToHICON(Display * pDisplay, Window id, int iconSize) (icon_data != NULL)) { for (icon = icon_data; icon < &icon_data[size] && *icon; icon = &icon[icon[0] * icon[1] + 2]) { - /* Find an exact match to the size we require... */ + winDebug("winXIconToHICON: %u x %u NetIcon\n", icon[0], icon[1]); + + /* Icon data size will overflow an int and thus is bigger than the + property can possibly be */ + if ((INT_MAX/icon[0]) < icon[1]) { + winDebug("winXIconToHICON: _NET_WM_ICON icon data size overflow\n"); + break; + } + + /* Icon data size is bigger than amount of data remaining */ + if (&icon[icon[0] * icon[1] + 2] > &icon_data[size]) { + winDebug("winXIconToHICON: _NET_WM_ICON data is malformed\n"); + break; + } + + /* Found an exact match to the size we require... */ if (icon[0] == iconSize && icon[1] == iconSize) { - winDebug("winXIconToHICON: found %lu x %lu NetIcon\n", icon[0], - icon[1]); + winDebug("winXIconToHICON: selected %d x %d NetIcon\n", + iconSize, iconSize); hIcon = NetWMToWinIcon(bpp, icon); break; } @@ -423,7 +437,7 @@ winXIconToHICON(Display * pDisplay, Window id, int iconSize) if (!hIcon && biggest_icon) { winDebug - ("winXIconToHICON: selected %lu x %lu NetIcon for scaling to %u x %u\n", + ("winXIconToHICON: selected %u x %u NetIcon for scaling to %d x %d\n", biggest_icon[0], biggest_icon[1], iconSize, iconSize); hIcon = NetWMToWinIcon(bpp, biggest_icon); diff --git a/xorg-server/hw/xwin/winmultiwindowwm.c b/xorg-server/hw/xwin/winmultiwindowwm.c index 8518147a6..0fd63312e 100644 --- a/xorg-server/hw/xwin/winmultiwindowwm.c +++ b/xorg-server/hw/xwin/winmultiwindowwm.c @@ -64,6 +64,7 @@ typedef int pid_t; #include "winmsg.h" #include "windowstr.h" #include "winmultiwindowclass.h" +#include "winglobals.h" #ifdef XWIN_MULTIWINDOWEXTWM #define _WINDOWSWM_SERVER_ @@ -74,6 +75,10 @@ typedef int pid_t; #define WINDOWSWM_NATIVE_HWND "_WINDOWSWM_NATIVE_HWND" #endif +#ifndef HOST_NAME_MAX +#define HOST_NAME_MAX 255 +#endif + extern void winDebug(const char *format, ...); extern void winReshapeMultiWindow(WindowPtr pWin); extern void winUpdateRgnMultiWindow(WindowPtr pWin); @@ -397,7 +402,10 @@ GetWindowName(Display * pDisplay, Window iWin, char **ppWindowName) { int nResult; XTextProperty xtpWindowName; + XTextProperty xtpClientMachine; char *pszWindowName; + char *pszClientMachine; + char hostname[HOST_NAME_MAX + 1]; winDebug ("GetWindowName\n"); @@ -413,6 +421,41 @@ GetWindowName(Display * pDisplay, Window iWin, char **ppWindowName) pszWindowName = Xutf8TextPropertyToString(pDisplay, &xtpWindowName); XFree(xtpWindowName.value); + + if (g_fHostInTitle) { + /* Try to get client machine name */ + nResult = XGetWMClientMachine(pDisplay, iWin, &xtpClientMachine); + if (nResult && xtpClientMachine.value && xtpClientMachine.nitems) { + pszClientMachine = + Xutf8TextPropertyToString(pDisplay, &xtpClientMachine); + XFree(xtpClientMachine.value); + + /* + If we have a client machine name + and it's not the local host name + and it's not already in the window title... + */ + if (strlen(pszClientMachine) && + !gethostname(hostname, HOST_NAME_MAX + 1) && + strcmp(hostname, pszClientMachine) && + (strstr(pszWindowName, pszClientMachine) == 0)) { + /* ... add '@<clientmachine>' to end of window name */ + *ppWindowName = + malloc(strlen(pszWindowName) + + strlen(pszClientMachine) + 2); + strcpy(*ppWindowName, pszWindowName); + strcat(*ppWindowName, "@"); + strcat(*ppWindowName, pszClientMachine); + + free(pszWindowName); + free(pszClientMachine); + + return; + } + } + } + + /* otherwise just return the window name */ *ppWindowName = pszWindowName; } @@ -1576,10 +1619,10 @@ winDeinitMultiWindowWM(void) } /* Windows window styles */ -#define HINT_NOFRAME (1l<<0) +#define HINT_NOFRAME (1L<<0) #define HINT_BORDER (1L<<1) -#define HINT_SIZEBOX (1l<<2) -#define HINT_CAPTION (1l<<3) +#define HINT_SIZEBOX (1L<<2) +#define HINT_CAPTION (1L<<3) #define HINT_NOMAXIMIZE (1L<<4) #define HINT_NOMINIMIZE (1L<<5) #define HINT_NOSYSMENU (1L<<6) diff --git a/xorg-server/hw/xwin/winmultiwindowwndproc.c b/xorg-server/hw/xwin/winmultiwindowwndproc.c index 9ca27e5ff..624c96fca 100644 --- a/xorg-server/hw/xwin/winmultiwindowwndproc.c +++ b/xorg-server/hw/xwin/winmultiwindowwndproc.c @@ -830,7 +830,7 @@ winTopLevelWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) break; case WM_CLOSE: - /* Removep AppUserModelID property */ + /* Remove AppUserModelID property */ winSetAppUserModelID(hwnd, NULL); /* Branch on if the window was killed in X already */ if (pWinPriv->fXKilled) { @@ -865,8 +865,9 @@ winTopLevelWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) case WM_MOVE: /* Adjust the X Window to the moved Windows window */ - if (!hasEnteredSizeMove) winAdjustXWindow (pWin, hwnd); - /* else: Wait for WM_EXITSIZEMOVE */ + if (!hasEnteredSizeMove) + winAdjustXWindow(pWin, hwnd); + /* else: Wait for WM_EXITSIZEMOVE */ return 0; case WM_SHOWWINDOW: @@ -1017,14 +1018,14 @@ winTopLevelWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) break; case WM_ENTERSIZEMOVE: - hasEnteredSizeMove = TRUE; - return 0; + hasEnteredSizeMove = TRUE; + return 0; case WM_EXITSIZEMOVE: - /* Adjust the X Window to the moved Windows window */ - hasEnteredSizeMove = FALSE; - winAdjustXWindow (pWin, hwnd); - return 0; + /* Adjust the X Window to the moved Windows window */ + hasEnteredSizeMove = FALSE; + winAdjustXWindow(pWin, hwnd); + return 0; case WM_SIZE: /* see dix/window.c */ diff --git a/xorg-server/hw/xwin/winprocarg.c b/xorg-server/hw/xwin/winprocarg.c index 570b91721..ad0b5bbe9 100644 --- a/xorg-server/hw/xwin/winprocarg.c +++ b/xorg-server/hw/xwin/winprocarg.c @@ -1119,6 +1119,11 @@ ddxProcessArgument(int argc, char *argv[], int i) return 2; } + if (IS_OPTION("-hostintitle")) { + g_fHostInTitle = TRUE; + return 1; + } + return 0; } diff --git a/xorg-server/hw/xwin/winresource.h b/xorg-server/hw/xwin/winresource.h index bb419188a..39b890c7c 100644 --- a/xorg-server/hw/xwin/winresource.h +++ b/xorg-server/hw/xwin/winresource.h @@ -44,9 +44,6 @@ #define ID_APP_ALWAYS_ON_TOP 202 #define ID_APP_ABOUT 203 -#define ID_ABOUT_UG 300 -#define ID_ABOUT_FAQ 301 -#define ID_ABOUT_CHANGELOG 302 #define ID_ABOUT_WEBSITE 303 #define IDC_HOSTLIST 100 diff --git a/xorg-server/hw/xwin/winwin32rootless.c b/xorg-server/hw/xwin/winwin32rootless.c index 024458063..aeec0eee2 100644 --- a/xorg-server/hw/xwin/winwin32rootless.c +++ b/xorg-server/hw/xwin/winwin32rootless.c @@ -39,7 +39,6 @@ #include <winuser.h> #define _WINDOWSWM_SERVER_ #include <X11/extensions/windowswmstr.h> -#include "dixevents.h" #include "winmultiwindowclass.h" #include <X11/Xatom.h> diff --git a/xorg-server/include/dix-config.h.in b/xorg-server/include/dix-config.h.in index 06455a837..f980a3d37 100644 --- a/xorg-server/include/dix-config.h.in +++ b/xorg-server/include/dix-config.h.in @@ -288,9 +288,15 @@ /* Support SHAPE extension */ #undef SHAPE +/* Where to install Xorg.bin and Xorg.wrap */ +#undef SUID_WRAPPER_DIR + /* Define to 1 on systems derived from System V Release 4 */ #undef SVR4 +/* sysconfdir */ +#undef SYSCONFDIR + /* Support TCP socket connections */ #undef TCPCONN diff --git a/xorg-server/include/hotplug.h b/xorg-server/include/hotplug.h index 1d9364eee..cefc164ae 100644 --- a/xorg-server/include/hotplug.h +++ b/xorg-server/include/hotplug.h @@ -48,12 +48,14 @@ struct OdevAttributes { struct xorg_list list; }; +/* Note starting with xserver 1.16 this function never fails */ struct OdevAttributes * config_odev_allocate_attribute_list(void); void config_odev_free_attribute_list(struct OdevAttributes *attribs); +/* Note starting with xserver 1.16 this function never fails */ Bool config_odev_add_attribute(struct OdevAttributes *attribs, int attrib, const char *attrib_name); @@ -61,6 +63,7 @@ config_odev_add_attribute(struct OdevAttributes *attribs, int attrib, char * config_odev_get_attribute(struct OdevAttributes *attribs, int attrib_id); +/* Note starting with xserver 1.16 this function never fails */ Bool config_odev_add_int_attribute(struct OdevAttributes *attribs, int attrib, int attrib_value); diff --git a/xorg-server/include/xorg-config.h.in b/xorg-server/include/xorg-config.h.in index 487d7addb..77a1aae55 100644 --- a/xorg-server/include/xorg-config.h.in +++ b/xorg-server/include/xorg-config.h.in @@ -118,6 +118,9 @@ /* Have execinfo.h */ #undef HAVE_EXECINFO_H +/* Define to 1 if you have the <sys/mkdev.h> header file. */ +#undef HAVE_SYS_MKDEV_H + /* Path to text files containing PCI IDs */ #undef PCI_TXT_IDS_PATH diff --git a/xorg-server/include/xwin-config.h.in b/xorg-server/include/xwin-config.h.in index c5119f268..176c01980 100644 --- a/xorg-server/include/xwin-config.h.in +++ b/xorg-server/include/xwin-config.h.in @@ -26,9 +26,6 @@ /* Vendor web address for support */ #undef __VENDORDWEBSUPPORT__ -/* Location of system.XWinrc */ -#undef SYSCONFDIR - /* Default log location */ #undef DEFAULT_LOGDIR diff --git a/xorg-server/manpages.am b/xorg-server/manpages.am index dfd671915..648210b4e 100644 --- a/xorg-server/manpages.am +++ b/xorg-server/manpages.am @@ -31,6 +31,7 @@ MAN_SUBSTS += -e 's|__logdir__|$(logdir)|g' \ -e 's|__XKB_DFLT_OPTIONS__|$(XKB_DFLT_OPTIONS)|g' \ -e 's|__bundle_id_prefix__|$(BUNDLE_ID_PREFIX)|g' \ -e 's|__modulepath__|$(DEFAULT_MODULE_PATH)|g' \ + -e 's|__suid_wrapper_dir__|$(SUID_WRAPPER_DIR)|g' \ -e 's|__default_font_path__|$(COMPILEDDEFAULTFONTPATH)|g' \ -e '\|$(COMPILEDDEFAULTFONTPATH)| s|/,|/, |g' |