]> git.ipfire.org Git - thirdparty/open-vm-tools.git/commitdiff
Catch exception from backdoor access.
authorVMware, Inc <>
Wed, 20 Jan 2010 21:31:56 +0000 (13:31 -0800)
committerMarcelo Vanzin <mvanzin@vmware.com>
Wed, 20 Jan 2010 21:31:56 +0000 (13:31 -0800)
Signed-off-by: Marcelo Vanzin <mvanzin@vmware.com>
open-vm-tools/lib/include/sigPosixRegs.h [new file with mode: 0644]
open-vm-tools/rpctool/rpctool.c

diff --git a/open-vm-tools/lib/include/sigPosixRegs.h b/open-vm-tools/lib/include/sigPosixRegs.h
new file mode 100644 (file)
index 0000000..6bcb3e8
--- /dev/null
@@ -0,0 +1,264 @@
+/*********************************************************
+ * Copyright (C) 2009 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation version 2.1 and no later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the Lesser GNU General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA.
+ *
+ *********************************************************/
+
+/*
+ * sigPosixRegs.h --
+ *
+ *      Platform-specific definitions for saved CPU registers inside
+ *      ucontext_t. These aren't part of sigPosix.h since few source
+ *      files need them, and this header is a bit invasive, and it must
+ *      be defined before system headers.
+ */
+
+#ifndef _SIGPOSIXREGS_H_
+#define _SIGPOSIXREGS_H_
+
+#define INCLUDE_ALLOW_USERLEVEL
+#define INCLUDE_ALLOW_VMCORE
+#include "includeCheck.h"
+
+
+#if __linux__         // We need the REG_foo offsets in the gregset_t;
+#  define _GNU_SOURCE // _GNU_SOURCE maps to __USE_GNU
+
+/* And, the REG_foo definitions conflict with our own in x86.h */
+#  if defined(__x86_64__)
+#    define REG_RAX GNU_REG_RAX
+#    define REG_RBX GNU_REG_RBX
+#    define REG_RCX GNU_REG_RCX
+#    define REG_RDX GNU_REG_RDX
+#    define REG_RSI GNU_REG_RSI
+#    define REG_RDI GNU_REG_RDI
+#    define REG_RSP GNU_REG_RSP
+#    define REG_RBP GNU_REG_RBP
+#    define REG_RIP GNU_REG_RIP
+#    define REG_R8  GNU_REG_R8
+#    define REG_R9  GNU_REG_R9
+#    define REG_R10 GNU_REG_R10
+#    define REG_R11 GNU_REG_R11
+#    define REG_R12 GNU_REG_R12
+#    define REG_R13 GNU_REG_R13
+#    define REG_R14 GNU_REG_R14
+#    define REG_R15 GNU_REG_R15
+#  elif defined(__i386__)
+#    if GLIBC_VERSION_22
+#       define REG_EAX GNU_REG_EAX
+#       define REG_EBX GNU_REG_EBX
+#       define REG_ECX GNU_REG_ECX
+#       define REG_EDX GNU_REG_EDX
+#       define REG_ESI GNU_REG_ESI
+#       define REG_EDI GNU_REG_EDI
+#       define REG_ESP GNU_REG_ESP
+#       define REG_EBP GNU_REG_EBP
+#       define REG_EIP GNU_REG_EIP
+#    else
+#       define EAX GNU_REG_EAX
+#       define EBX GNU_REG_EBX
+#       define ECX GNU_REG_ECX
+#       define EDX GNU_REG_EDX
+#       define ESI GNU_REG_ESI
+#       define EDI GNU_REG_EDI
+#       define ESP GNU_REG_ESP
+#       define EBP GNU_REG_EBP
+#       define EIP GNU_REG_EIP
+#    endif
+#  endif
+#endif
+
+#include <signal.h>
+#include <sys/ucontext.h>
+
+#if __linux__
+#  if defined(__x86_64__)
+#    undef REG_RAX
+#    undef REG_RBX
+#    undef REG_RCX
+#    undef REG_RDX
+#    undef REG_RSI
+#    undef REG_RDI
+#    undef REG_RSP
+#    undef REG_RBP
+#    undef REG_RIP
+#    undef REG_R8
+#    undef REG_R9
+#    undef REG_R10
+#    undef REG_R11
+#    undef REG_R12
+#    undef REG_R13
+#    undef REG_R14
+#    undef REG_R15
+#  elif defined(__i386__)
+#    if GLIBC_VERSION_22
+#       undef REG_EAX
+#       undef REG_EBX
+#       undef REG_ECX
+#       undef REG_EDX
+#       undef REG_ESI
+#       undef REG_EDI
+#       undef REG_ESP
+#       undef REG_EBP
+#       undef REG_EIP
+#    else
+#       undef EAX
+#       undef EBX
+#       undef ECX
+#       undef EDX
+#       undef ESI
+#       undef EDI
+#       undef ESP
+#       undef EBP
+#       undef EIP
+#    endif
+#  endif
+#endif
+
+#if defined(__APPLE__)
+#if __DARWIN_UNIX03
+#ifdef __x86_64__
+#define SC_EAX(uc) ((unsigned long) (uc)->uc_mcontext->__ss.__rax)
+#define SC_EBX(uc) ((unsigned long) (uc)->uc_mcontext->__ss.__rbx)
+#define SC_ECX(uc) ((unsigned long) (uc)->uc_mcontext->__ss.__rcx)
+#define SC_EDX(uc) ((unsigned long) (uc)->uc_mcontext->__ss.__rdx)
+#define SC_EDI(uc) ((unsigned long) (uc)->uc_mcontext->__ss.__rdi)
+#define SC_ESI(uc) ((unsigned long) (uc)->uc_mcontext->__ss.__rsi)
+#define SC_EBP(uc) ((unsigned long) (uc)->uc_mcontext->__ss.__rbp)
+#define SC_ESP(uc) ((unsigned long) (uc)->uc_mcontext->__ss.__rsp)
+#define SC_EIP(uc) ((unsigned long) (uc)->uc_mcontext->__ss.__rip)
+#define SC_R8(uc)  ((unsigned long) (uc)->uc_mcontext->__ss.__r8)
+#define SC_R9(uc)  ((unsigned long) (uc)->uc_mcontext->__ss.__r9)
+#define SC_R10(uc) ((unsigned long) (uc)->uc_mcontext->__ss.__r10)
+#define SC_R11(uc) ((unsigned long) (uc)->uc_mcontext->__ss.__r11)
+#define SC_R12(uc) ((unsigned long) (uc)->uc_mcontext->__ss.__r12)
+#define SC_R13(uc) ((unsigned long) (uc)->uc_mcontext->__ss.__r13)
+#define SC_R14(uc) ((unsigned long) (uc)->uc_mcontext->__ss.__r14)
+#define SC_R15(uc) ((unsigned long) (uc)->uc_mcontext->__ss.__r15)
+#else
+#define SC_EAX(uc) ((unsigned long) (uc)->uc_mcontext->__ss.__eax)
+#define SC_EBX(uc) ((unsigned long) (uc)->uc_mcontext->__ss.__ebx)
+#define SC_ECX(uc) ((unsigned long) (uc)->uc_mcontext->__ss.__ecx)
+#define SC_EDX(uc) ((unsigned long) (uc)->uc_mcontext->__ss.__edx)
+#define SC_EDI(uc) ((unsigned long) (uc)->uc_mcontext->__ss.__edi)
+#define SC_ESI(uc) ((unsigned long) (uc)->uc_mcontext->__ss.__esi)
+#define SC_EBP(uc) ((unsigned long) (uc)->uc_mcontext->__ss.__ebp)
+#define SC_ESP(uc) ((unsigned long) (uc)->uc_mcontext->__ss.__esp)
+#define SC_EIP(uc) ((unsigned long) (uc)->uc_mcontext->__ss.__eip)
+#endif
+#else
+#define SC_EAX(uc) ((unsigned long) (uc)->uc_mcontext->ss.eax)
+#define SC_EBX(uc) ((unsigned long) (uc)->uc_mcontext->ss.ebx)
+#define SC_ECX(uc) ((unsigned long) (uc)->uc_mcontext->ss.ecx)
+#define SC_EDX(uc) ((unsigned long) (uc)->uc_mcontext->ss.edx)
+#define SC_EDI(uc) ((unsigned long) (uc)->uc_mcontext->ss.edi)
+#define SC_ESI(uc) ((unsigned long) (uc)->uc_mcontext->ss.esi)
+#define SC_EBP(uc) ((unsigned long) (uc)->uc_mcontext->ss.ebp)
+#define SC_ESP(uc) ((unsigned long) (uc)->uc_mcontext->ss.esp)
+#define SC_EIP(uc) ((unsigned long) (uc)->uc_mcontext->ss.eip)
+#endif
+#elif defined(__FreeBSD__)
+#ifdef __x86_64__
+#define SC_EAX(uc) ((unsigned long) (uc)->uc_mcontext.mc_rax)
+#define SC_EBX(uc) ((unsigned long) (uc)->uc_mcontext.mc_rbx)
+#define SC_ECX(uc) ((unsigned long) (uc)->uc_mcontext.mc_rcx)
+#define SC_EDX(uc) ((unsigned long) (uc)->uc_mcontext.mc_rdx)
+#define SC_EDI(uc) ((unsigned long) (uc)->uc_mcontext.mc_rdi)
+#define SC_ESI(uc) ((unsigned long) (uc)->uc_mcontext.mc_rsi)
+#define SC_EBP(uc) ((unsigned long) (uc)->uc_mcontext.mc_rbp)
+#define SC_ESP(uc) ((unsigned long) (uc)->uc_mcontext.mc_rsp)
+#define SC_EIP(uc) ((unsigned long) (uc)->uc_mcontext.mc_rip)
+#define SC_R8(uc)  ((unsigned long) (uc)->uc_mcontext.mc_r8)
+#define SC_R9(uc)  ((unsigned long) (uc)->uc_mcontext.mc_r9)
+#define SC_R10(uc) ((unsigned long) (uc)->uc_mcontext.mc_r10)
+#define SC_R11(uc) ((unsigned long) (uc)->uc_mcontext.mc_r11)
+#define SC_R12(uc) ((unsigned long) (uc)->uc_mcontext.mc_r12)
+#define SC_R13(uc) ((unsigned long) (uc)->uc_mcontext.mc_r13)
+#define SC_R14(uc) ((unsigned long) (uc)->uc_mcontext.mc_r14)
+#define SC_R15(uc) ((unsigned long) (uc)->uc_mcontext.mc_r15)
+#else
+#define SC_EAX(uc) ((unsigned long) (uc)->uc_mcontext.mc_eax)
+#define SC_EBX(uc) ((unsigned long) (uc)->uc_mcontext.mc_ebx)
+#define SC_ECX(uc) ((unsigned long) (uc)->uc_mcontext.mc_ecx)
+#define SC_EDX(uc) ((unsigned long) (uc)->uc_mcontext.mc_edx)
+#define SC_EDI(uc) ((unsigned long) (uc)->uc_mcontext.mc_edi)
+#define SC_ESI(uc) ((unsigned long) (uc)->uc_mcontext.mc_esi)
+#define SC_EBP(uc) ((unsigned long) (uc)->uc_mcontext.mc_ebp)
+#define SC_ESP(uc) ((unsigned long) (uc)->uc_mcontext.mc_esp)
+#define SC_EIP(uc) ((unsigned long) (uc)->uc_mcontext.mc_eip)
+#endif
+#elif defined (sun)
+#ifdef __x86_64__
+#define SC_EAX(uc) ((unsigned long) (uc)->uc_mcontext.gregs[REG_RAX])
+#define SC_EBX(uc) ((unsigned long) (uc)->uc_mcontext.gregs[REG_RBX])
+#define SC_ECX(uc) ((unsigned long) (uc)->uc_mcontext.gregs[REG_RCX])
+#define SC_EDX(uc) ((unsigned long) (uc)->uc_mcontext.gregs[REG_RDX])
+#define SC_EDI(uc) ((unsigned long) (uc)->uc_mcontext.gregs[REG_RDI])
+#define SC_ESI(uc) ((unsigned long) (uc)->uc_mcontext.gregs[REG_RSI])
+#define SC_EBP(uc) ((unsigned long) (uc)->uc_mcontext.gregs[REG_RBP])
+#define SC_ESP(uc) ((unsigned long) (uc)->uc_mcontext.gregs[REG_RSP])
+#define SC_EIP(uc) ((unsigned long) (uc)->uc_mcontext.gregs[REG_RIP])
+#define SC_R8(uc)  ((unsigned long) (uc)->uc_mcontext.gregs[REG_R8])
+#define SC_R9(uc)  ((unsigned long) (uc)->uc_mcontext.gregs[REG_R9])
+#define SC_R10(uc) ((unsigned long) (uc)->uc_mcontext.gregs[REG_R10])
+#define SC_R11(uc) ((unsigned long) (uc)->uc_mcontext.gregs[REG_R11])
+#define SC_R12(uc) ((unsigned long) (uc)->uc_mcontext.gregs[REG_R12])
+#define SC_R13(uc) ((unsigned long) (uc)->uc_mcontext.gregs[REG_R13])
+#define SC_R14(uc) ((unsigned long) (uc)->uc_mcontext.gregs[REG_R14])
+#define SC_R15(uc) ((unsigned long) (uc)->uc_mcontext.gregs[REG_R15])
+#else
+#define SC_EAX(uc) ((unsigned long) (uc)->uc_mcontext.gregs[EAX])
+#define SC_EBX(uc) ((unsigned long) (uc)->uc_mcontext.gregs[EBX])
+#define SC_ECX(uc) ((unsigned long) (uc)->uc_mcontext.gregs[ECX])
+#define SC_EDX(uc) ((unsigned long) (uc)->uc_mcontext.gregs[EDX])
+#define SC_EDI(uc) ((unsigned long) (uc)->uc_mcontext.gregs[EDI])
+#define SC_ESI(uc) ((unsigned long) (uc)->uc_mcontext.gregs[ESI])
+#define SC_EBP(uc) ((unsigned long) (uc)->uc_mcontext.gregs[EBP])
+#define SC_ESP(uc) ((unsigned long) (uc)->uc_mcontext.gregs[ESP])
+#define SC_EIP(uc) ((unsigned long) (uc)->uc_mcontext.gregs[EIP])
+#endif
+#else
+#ifdef __x86_64__
+#define SC_EAX(uc) ((unsigned long) (uc)->uc_mcontext.gregs[GNU_REG_RAX])
+#define SC_EBX(uc) ((unsigned long) (uc)->uc_mcontext.gregs[GNU_REG_RBX])
+#define SC_ECX(uc) ((unsigned long) (uc)->uc_mcontext.gregs[GNU_REG_RCX])
+#define SC_EDX(uc) ((unsigned long) (uc)->uc_mcontext.gregs[GNU_REG_RDX])
+#define SC_EDI(uc) ((unsigned long) (uc)->uc_mcontext.gregs[GNU_REG_RDI])
+#define SC_ESI(uc) ((unsigned long) (uc)->uc_mcontext.gregs[GNU_REG_RSI])
+#define SC_EBP(uc) ((unsigned long) (uc)->uc_mcontext.gregs[GNU_REG_RBP])
+#define SC_ESP(uc) ((unsigned long) (uc)->uc_mcontext.gregs[GNU_REG_RSP])
+#define SC_EIP(uc) ((unsigned long) (uc)->uc_mcontext.gregs[GNU_REG_RIP])
+#define SC_R8(uc)  ((unsigned long) (uc)->uc_mcontext.gregs[GNU_REG_R8])
+#define SC_R9(uc)  ((unsigned long) (uc)->uc_mcontext.gregs[GNU_REG_R9])
+#define SC_R10(uc) ((unsigned long) (uc)->uc_mcontext.gregs[GNU_REG_R10])
+#define SC_R11(uc) ((unsigned long) (uc)->uc_mcontext.gregs[GNU_REG_R11])
+#define SC_R12(uc) ((unsigned long) (uc)->uc_mcontext.gregs[GNU_REG_R12])
+#define SC_R13(uc) ((unsigned long) (uc)->uc_mcontext.gregs[GNU_REG_R13])
+#define SC_R14(uc) ((unsigned long) (uc)->uc_mcontext.gregs[GNU_REG_R14])
+#define SC_R15(uc) ((unsigned long) (uc)->uc_mcontext.gregs[GNU_REG_R15])
+#else
+#define SC_EAX(uc) ((unsigned long) (uc)->uc_mcontext.gregs[GNU_REG_EAX])
+#define SC_EBX(uc) ((unsigned long) (uc)->uc_mcontext.gregs[GNU_REG_EBX])
+#define SC_ECX(uc) ((unsigned long) (uc)->uc_mcontext.gregs[GNU_REG_ECX])
+#define SC_EDX(uc) ((unsigned long) (uc)->uc_mcontext.gregs[GNU_REG_EDX])
+#define SC_EDI(uc) ((unsigned long) (uc)->uc_mcontext.gregs[GNU_REG_EDI])
+#define SC_ESI(uc) ((unsigned long) (uc)->uc_mcontext.gregs[GNU_REG_ESI])
+#define SC_EBP(uc) ((unsigned long) (uc)->uc_mcontext.gregs[GNU_REG_EBP])
+#define SC_ESP(uc) ((unsigned long) (uc)->uc_mcontext.gregs[GNU_REG_ESP])
+#define SC_EIP(uc) ((unsigned long) (uc)->uc_mcontext.gregs[GNU_REG_EIP])
+#endif
+#endif
+
+#endif // ifndef _SIGPOSIXREGS_H_
index b93fd28b211d75ce0ec2f7b039c34940332e2a4f..0e113a25f7a33267c91d2580cef0461016ba4693 100644 (file)
  *      Simple program to drive the guest RPC library.
  */
 
+#ifndef _WIN32
+#include "sigPosixRegs.h"
+#include <errno.h>
+#include <stdint.h>
+#endif
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include "vmware.h"
 #include "rpcout.h"
 #include "str.h"
+#include "backdoor_def.h"
+
+#define NOT_VMWARE_ERROR "Failed sending message to VMware.\n"
 
 int RpcToolCommand(int argc, char *argv[]);
 
+#ifndef _WIN32
+static Bool SetSignalHandler(int sig,
+                             void (*handler)(int, siginfo_t *, void *),
+                             Bool reset);
+#endif
+
 void
 PrintUsage(void)
 {
@@ -40,9 +54,86 @@ PrintUsage(void)
 }
 
 
+#ifdef _WIN32
+static Bool
+ExceptionIsBackdoor(PEXCEPTION_POINTERS excInfo)
+{
+#ifdef _WIN64
+   uint32 magic = excInfo->ContextRecord->Rax & 0xffffffff;
+   uint16 port = excInfo->ContextRecord->Rdx & 0xffff;
+#else
+   uint32 magic = excInfo->ContextRecord->Eax & 0xffffffff;
+   uint16 port = excInfo->ContextRecord->Edx & 0xffff;
+#endif
+
+   return (magic == BDOOR_MAGIC &&
+           (port == BDOOR_PORT || port == BDOORHB_PORT));
+}
+
+
+#else
+static void
+SignalHandler(int sig,
+              siginfo_t *sip,
+              void *data)
+{
+   ucontext_t *ucp = (ucontext_t *) data;
+   uint16 port = SC_EDX(ucp) & 0xffff;
+   uint32 magic = SC_EAX(ucp) & 0xffffffff;
+
+   if (magic == BDOOR_MAGIC &&
+       (port == BDOORHB_PORT || port == BDOOR_PORT)) {
+      fprintf(stderr, NOT_VMWARE_ERROR);
+      exit(1);
+   } else {
+      SetSignalHandler(sig, NULL, TRUE);
+      raise(sig);
+   }
+}
+
+
+static Bool
+SetSignalHandler(int sig,
+                 void (*handler)(int, siginfo_t *, void *),
+                 Bool reset)
+{
+   static struct sigaction old;
+
+   if (reset) {
+      struct sigaction tmp = old;
+
+      memset(&old, 0, sizeof old);
+      return sigaction(sig, &tmp, NULL) ? FALSE : TRUE;
+   } else {
+      struct sigaction new;
+
+      /* Setup the handler and flags to get exception information. */
+      new.sa_sigaction = handler;
+      new.sa_flags = SA_SIGINFO;
+
+      /* Block all signals when handling this. */
+      if (sigfillset(&new.sa_mask) == -1) {
+         fprintf(stderr, "Unable to initialize a signal set: %s.\n\n",
+                 strerror(errno));
+         return FALSE;
+      }
+
+      if (sigaction(sig, &new, &old) == -1) {
+         fprintf(stderr, "Unable to initialize a signal handler: %s.\n\n",
+                 strerror(errno));
+         return FALSE;
+      }
+   }
+   return TRUE;
+}
+#endif
+
+
 int
 main(int argc, char *argv[])
 {
+   int ret = 1;
+
    if (argc <= 1) {
       PrintUsage();
       return 1;
@@ -51,7 +142,26 @@ main(int argc, char *argv[])
    argc--;
    argv++;
 
-   return RpcToolCommand(argc, argv);
+#ifdef _WIN32
+   __try {
+      ret = RpcToolCommand(argc, argv);
+   } __except(ExceptionIsBackdoor(GetExceptionInformation()) ?
+               EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
+      fprintf(stderr, NOT_VMWARE_ERROR);
+      return 1;
+   }
+#else
+#ifdef __FreeBSD__
+#  define ERROR_SIGNAL SIGBUS
+#else
+#  define ERROR_SIGNAL SIGSEGV
+#endif
+   if (SetSignalHandler(ERROR_SIGNAL, SignalHandler, FALSE)) {
+      ret = RpcToolCommand(argc, argv);
+   }
+   ret = SetSignalHandler(ERROR_SIGNAL, NULL, TRUE) ? 0 : 1;
+#endif
+   return ret;
 }
 
 int