]> git.ipfire.org Git - thirdparty/open-vm-tools.git/commitdiff
Common source file changes not applicable to open-vm-tools.
authorOliver Kurth <okurth@vmware.com>
Tue, 21 Apr 2020 21:43:45 +0000 (14:43 -0700)
committerOliver Kurth <okurth@vmware.com>
Tue, 21 Apr 2020 21:43:45 +0000 (14:43 -0700)
Tools Windows: test plugin DLLs are the correct version

open-vm-tools/services/vmtoolsd/mainLoop.c
open-vm-tools/services/vmtoolsd/pluginMgr.c
open-vm-tools/services/vmtoolsd/toolsCoreInt.h

index 941452acb16906f12c20a81bfe6ea79875f89906..f864742cb6abaab7801e79c14eb308e2f0464687 100644 (file)
@@ -1,5 +1,5 @@
 /*********************************************************
- * Copyright (C) 2008-2019 VMware, Inc. All rights reserved.
+ * Copyright (C) 2008-2020 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
@@ -45,6 +45,7 @@
 #include "vmware/tools/utils.h"
 #include "vmware/tools/vmbackup.h"
 #if defined(_WIN32)
+#  include "codeset.h"
 #  include "windowsu.h"
 #else
 #  include "posix.h"
@@ -676,6 +677,98 @@ ToolCoreGetLastErrorMsg(DWORD error)
    return msg;
 }
 
+
+/**
+ * Check the version for a file using GetFileVersionInfo method
+ *
+ * @param[in]  pluginPath        plugin path name.
+ * @param[in]  checkBuildNumber  inlcude check for build number.
+ *
+ * @return TRUE if plugin version matches the tools version,
+ *         FALSE in case of a mismatch.
+ */
+
+gboolean
+ToolsCore_CheckModuleVersion(const gchar *pluginPath,
+                             gboolean checkBuildNumber)
+{
+   WCHAR *pluginPathW = NULL;
+   void *buffer = NULL;
+   DWORD bufferLen = 0;
+   DWORD dummy = 0;
+   VS_FIXEDFILEINFO *fixedFileInfo = NULL;
+   UINT fixedFileInfoLen = 0;
+   ToolsVersionComponents toolsVer = {0};
+   uint32 pluginVersion[4] = {0};
+   gboolean result = FALSE;
+   static const uint32 toolsBuildNumber = PRODUCT_BUILD_NUMBER_NUMERIC;
+
+   if (!CodeSet_Utf8ToUtf16le(pluginPath,
+                              strlen(pluginPath),
+                              (char **)&pluginPathW,
+                              NULL)) {
+      g_debug("%s: Could not convert file %s to UTF-16\n",
+              __FUNCTION__, pluginPath);
+      goto exit;
+   }
+
+   bufferLen = GetFileVersionInfoSizeW(pluginPathW, &dummy);
+   if (bufferLen == 0) {
+      g_debug("%s: Failed to get info size from %s %u",
+              __FUNCTION__, pluginPath, GetLastError());
+      goto exit;
+   }
+
+   buffer = g_malloc(bufferLen);
+   if (!buffer) {
+      g_debug("%s: malloc failed for %s", __FUNCTION__, pluginPath);
+      goto exit;
+   }
+
+   if (!GetFileVersionInfoW(pluginPathW, 0, bufferLen, buffer)) {
+      g_debug("%s: Failed to get info size from %s %u",
+              __FUNCTION__, pluginPath, GetLastError());
+      goto exit;
+   }
+
+   if (!VerQueryValueW(buffer, L"\\", (void **)&fixedFileInfo, &fixedFileInfoLen)) {
+      g_debug("%s: Failed to get fixed file info from %s %u",
+              __FUNCTION__, pluginPath, GetLastError());
+      goto exit;
+   }
+
+   if (fixedFileInfoLen < sizeof *fixedFileInfo) {
+      g_debug("%s: Fixed file info from %s is too short: %d",
+                __FUNCTION__, pluginPath, fixedFileInfoLen);
+      goto exit;
+   }
+
+   /* Using Product version. File version is also available. */
+   pluginVersion[0] = (uint16)(fixedFileInfo->dwProductVersionMS >> 16);
+   pluginVersion[1] = (uint16)(fixedFileInfo->dwProductVersionMS >>  0);
+   pluginVersion[2] = (uint16)(fixedFileInfo->dwProductVersionLS >> 16);
+   pluginVersion[3] = (uint16)(fixedFileInfo->dwProductVersionLS >>  0);
+
+   TOOLS_VERSION_UINT_TO_COMPONENTS(TOOLS_VERSION_CURRENT, &toolsVer);
+
+   result = (pluginVersion[0] == toolsVer.major &&
+             pluginVersion[1] == toolsVer.minor &&
+             pluginVersion[2] == toolsVer.base);
+
+   if (result && checkBuildNumber) {
+      result =  pluginVersion[3] == toolsBuildNumber;
+   }
+
+exit:
+   if (!result) {
+      g_warning("%s: Failed or no version check %s : %u.%u.%u.%u",
+                __FUNCTION__, pluginPath, pluginVersion[0], pluginVersion[1],
+                pluginVersion[2], pluginVersion[3]);
+   }
+   g_free(buffer);
+   free(pluginPathW);
+   return result;
+}
 #endif
 
 
index a7338db9070793ef2802faafa41e1120d3862636..53b91f7aafc210b8bdcaa3631f87081e8882cb0e 100644 (file)
@@ -1,5 +1,5 @@
 /*********************************************************
- * Copyright (C) 2008-2019 VMware, Inc. All rights reserved.
+ * Copyright (C) 2008-2020 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
@@ -554,6 +554,21 @@ ToolsCoreLoadDirectory(ToolsAppCtx *ctx,
       }
 #endif
 
+#ifdef _WIN32
+      /*
+       * Only load compatible versions of a plugin which requires that a plugin
+       * and tools product versions match.
+       * Using FALSE compares the major.minor.base components of the version.
+       * Version format is: "major.minor.base.buildnumber" e.g. "11.2.0.19761"
+       * Use TRUE for a more strict check to verify all four version components.
+       */
+      if (!ToolsCore_CheckModuleVersion(path, FALSE)) {
+         g_warning("%s: Version check of plugin '%s' failed: not loaded.\n",
+                    __FUNCTION__, path);
+         goto next;
+      }
+#endif
+
       module = g_module_open(path, G_MODULE_BIND_LOCAL);
 #ifdef USE_APPLOADER
       if (module == NULL) {
index b26a0d0cd71b714d202f4d9a0e7b7448dfb4bae3..06c99020294d6d35916b8d9e431acfbd6a225d31 100644 (file)
@@ -1,5 +1,5 @@
 /*********************************************************
- * Copyright (C) 2008-2019 VMware, Inc. All rights reserved.
+ * Copyright (C) 2008-2020 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
@@ -150,6 +150,11 @@ void
 ToolsCore_SetCapabilities(RpcChannel *chan,
                           GArray *caps,
                           gboolean set);
+#if defined(_WIN32)
+gboolean
+ToolsCore_CheckModuleVersion(const gchar *pluginPath,
+                             gboolean checkBuildNumber);
+#endif
 
 void
 ToolsCore_UnloadPlugins(ToolsServiceState *state);