]> git.ipfire.org Git - thirdparty/open-vm-tools.git/commitdiff
Common source file changes not directly applicable to open-vm-tools.
authorOliver Kurth <okurth@vmware.com>
Wed, 4 Mar 2020 20:07:12 +0000 (12:07 -0800)
committerOliver Kurth <okurth@vmware.com>
Wed, 4 Mar 2020 20:07:12 +0000 (12:07 -0800)
Fix procMgr library for Windows.

- For windows, to retrieve the command line for a target process,
the procMgr library creates a remote thread in the target process
and executes GetCommandLine function.  This approach is OK. But for
few applications that are not built with proper flags, creating a
remote thread may crash the application.  In order to avoid any
issues, it was decided not use the 'remote thread' approach by DEFAULT.

- Refactored the procMgr APIs to take an input argument from the
user if the 'remote thread' approach needs to be used.

- Refactored the procMgr APIs to conditionally use the WMI for
retrieving the command line for a target process.

- New options are provided to the user if the 'remote thread'
and 'WMI' approaches need to be forced.  Modified the VIX tools plugin
to read and honor the new flags from tools.conf

The following are the new flags under guestoperations group.
useRemoteThreadForProcessCommandLine
useWMIForProcessCommandLine

The default value for the above new flags is false. User can set them
to true if needed.

- Re-factored some code in appInfo plugin that calls procMgr library.
The appinfo plugin doesn't really use the commandline.  So, modified the
appinfo plugin to just use the API that doesn't use the complicated
approaches for the listing down the processes.

open-vm-tools/lib/include/procMgr.h
open-vm-tools/services/plugins/appInfo/appInfo.c
open-vm-tools/services/plugins/appInfo/appInfoInt.h
open-vm-tools/services/plugins/appInfo/appInfoPosix.c
open-vm-tools/services/plugins/vix/vixTools.c

index d6adad1ba86f014eb0cf79ebfa5c4a19b1cf0074..218b7ba6e8aa2729a3e8f59d2b7423680897640c 100644 (file)
@@ -1,5 +1,5 @@
 /*********************************************************
- * Copyright (C) 2002-2019 VMware, Inc. All rights reserved.
+ * Copyright (C) 2002-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
@@ -139,7 +139,8 @@ typedef int Selectable;
 ProcMgrProcInfoArray *ProcMgr_ListProcesses(void);
 
 #if defined(_WIN32)
-ProcMgrProcInfoArray *ProcMgr_ListProcessesEx(void);
+ProcMgrProcInfoArray *ProcMgr_ListProcessesEx(Bool useRemoteThreadForCmdLine,
+                                              Bool useWMIForCmdLine);
 #endif
 
 void ProcMgr_FreeProcList(ProcMgrProcInfoArray *procList);
index a7e17a86b5f8841da070dd0d0c5fe6084a1f641f..708c411e062f6c991c3c6b5acfe10aa57b2a2489 100644 (file)
@@ -1,5 +1,5 @@
 /*********************************************************
- * Copyright (C) 2019 VMware, Inc. All rights reserved.
+ * Copyright (C) 2019-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
@@ -184,6 +184,49 @@ SetGuestInfo(ToolsAppCtx *ctx,              // IN:
 }
 
 
+/*
+ *----------------------------------------------------------------------
+ * AppInfo_GetAppList --
+ *
+ * Generates the application information list.
+ *
+ * @retval Pointer to the newly allocated application list. The caller must
+ *         free the memory using AppInfoDestroyAppList function.
+ *         NULL if any error occurs.
+ *
+ *----------------------------------------------------------------------
+ */
+
+GSList *
+AppInfo_GetAppList(void) {
+   GSList *appList = NULL;
+   int i;
+   ProcMgrProcInfoArray *procList = NULL;
+   size_t procCount;
+
+   procList = ProcMgr_ListProcesses();
+
+   if (procList == NULL) {
+      g_warning("Failed to get the list of processes.\n");
+      return appList;
+   }
+
+   procCount = ProcMgrProcInfoArray_Count(procList);
+   for (i = 0; i < procCount; i++) {
+      AppInfo *appInfo;
+      ProcMgrProcInfo *procInfo = ProcMgrProcInfoArray_AddressOf(procList, i);
+      appInfo = AppInfoGetAppInfo(procInfo);
+      if (NULL != appInfo) {
+         appList = g_slist_prepend(appList, appInfo);
+      }
+   }
+
+   ProcMgr_FreeProcList(procList);
+
+   return appList;
+}
+
+
 /*
  *****************************************************************************
  * AppInfoGatherTask --
index d827e14c3107c08ceb7e0cb692fd91060b5da8c1..4d2ae17ba256d45e83ec321f49de7581b15adccc 100644 (file)
@@ -1,5 +1,5 @@
 /*********************************************************
- * Copyright (C) 2019 VMware, Inc. All rights reserved.
+ * Copyright (C) 2019-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
@@ -29,6 +29,7 @@
 #include "vm_basic_types.h"
 #include <glib.h>
 #include "vmware/tools/plugin.h"
+#include "procMgr.h"
 
 #if defined(_WIN32)
 
@@ -61,4 +62,7 @@ GSList *AppInfo_GetAppList(void);
 GSList *AppInfo_SortAppList(GSList *appList);
 
 void AppInfo_DestroyAppList(GSList *appList);
+
+AppInfo *AppInfoGetAppInfo(ProcMgrProcInfo *procInfo);
+
 #endif /* _APPINFOINT_H_ */
index fb863800cc5fc3451654927139856092edd9e60c..4e1c39466a86ca297b56d58e501f8534e1b1a16b 100644 (file)
@@ -1,5 +1,5 @@
 /*********************************************************
- * Copyright (C) 2019 VMware, Inc. All rights reserved.
+ * Copyright (C) 2019-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
 #   error This file should not be compiled.
 #endif
 
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
 #include "appInfoInt.h"
-#include "procMgr.h"
-#include "vmware.h"
-#include "str.h"
 #include "util.h"
 
 
@@ -75,50 +67,3 @@ AppInfoGetAppInfo(ProcMgrProcInfo *procInfo)   // IN
 
    return appInfo;
 }
-
-
-/*
- *----------------------------------------------------------------------
- * AppInfo_GetAppList --
- *
- * Generates the application information list.
- *
- * @retval Pointer to the newly allocated application list. The caller must
- *         free the memory using AppInfoDestroyAppList function.
- *         NULL if any error occurs.
- *
- *----------------------------------------------------------------------
- */
-
-GSList *
-AppInfo_GetAppList(void) {
-   GSList *appList = NULL;
-   int i;
-   ProcMgrProcInfoArray *procList = NULL;
-   size_t procCount;
-
-#if defined(_WIN32)
-   procList = ProcMgr_ListProcessesEx();
-#else
-   procList = ProcMgr_ListProcesses();
-#endif
-
-   if (procList == NULL) {
-      g_warning("Failed to get the list of processes.\n");
-      return appList;
-   }
-
-   procCount = ProcMgrProcInfoArray_Count(procList);
-   for (i = 0; i < procCount; i++) {
-      AppInfo *appInfo;
-      ProcMgrProcInfo *procInfo = ProcMgrProcInfoArray_AddressOf(procList, i);
-      appInfo = AppInfoGetAppInfo(procInfo);
-      if (NULL != appInfo) {
-         appList = g_slist_prepend(appList, appInfo);
-      }
-   }
-
-   ProcMgr_FreeProcList(procList);
-
-   return appList;
-}
index 8d78ccb5607432fca5ecfd2cd885692c09709295..ffe77abe2b8ba7fff6064093819e7aa30691a1ff 100644 (file)
 static gboolean gSupportVGAuth = USE_VGAUTH_DEFAULT;
 static gboolean QueryVGAuthConfig(GKeyFile *confDictRef);
 
+#ifdef _WIN32
+/*
+ * Check bug 2508431 for more details. If an application is not built
+ * with proper flags, 'creating a remote thread' to get the process
+ * command line will crash the target process. To avoid any such crash,
+ * 'remote thread' approach is not used by default.
+ *
+ * But 'remote thread' approach can be turned on (for whatever reason)
+ * by setting the following option to true in the tools.conf file.
+ *
+ * For few processes, 'WMI' can provide detailed commandline information.
+ * But using 'WMI' is a heavy weight approach and may affect the CPU
+ * performance and hence it is disabled by default. It can always be
+ * turned on by a setting (as mentioned below) in the tools.conf file.
+ */
+#define VIXTOOLS_CONFIG_USE_REMOTE_THREAD_PROCESS_COMMAND_LINE  \
+      "useRemoteThreadForProcessCommandLine"
+
+#define VIXTOOLS_CONFIG_USE_WMI_PROCESS_COMMAND_LINE  \
+      "useWMIForProcessCommandLine"
+
+#define USE_REMOTE_THREAD_PROCESS_COMMAND_LINE_DEFAULT FALSE
+#define USE_WMI_PROCESS_COMMAND_LINE_DEFAULT FALSE
+
+#endif
+
 #if ALLOW_LOCAL_SYSTEM_IMPERSONATION_BYPASS
 static gchar *gCurrentUsername = NULL;
 
@@ -5484,9 +5510,10 @@ VixToolsListProcCacheCleanup(void *clientData) // IN
  *-----------------------------------------------------------------------------
  */
 
-VixError
+static VixError
 VixToolsListProcessesExGenerateData(uint32 numPids,          // IN
                                     const uint64 *pids,      // IN
+                                    GKeyFile *confDictRef,   // IN
                                     size_t *resultSize,      // OUT
                                     char **resultBuffer)     // OUT
 {
@@ -5501,6 +5528,11 @@ VixToolsListProcessesExGenerateData(uint32 numPids,          // IN
    Bool bRet;
    size_t procCount;
 
+#ifdef _WIN32
+   gboolean useRemoteThreadProcCmdLine;
+   gboolean useWMIProcCmdLine;
+#endif
+
    DynBuf_Init(&dynBuffer);
 
    /*
@@ -5567,7 +5599,25 @@ VixToolsListProcessesExGenerateData(uint32 numPids,          // IN
     * return an error code so there's no risk of errno/LastError
     * being clobbered.
     */
+#ifdef _WIN32
+   useRemoteThreadProcCmdLine = VixTools_ConfigGetBoolean(confDictRef,
+                     VIX_TOOLS_CONFIG_API_GROUPNAME,
+                     VIXTOOLS_CONFIG_USE_REMOTE_THREAD_PROCESS_COMMAND_LINE,
+                     USE_REMOTE_THREAD_PROCESS_COMMAND_LINE_DEFAULT);
+
+   useWMIProcCmdLine = VixTools_ConfigGetBoolean(confDictRef,
+                          VIX_TOOLS_CONFIG_API_GROUPNAME,
+                          VIXTOOLS_CONFIG_USE_WMI_PROCESS_COMMAND_LINE,
+                          USE_WMI_PROCESS_COMMAND_LINE_DEFAULT);
+
+   g_debug("Options for process cmdline: useRemoeThread: %d, useWMI: %d\n",
+            useRemoteThreadProcCmdLine, useWMIProcCmdLine);
+
+   procList = ProcMgr_ListProcessesEx(useRemoteThreadProcCmdLine,
+                                      useWMIProcCmdLine);
+#else
    procList = ProcMgr_ListProcesses();
+#endif
    if (NULL == procList) {
       err = FoundryToolsDaemon_TranslateSystemErr();
       goto abort;
@@ -5660,9 +5710,10 @@ abort:
  *-----------------------------------------------------------------------------
  */
 
-VixError
+static VixError
 VixToolsListProcessesEx(VixCommandRequestHeader *requestMsg, // IN
                         size_t maxBufferSize,                // IN
+                        GKeyFile *confDictRef,               // IN
                         void *eventQueue,                    // IN
                         char **result)                       // OUT
 {
@@ -5798,7 +5849,7 @@ VixToolsListProcessesEx(VixCommandRequestHeader *requestMsg, // IN
          pids = (uint64 *)((char *)requestMsg + sizeof(*listRequest));
       }
 
-      err = VixToolsListProcessesExGenerateData(numPids, pids,
+      err = VixToolsListProcessesExGenerateData(numPids, pids, confDictRef,
                                                 &fullResultSize,
                                                 &fullResultBuffer);
 
@@ -10937,9 +10988,10 @@ VixTools_ProcessVixCommand(VixCommandRequestHeader *requestMsg,   // IN
       ////////////////////////////////////
       case VIX_COMMAND_LIST_PROCESSES_EX:
          err = VixToolsListProcessesEx(requestMsg,
-                                      maxResultBufferSize,
-                                      eventQueue,
-                                      &resultValue);
+                                       maxResultBufferSize,
+                                       confDictRef,
+                                       eventQueue,
+                                       &resultValue);
          deleteResultValue = TRUE;
          break;