/*********************************************************
- * 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
/*
*-----------------------------------------------------------------------------
*
- * 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.
*-----------------------------------------------------------------------------
*/
-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;
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;
}
"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__);
}
}
+ 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);
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.
*/
* 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:
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);
+}
CONFNAME_SUSPENDSCRIPT, NULL);
}
- tempDir = File_GetSafeTmpDir(TRUE);
+ tempDir = File_GetSafeRandomTmpDir(TRUE);
/*
* Now, record these values in a property list.
/*
* 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;
#endif
if (NULL == tempDirPath) {
- tempDirPath = File_GetSafeTmpDir(TRUE);
+ tempDirPath = File_GetSafeRandomTmpDir(TRUE);
+
if (NULL == tempDirPath) {
err = FoundryToolsDaemon_TranslateSystemErr();
goto abort;
/*
* 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);
if (!strcmp(directoryPath, "")) {
free(directoryPath);
directoryPath = NULL;
- directoryPath = File_GetSafeTmpDir(TRUE);
+ directoryPath = File_GetSafeRandomTmpDir(TRUE);
}
/*