From: Oliver Kurth Date: Mon, 26 Feb 2018 20:35:36 +0000 (-0800) Subject: Use a unique random temp directory for vmtoolsd on Linux. X-Git-Tag: 10.2.5~6 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f14358943289c29fc2a0374d7e258ca9d498225d;p=thirdparty%2Fopen-vm-tools.git Use a unique random temp directory for vmtoolsd on Linux. The temporay directory currently used by vmtoolsd and its plugins on Linux is of the form /tmp/vmware-. Since it is used to upload VMware Tools upgrade and GOS customization scripts and commands, that name predictability may make it susceptible to attack. This change adds a new function File_GetSafeRandomTmpDir() in bora/lib/file/fileTempPosix.c to both add the PID to the user name and add a random number suffix to the temp directory path. /tmp/vmware-_-nnnnnn VMware Tools commands and plugins are being updated to use this random temp directory. --- diff --git a/open-vm-tools/lib/file/fileTempPosix.c b/open-vm-tools/lib/file/fileTempPosix.c index c6d98786b..adce56be9 100644 --- a/open-vm-tools/lib/file/fileTempPosix.c +++ b/open-vm-tools/lib/file/fileTempPosix.c @@ -1,5 +1,5 @@ /********************************************************* - * Copyright (C) 2004-2017 VMware, Inc. All rights reserved. + * Copyright (C) 2004-2018 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 @@ -439,16 +439,16 @@ FileCreateSafeTmpDir(uid_t userId, // IN: /* *----------------------------------------------------------------------------- * - * File_GetSafeTmpDir -- + * FileGetSafeTmpDir -- * * Return a safe temporary directory (i.e. a temporary directory which * is not prone to symlink attacks, because it is only writable by the * current effective user). * - * Guaranteed to return the same directory every time it is - * called during the lifetime of the current process, for the - * current effective user ID. (Barring the user manually deleting - * or renaming the directory.) + * Guaranteed to return the same directory, based on the randomTemp + * boolean argument, every time it is called during the lifetime of + * the current process, for the current effective user ID. (Barring + * the user manually deleting or renaming the directory.) * * Results: * The allocated directory path on success. @@ -460,16 +460,19 @@ FileCreateSafeTmpDir(uid_t userId, // IN: *----------------------------------------------------------------------------- */ -char * -File_GetSafeTmpDir(Bool useConf) // IN: +static char * +FileGetSafeTmpDir(Bool useConf, // IN: + Bool randomTemp) // IN: { - char *tmpDir; + char *tmpDir = NULL; #if defined(__FreeBSD__) || defined(sun) tmpDir = FileGetTmpDir(useConf); #else static Atomic_Ptr lckStorage; static char *safeDir; + static char *safeRandomDir; + char *testSafeDir; char *baseTmpDir = NULL; char *userName = NULL; uid_t userId; @@ -484,13 +487,13 @@ File_GetSafeTmpDir(Bool useConf) // IN: MXUser_AcquireExclLock(lck); /* - * Check if we've created a temporary dir already and if it is still usable. + * Based on the randomTemp boolean argument, check if we've created a + * temporary dir already and if it is still usable. */ - tmpDir = NULL; - - if (safeDir && FileAcceptableSafeTmpDir(safeDir, userId)) { - tmpDir = Util_SafeStrdup(safeDir); + testSafeDir = randomTemp ? safeRandomDir : safeDir; + if (testSafeDir && FileAcceptableSafeTmpDir(testSafeDir, userId)) { + tmpDir = Util_SafeStrdup(testSafeDir); goto exit; } @@ -509,7 +512,7 @@ File_GetSafeTmpDir(Bool useConf) // IN: "as username instead.\n", __FUNCTION__); /* Fallback on just using the userId as the username. */ - userName = Str_Asprintf(NULL, "uid-%d", userId); + userName = Str_Asprintf(NULL, "uid_%d", userId); if (userName == NULL) { Warning("%s: Str_Asprintf error.\n", __FUNCTION__); @@ -517,6 +520,26 @@ File_GetSafeTmpDir(Bool useConf) // IN: } } + if (randomTemp) { + /* + * Suffix the userName with the PID for the cases where the + * EUID may toggle during the lifetime of the process. + */ + + char *userNameAndPid; + pid_t pid = getpid(); + + userNameAndPid = Str_Asprintf(NULL, "%s_%d", userName, pid); + + if (userNameAndPid == NULL) { + Warning("%s: Str_Asprintf error.\n", __FUNCTION__); + goto exit; + } + + Posix_Free(userName); + userName = userNameAndPid; + } + tmpDir = Str_Asprintf(NULL, "%s%s%s-%s", baseTmpDir, DIRSEPS, PRODUCT_GENERIC_NAME_LOWER, userName); @@ -525,9 +548,10 @@ File_GetSafeTmpDir(Bool useConf) // IN: goto exit; } - if (!FileAcceptableSafeTmpDir(tmpDir, userId)) { + if (randomTemp || !FileAcceptableSafeTmpDir(tmpDir, userId)) { /* - * We didn't get our first choice for the safe temp directory. + * Either we want a truely random temp directory or we didn't get + * our first choice for the safe temp directory. * Search through the unsafe tmp directory to see if there is * an acceptable one to use. */ @@ -551,8 +575,14 @@ File_GetSafeTmpDir(Bool useConf) // IN: * future calls. */ - Posix_Free(safeDir); - safeDir = Util_SafeStrdup(tmpDir); + testSafeDir = Util_SafeStrdup(tmpDir); + if (randomTemp) { + Posix_Free(safeRandomDir); + safeRandomDir = testSafeDir; + } else { + Posix_Free(safeDir); + safeDir = testSafeDir; + } } exit: @@ -563,3 +593,65 @@ File_GetSafeTmpDir(Bool useConf) // IN: return tmpDir; } + + +/* + *----------------------------------------------------------------------------- + * + * File_GetSafeTmpDir -- + * + * Return a safe temporary directory (i.e. a temporary directory which + * is not prone to symlink attacks, because it is only writable by the + * current effective user). + * + * Guaranteed to return the same directory every time it is + * called during the lifetime of the current process, for the + * current effective user ID. (Barring the user manually deleting + * or renaming the directory.) + * + * Results: + * The allocated directory path on success. + * NULL on failure. + * + * Side effects: + * None. + * + *----------------------------------------------------------------------------- + */ + +char * +File_GetSafeTmpDir(Bool useConf) // IN: +{ + return FileGetSafeTmpDir(useConf, FALSE); +} + + +/* + *----------------------------------------------------------------------------- + * + * File_GetSafeRandomTmpDir -- + * + * Return a safe, random temporary directory (i.e. a temporary directory + * which is not prone to symlink attacks, because it is only writable + * by the current effective user). + * + * Guaranteed to return the same directory every time it is + * called during the lifetime of the current process, for the + * current effective user ID. (Barring the user manually deleting + * or renaming the directory.) + * + * Results: + * The allocated directory path on success. + * NULL on failure. + * + * Side effects: + * None. + * + *----------------------------------------------------------------------------- + */ + +char * +File_GetSafeRandomTmpDir(Bool useConf) // IN: +{ + return FileGetSafeTmpDir(useConf, TRUE); +} diff --git a/open-vm-tools/lib/include/file.h b/open-vm-tools/lib/include/file.h index 39b862571..a7a698a50 100644 --- a/open-vm-tools/lib/include/file.h +++ b/open-vm-tools/lib/include/file.h @@ -1,5 +1,5 @@ /********************************************************* - * Copyright (C) 1998-2017 VMware, Inc. All rights reserved. + * Copyright (C) 1998-2018 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 @@ -372,6 +372,8 @@ char *File_ExpandAndCheckDir(const char *dirName); char *File_GetSafeTmpDir(Bool useConf); +char *File_GetSafeRandomTmpDir(Bool useConf); + int File_MakeSafeTemp(const char *tag, char **presult); diff --git a/open-vm-tools/services/plugins/deployPkg/deployPkg.c b/open-vm-tools/services/plugins/deployPkg/deployPkg.c index d97d83571..237d2351e 100644 --- a/open-vm-tools/services/plugins/deployPkg/deployPkg.c +++ b/open-vm-tools/services/plugins/deployPkg/deployPkg.c @@ -1,5 +1,5 @@ /********************************************************* - * Copyright (C) 2006-2017 VMware, Inc. All rights reserved. + * Copyright (C) 2006-2018 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 @@ -325,8 +325,8 @@ DeployPkgGetTempDir(void) * Get system temporary directory. */ - if ((dir = File_GetSafeTmpDir(TRUE)) == NULL) { - g_warning("%s: File_GetSafeTmpDir failed\n", __FUNCTION__); + if ((dir = File_GetSafeRandomTmpDir(TRUE)) == NULL) { + g_warning("%s: File_GetSafeRandomTmpDir failed\n", __FUNCTION__); goto exit; } diff --git a/open-vm-tools/services/plugins/vix/vixTools.c b/open-vm-tools/services/plugins/vix/vixTools.c index 435b934ad..98df172d8 100644 --- a/open-vm-tools/services/plugins/vix/vixTools.c +++ b/open-vm-tools/services/plugins/vix/vixTools.c @@ -2510,7 +2510,7 @@ VixTools_GetToolsPropertiesImpl(GKeyFile *confDictRef, // IN CONFNAME_SUSPENDSCRIPT, NULL); } - tempDir = File_GetSafeTmpDir(TRUE); + tempDir = File_GetSafeRandomTmpDir(TRUE); /* * Now, record these values in a property list. @@ -7316,7 +7316,7 @@ VixToolsRunScript(VixCommandRequestHeader *requestMsg, // IN /* * Don't give up if VixToolsGetUserTmpDir() failed. It might just * have failed to load DLLs, so we might be running on Win 9x. - * Just fall through to use the old fashioned File_GetSafeTmpDir(). + * Just fall through to use the old fashioned File_GetSafeRandomTmpDir(). */ err = VIX_OK; @@ -7324,7 +7324,8 @@ VixToolsRunScript(VixCommandRequestHeader *requestMsg, // IN #endif if (NULL == tempDirPath) { - tempDirPath = File_GetSafeTmpDir(TRUE); + tempDirPath = File_GetSafeRandomTmpDir(TRUE); + if (NULL == tempDirPath) { err = FoundryToolsDaemon_TranslateSystemErr(); goto abort; @@ -8360,7 +8361,8 @@ VixToolsGetTempFile(VixCommandRequestHeader *requestMsg, // IN /* * Don't give up if VixToolsGetUserTmpDir() failed. It might just * have failed to load DLLs, so we might be running on Win 9x. - * Just fall through to use the old fashioned File_GetSafeTmpDir(). + * Just fall through to use the old fashioned + * File_GetSafeRandomTmpDir(). */ ASSERT(directoryPath == NULL); @@ -8374,7 +8376,7 @@ VixToolsGetTempFile(VixCommandRequestHeader *requestMsg, // IN if (!strcmp(directoryPath, "")) { free(directoryPath); directoryPath = NULL; - directoryPath = File_GetSafeTmpDir(TRUE); + directoryPath = File_GetSafeRandomTmpDir(TRUE); } /*