From d5c1493b5fe0871f4f2823125f0d49f8e1edcda7 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Thu, 15 Jan 2015 10:14:30 +0100 Subject: vmmouse: Run vmmouse_detect as an io privileged process Many distros already include patches to do this in various more or less hackish ways. Since VMware now is about to restrict access to the VMmouse backdoor, let's try to support it officially. Signed-off-by: Thomas Hellstrom Acked-by: Sinclair Yeh --- configure.ac | 41 +++++++-- tools/Makefile.am | 2 +- tools/vmmouse_detect.c | 1 + tools/vmmouse_iopl.c | 236 +++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 273 insertions(+), 7 deletions(-) create mode 100644 tools/vmmouse_iopl.c diff --git a/configure.ac b/configure.ac index 1197555..212f083 100644 --- a/configure.ac +++ b/configure.ac @@ -32,6 +32,11 @@ AC_CONFIG_HEADERS([config.h]) AM_INIT_AUTOMAKE([foreign dist-bzip2]) +# XORG_DEFAULT_OPTIONS below forces C99. Solaris GCC doesn't like that. +AC_PROG_CC +AC_PROG_CC_C89 +save_solaris_cc=$CC + # Require X.Org macros 1.8 or later for MAN_SUBSTS set by XORG_MANPAGE_SECTIONS m4_ifndef([XORG_MACROS_VERSION], [m4_fatal([must install xorg-macros 1.8 or later before running autoconf/autogen])]) @@ -112,12 +117,36 @@ AC_ARG_WITH([libudev], [if test x$withval = xno; then libudev_check=no; fi] []) -if test x`uname` = xLinux -a $libudev_check = yes; then - PKG_CHECK_MODULES(LIBUDEV, [libudev], - [AC_DEFINE([HAVE_LIBUDEV], 1, - [Has libudev installed])], - []); -fi +case $host_os in + linux*) + if test $libudev_check != no; then + PKG_CHECK_MODULES(LIBUDEV, [libudev], + [AC_DEFINE([HAVE_LIBUDEV], 1, + [Has libudev installed])], + []); + fi + AC_CHECK_FUNCS(ioperm iopl,[], + [AC_MSG_ERROR + ([cannot determine how to elevate io permissions)]],[1]) + AC_DEFINE(VMMOUSE_OS_GENERIC, 1, + [Building for iopl / ioperm capable OS]) + ;; + *bsd*) + AC_DEFINE(VMMOUSE_OS_BSD, 1, [Building for BSD flavour]) + ;; + solaris*) + if test "x$GCC" == "xyes"; then + CC="$save_solaris_cc -fms-extensions" + fi + AC_DEFINE(VMMOUSE_OS_SOLARIS, 1, [Building for Solaris flavour]) + ;; + *) + AC_CHECK_FUNCS(ioperm iopl,[], + [AC_MSG_ERROR + ([cannot determine how to elevate io permissions)]],[1]) + AC_DEFINE(VMMOUSE_OS_GENERIC, 1) + ;; +esac PKG_CHECK_MODULES(XORG, [xorg-server >= 1.0.1] xproto $REQUIRED_MODULES) diff --git a/tools/Makefile.am b/tools/Makefile.am index a1396ba..da0e782 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -22,7 +22,7 @@ bin_PROGRAMS = @DRIVER_NAME@_detect AM_CPPFLAGS = -I$(top_srcdir)/shared $(XORG_CFLAGS) -@DRIVER_NAME@_detect_SOURCES = vmmouse_detect.c vmmouse_udev.c +@DRIVER_NAME@_detect_SOURCES = vmmouse_detect.c vmmouse_udev.c vmmouse_iopl.c @DRIVER_NAME@_detect_LDADD = $(top_builddir)/shared/lib@DRIVER_NAME@.la \ @LIBUDEV_LIBS@ @DRIVER_NAME@_detect_CFLAGS = @LIBUDEV_CFLAGS@ diff --git a/tools/vmmouse_detect.c b/tools/vmmouse_detect.c index b743b2d..1d28122 100644 --- a/tools/vmmouse_detect.c +++ b/tools/vmmouse_detect.c @@ -58,6 +58,7 @@ main(void) signal(SIGSEGV, segvCB); #if defined __i386__ || defined __x86_64__ + (void) xf86EnableIO(); if (VMMouseClient_Enable()) { VMMouseClient_Disable(); return 0; diff --git a/tools/vmmouse_iopl.c b/tools/vmmouse_iopl.c new file mode 100644 index 0000000..3b3fc0b --- /dev/null +++ b/tools/vmmouse_iopl.c @@ -0,0 +1,236 @@ +/* + * Copyright 1990, 1991 by Thomas Roell, Dinkelscherben, Germany + * Copyright 1992 by David Dawes + * Copyright 1992 by Jim Tsillas + * Copyright 1992 by Rich Murphey + * Copyright 1992 by Robert Baron + * Copyright 1992 by Orest Zborowski + * Copyright 1993 by Vrije Universiteit, The Netherlands + * Copyright 1993 by David Wexelblat + * Copyright 1994, 1996 by Holger Veit + * Copyright 1997 by Takis Psarogiannakopoulos + * Copyright 1994-2003 by The XFree86 Project, Inc + * Copyright 1999 by David Holland + * Copyright 2015 by VMware 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, and that the names of the above listed copyright holders + * not be used in advertising or publicity pertaining to distribution of + * the software without specific, written prior permission. The above listed + * copyright holders make no representations about the suitability of this + * software for any purpose. It is provided "as is" without express or + * implied warranty. + * + * THE ABOVE LISTED COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD + * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDERS BE + * LIABLE FOR ANY SPECIAL, 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. + * + */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +#ifdef HAVE_XORG_CONFIG_H +#include +#endif + +#include + +#if defined(VMMOUSE_OS_BSD) +#define HAVE_WRAPPER_DECLS +#include "xf86_OSlib.h" +#include "xf86OSpriv.h" +#ifdef USE_I386_IOPL +/***************************************************************************/ +/* I/O Permissions section */ +/***************************************************************************/ +static bool ExtendedEnabled = false; + +bool +xf86EnableIO() +{ + if (ExtendedEnabled) + return true; + + if (i386_iopl(1) < 0) + return false; + + ExtendedEnabled = true; + return true; +} + +void +xf86DisableIO() +{ + if (!ExtendedEnabled) + return; + + i386_iopl(0); + + ExtendedEnabled = false; + return; +} + +#endif /* USE_I386_IOPL */ + +#ifdef USE_AMD64_IOPL +/***************************************************************************/ +/* I/O Permissions section */ +/***************************************************************************/ + +static bool ExtendedEnabled = false; + +bool +xf86EnableIO() +{ + if (ExtendedEnabled) + return true; + + if (amd64_iopl(1) < 0) + return false; + + ExtendedEnabled = true; + return true; +} + +void +xf86DisableIO() +{ + if (!ExtendedEnabled) + return; + + if (amd64_iopl(0) == 0) + ExtendedEnabled = false; + + return; +} + +#endif /* USE_AMD64_IOPL */ + +#ifdef USE_DEV_IO +static int IoFd = -1; + +bool +xf86EnableIO() +{ + if (IoFd >= 0) + return true; + + if ((IoFd = open("/dev/io", O_RDWR)) == -1) + return false; + + return true; +} + +void +xf86DisableIO() +{ + if (IoFd < 0) + return; + + close(IoFd); + IoFd = -1; + return; +} +#endif + +#elif defined(VMMOUSE_OS_GENERIC) + +static bool ExtendedEnabled = false; + +extern int ioperm(unsigned long __from, unsigned long __num, int __turn_on); +extern int iopl(int __level); + +bool xf86EnableIO(void) +{ + if (ExtendedEnabled) + return true; + + if (ioperm(0, 1024, 1) || iopl(3)) + return false; + + ExtendedEnabled = true; + return true; +} + +void +xf86DisableIO(void) +{ + if (!ExtendedEnabled) + return; + + iopl(0); + ioperm(0, 1024, 0); + ExtendedEnabled = false; + + return; +} + +#elif defined(VMMOUSE_OS_SOLARIS) + +#ifdef __GNUC__ +#if defined(__sun) && !defined(sun) +#define sun 1 +#endif +#if defined(__SVR4) && !defined(SVR4) +#define SVR4 1 +#endif +#endif +/* + * The below sequence of includes is stolen from Xserver. If it doesn't work + * for your setup, please propose a patch to fix it. + */ +#include +#include +#if !(defined (sun) && defined (SVR4)) +#include +#include +#include +#endif +#include +#include +#if defined(SVR4) && !defined(sun) +#include +#endif /* SVR4 && !sun */ +/* V86SC_IOPL was moved to on Solaris 7 and later */ +#if !defined(V86SC_IOPL) /* Solaris 7 or later? */ +#include /* Nope */ +#endif +#if defined(sun) && (defined (__i386__) || defined(__i386) || defined(__x86)) && defined (SVR4) +#include +#endif + +static bool ExtendedEnabled = false; + +bool +xf86EnableIO(void) +{ + if (ExtendedEnabled) + return true; + + if (sysi86(SI86V86, V86SC_IOPL, PS_IOPL) < 0) + return false; + + ExtendedEnabled = true; + + return true; +} + +void +xf86DisableIO(void) +{ + if(!ExtendedEnabled) + return; + + sysi86(SI86V86, V86SC_IOPL, 0); + + ExtendedEnabled = false; +} + +#endif -- cgit v1.2.3