]> git.ipfire.org Git - thirdparty/open-vm-tools.git/commitdiff
Use a unique random temp directory for vmtoolsd on Linux.
authorOliver Kurth <okurth@vmware.com>
Mon, 26 Feb 2018 20:35:36 +0000 (12:35 -0800)
committerOliver Kurth <okurth@vmware.com>
Mon, 26 Feb 2018 20:35:36 +0000 (12:35 -0800)
The temporay directory currently used by vmtoolsd and its plugins
on Linux is of the form /tmp/vmware-<user>.  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-<user>_<pid>-nnnnnn

VMware Tools commands and plugins are being updated to use this random
temp directory.

open-vm-tools/lib/file/fileTempPosix.c
open-vm-tools/lib/include/file.h
open-vm-tools/services/plugins/deployPkg/deployPkg.c
open-vm-tools/services/plugins/vix/vixTools.c

index c6d98786b23eecf033cfdd7b7383e183a3d903c9..adce56be9842a4641bed29fdf2b8837eb1e6b0f3 100644 (file)
@@ -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);
+}
index 39b862571c5658db42e7296dea848be76bd4e95a..a7a698a503d35f191544afcf44df273d234a9ed8 100644 (file)
@@ -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);
 
index d97d83571096f6bdb2110b46f614fb22b53ab22b..237d2351e2edd58e876b8e57ab0e800f9a05b769 100644 (file)
@@ -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;
    }
 
index 435b934addb34bbc54a212388199bdefa384d727..98df172d87f7e4f09c6d052fcfb90f38a9757cc4 100644 (file)
@@ -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);
       }
 
       /*