[PATCH 1/2] vmmouse: Run vmmouse_detect as an io privileged process

Thomas Hellstrom thellstrom at vmware.com
Tue Apr 7 02:05:12 PDT 2015


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 <thellstrom at vmware.com>
Acked-by: Sinclair Yeh <syeh at vmware.com>
---
 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 at _detect
 
 AM_CPPFLAGS = -I$(top_srcdir)/shared $(XORG_CFLAGS)
 
- at DRIVER_NAME@_detect_SOURCES = vmmouse_detect.c vmmouse_udev.c
+ at DRIVER_NAME@_detect_SOURCES = vmmouse_detect.c vmmouse_udev.c vmmouse_iopl.c
 @DRIVER_NAME at _detect_LDADD = $(top_builddir)/shared/lib at DRIVER_NAME@.la \
 				@LIBUDEV_LIBS@
 @DRIVER_NAME at _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 <dawes at XFree86.org>
+ * Copyright 1992 by Jim Tsillas <jtsilla at damon.ccs.northeastern.edu>
+ * Copyright 1992 by Rich Murphey <Rich at Rice.edu>
+ * Copyright 1992 by Robert Baron <Robert.Baron at ernst.mach.cs.cmu.edu>
+ * Copyright 1992 by Orest Zborowski <obz at eskimo.com>
+ * Copyright 1993 by Vrije Universiteit, The Netherlands
+ * Copyright 1993 by David Wexelblat <dwex at XFree86.org>
+ * Copyright 1994, 1996 by Holger Veit <Holger.Veit at gmd.de>
+ * Copyright 1997 by Takis Psarogiannakopoulos <takis at dpmms.cam.ac.uk>
+ * Copyright 1994-2003 by The XFree86 Project, Inc
+ * Copyright 1999 by David Holland <davidh at iquest.net>
+ * 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 <xorg-config.h>
+#endif
+
+#include <stdbool.h>
+
+#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 <sys/types.h>
+#include <errno.h>
+#if !(defined (sun) && defined (SVR4))
+#include <sys/immu.h>
+#include <sys/region.h>
+#include <sys/proc.h>
+#endif
+#include <sys/tss.h>
+#include <sys/sysi86.h>
+#if defined(SVR4) && !defined(sun)
+#include <sys/seg.h>
+#endif                          /* SVR4 && !sun */
+/* V86SC_IOPL was moved to <sys/sysi86.h> on Solaris 7 and later */
+#if !defined(V86SC_IOPL)        /* Solaris 7 or later? */
+#include <sys/v86.h>            /* Nope */
+#endif
+#if defined(sun) && (defined (__i386__) || defined(__i386) || defined(__x86))  && defined (SVR4)
+#include <sys/psw.h>
+#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
-- 
2.1.0



More information about the xorg-devel mailing list