From: Oliver Kurth Date: Wed, 4 Mar 2020 20:07:12 +0000 (-0800) Subject: Common source file changes not directly applicable to open-vm-tools. X-Git-Tag: stable-11.1.0~54 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5c984cb0d9c72a1ef61cdb378371c528c83b3109;p=thirdparty%2Fopen-vm-tools.git Common source file changes not directly applicable to open-vm-tools. 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. --- diff --git a/open-vm-tools/lib/include/procMgr.h b/open-vm-tools/lib/include/procMgr.h index d6adad1ba..218b7ba6e 100644 --- a/open-vm-tools/lib/include/procMgr.h +++ b/open-vm-tools/lib/include/procMgr.h @@ -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); diff --git a/open-vm-tools/services/plugins/appInfo/appInfo.c b/open-vm-tools/services/plugins/appInfo/appInfo.c index a7e17a86b..708c411e0 100644 --- a/open-vm-tools/services/plugins/appInfo/appInfo.c +++ b/open-vm-tools/services/plugins/appInfo/appInfo.c @@ -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 -- diff --git a/open-vm-tools/services/plugins/appInfo/appInfoInt.h b/open-vm-tools/services/plugins/appInfo/appInfoInt.h index d827e14c3..4d2ae17ba 100644 --- a/open-vm-tools/services/plugins/appInfo/appInfoInt.h +++ b/open-vm-tools/services/plugins/appInfo/appInfoInt.h @@ -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 #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_ */ diff --git a/open-vm-tools/services/plugins/appInfo/appInfoPosix.c b/open-vm-tools/services/plugins/appInfo/appInfoPosix.c index fb863800c..4e1c39466 100644 --- a/open-vm-tools/services/plugins/appInfo/appInfoPosix.c +++ b/open-vm-tools/services/plugins/appInfo/appInfoPosix.c @@ -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 @@ -28,15 +28,7 @@ # error This file should not be compiled. #endif - -#include -#include -#include - #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; -} diff --git a/open-vm-tools/services/plugins/vix/vixTools.c b/open-vm-tools/services/plugins/vix/vixTools.c index 8d78ccb56..ffe77abe2 100644 --- a/open-vm-tools/services/plugins/vix/vixTools.c +++ b/open-vm-tools/services/plugins/vix/vixTools.c @@ -161,6 +161,32 @@ 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;