Browse code

Fixing tmp race condition in libDeploy OVT PR# 1733669

Change-Id: Iad5672837690496796f0856740132b2e75501834
Reviewed-on: http://photon-jenkins.eng.vmware.com:8082/2335
Tested-by: gerrit-photon <photon-checkins@vmware.com>
Reviewed-by: Anish Swaminathan <anishs@vmware.com>

Kumar Kaushik authored on 2017/04/08 09:21:57
Showing 3 changed files
... ...
@@ -1,9 +1,8 @@
1
-diff -ru open-vm-tools-stable-10.1.5/open-vm-tools/libDeployPkg/linuxDeployment.c open-vm-tools-stable-10.1.5-modified/open-vm-tools/libDeployPkg/linuxDeployment.c
2
-+++ open-vm-tools-stable-10.1.5-modified/open-vm-tools/libDeployPkg/linuxDeployment.c	2017-03-03 15:55:49.921709009 -0800
3
-@@ -558,13 +558,17 @@
1
+--- open-vm-tools-10.1.5-5055683/libDeployPkg/linuxDeployment.c 2017-04-06 19:19:36.000010000 -0700
2
+@@ -580,13 +580,17 @@
4 3
     close(fd);
5
- 
4
+
6 5
     // Create space and copy the command
7 6
 -   *command = malloc(VMWAREDEPLOYPKG_CMD_LENGTH);
8 7
 +   *command = malloc(VMWAREDEPLOYPKG_CMD_LENGTH + 1);
... ...
@@ -11,7 +10,7 @@ diff -ru open-vm-tools-stable-10.1.5/open-vm-tools/libDeployPkg/linuxDeployment.
11 11
        SetDeployError("Error allocating memory.");
12 12
        return FALSE;
13 13
     }
14
- 
14
+
15 15
 -   memcpy(*command, hdr.command, VMWAREDEPLOYPKG_CMD_LENGTH);
16 16
 +   // will pad with '\0' if necessary
17 17
 +   strncpy(*command, hdr.command, VMWAREDEPLOYPKG_CMD_LENGTH);
... ...
@@ -20,23 +19,24 @@ diff -ru open-vm-tools-stable-10.1.5/open-vm-tools/libDeployPkg/linuxDeployment.
20 20
 +
21 21
     *archiveType = hdr.payloadType;
22 22
     *flags = hdr.reserved;
23
- 
24
-@@ -1042,6 +1046,18 @@
23
+
24
+@@ -1074,6 +1078,20 @@
25 25
        free(command);
26
-       deployStatus =  CloudInitSetup(EXTRACTPATH);
26
+       deployStatus =  CloudInitSetup(tmpDirPath);
27 27
     } else {
28 28
 +      if ((strstr(command, "scripts/Customize.pl") != NULL) || (strstr(command, "scripts/customize.sh") != NULL)) {
29 29
 +          free (command);
30 30
 +          const char* PHOTON_OS_LAUNCH_COMMAND = "/bin/bash /usr/share/open-vm-tools/GOSC/gosc-scripts/imc-shell/imgcust-scripts/customize.sh /tmp/.vmware/linux/deploy/cust.cfg";
31 31
 +
32 32
 +          // The command will be parsed alter and can be of arbitrary length
33
-+          command = strdup(PHOTON_OS_LAUNCH_COMMAND);
33
++          command = StrUtil_ReplaceAll(PHOTON_OS_LAUNCH_COMMAND, TMP_PATH_VAR, tmpDirPath);
34 34
 +          if (!command) {
35 35
 +             SetDeployError("Error allocating memory.");
36 36
 +             return DEPLOY_ERROR;
37 37
 +          }
38 38
 +          _DeployPkg_SkipReboot(true);
39 39
 +      }
40
-       // Run the deployment command
41
-       sLog(log_info, "Launching deployment %s.  \n", command);
40
++      // Run the deployment command
41
++      sLog(log_info, "Launching deployment %s.  \n", command);
42 42
        deploymentResult = ForkExecAndWaitCommand(command);
43
+       free(command);
43 44
new file mode 100755
... ...
@@ -0,0 +1,267 @@
0
+--- libDeployPkg/linuxDeployment.c	2016-10-11 14:08:49.000079000 -0400
1
+@@ -43,6 +43,8 @@
2
+ #include "mspackWrapper.h"
3
+ #include "rpcout.h"
4
+ #include "toolsDeployPkg.h"
5
++#include <strutil.h>
6
++#include <util.h>
7
+ 
8
+ /*
9
+  * These are covered by #ifndef to give the ability to change these
10
+@@ -52,12 +54,17 @@
11
+ 
12
+ #define CLEANUPCMD  "/bin/rm -r -f "
13
+ 
14
+-#ifndef EXTRACTPATH
15
+-#define EXTRACTPATH "/tmp/.vmware/linux/deploy"
16
++#ifndef TMP_PATH_VAR
17
++#define TMP_PATH_VAR "/tmp/.vmware/linux/deploy"
18
+ #endif
19
+ 
20
+-#ifndef CLEANUPPATH
21
+-#define CLEANUPPATH "/tmp/.vmware"
22
++#ifndef IMC_TMP_PATH_VAR
23
++#define IMC_TMP_PATH_VAR "@@IMC_TMP_PATH_VAR@@"
24
++#endif
25
++
26
++// '/tmp' below will be addressed by PR 1601405.
27
++#ifndef TMP_DIR_PATH_PATTERN
28
++#define TMP_DIR_PATH_PATTERN "/tmp/.vmware-imgcust-dXXXXXX"
29
+ #endif
30
+ 
31
+ #ifndef BASEFILENAME
32
+@@ -115,7 +122,6 @@
33
+ // Private functions
34
+ static Bool GetPackageInfo(const char* pkgName, char** cmd, uint8* type, uint8* flags);
35
+ static Bool ExtractZipPackage(const char* pkg, const char* dest);
36
+-static Bool CreateDir(const char *path);
37
+ static void Init(void);
38
+ static struct List* AddToList(struct List* head, const char* token);
39
+ static int ListSize(struct List* head);
40
+@@ -151,8 +157,17 @@
41
+ NORETURN void
42
+ Panic(const char *fmtstr, ...)
43
+ {
44
+-   /* Ignored */
45
+-   sLog(log_warning, "Panic callback invoked. \n");
46
++   va_list args;
47
++
48
++   char *tmp = Util_SafeMalloc(MAXSTRING);
49
++
50
++   va_start(args, fmtstr);
51
++   vsprintf(tmp, fmtstr, args);
52
++
53
++   sLog(log_error, "Panic callback invoked: %s\n", tmp);
54
++
55
++   free(tmp);
56
++
57
+    exit(1);
58
+ }
59
+ 
60
+@@ -169,12 +184,19 @@
61
+  *
62
+  **/
63
+ void
64
+-Debug(const char *fmtstr,
65
+-      va_list args)
66
++Debug(const char *fmtstr, ...)
67
+ {
68
+-   /* Ignored */
69
+ #ifdef VMX86_DEBUG
70
+-   sLog(log_warning, "Debug callback invoked. \n");
71
++   va_list args;
72
++
73
++   char *tmp = Util_SafeMalloc(MAXSTRING);
74
++
75
++   va_start(args, fmtstr);
76
++   vsprintf(tmp, fmtstr, args);
77
++
78
++   sLog(log_debug, "Debug callback invoked: %s\n", tmp);
79
++
80
++   free(tmp);
81
+ #endif
82
+ }
83
+ 
84
+@@ -979,6 +1001,7 @@
85
+ Deploy(const char* packageName)
86
+ {
87
+    int deployStatus = DEPLOY_SUCCESS;
88
++   char* pkgCommand = NULL;
89
+    char* command = NULL;
90
+    int deploymentResult = 0;
91
+    char *nics;
92
+@@ -986,6 +1009,7 @@
93
+    uint8 archiveType;
94
+    uint8 flags;
95
+    bool forceSkipReboot = false;
96
++   char *tmpDirPath;
97
+    Bool cloudInitEnabled = FALSE;
98
+    const char *cloudInitConfigFilePath = "/etc/cloud/cloud.cfg";
99
+    char cloudCommand[1024];
100
+@@ -998,33 +1022,41 @@
101
+                                TOOLSDEPLOYPKG_ERROR_SUCCESS,
102
+                                NULL);
103
+ 
104
++   tmpDirPath = mkdtemp((char *)Util_SafeStrdup(TMP_DIR_PATH_PATTERN));
105
++   if (tmpDirPath == NULL) {
106
++      SetDeployError("Error creating tmp dir: %s", strerror(errno));
107
++      return DEPLOY_ERROR;
108
++   }
109
++
110
+    sLog(log_info, "Reading cabinet file %s. \n", packageName);
111
+ 
112
+    // Get the command to execute
113
+-   if (!GetPackageInfo(packageName, &command, &archiveType, &flags)) {
114
++   if (!GetPackageInfo(packageName, &pkgCommand, &archiveType, &flags)) {
115
+       SetDeployError("Error extracting package header information. (%s)",
116
+                      GetDeployError());
117
++      free(tmpDirPath);
118
+       return DEPLOY_ERROR;
119
+    }
120
+ 
121
+-   // Print the header command
122
+-#ifdef VMX86_DEBUG
123
+-   sLog(log_debug, "Header command: %s \n ", command);
124
+-#endif
125
+-
126
+-   // create the destination directory
127
+-   if (!CreateDir(EXTRACTPATH "/")) {
128
+-      free(command);
129
+-      return DEPLOY_ERROR;
130
++   sLog(log_info, "Original deployment command: %s\n", pkgCommand);
131
++   if (strstr(pkgCommand, IMC_TMP_PATH_VAR) != NULL) {
132
++      command = StrUtil_ReplaceAll(pkgCommand, IMC_TMP_PATH_VAR, tmpDirPath);
133
++   } else {
134
++      command = StrUtil_ReplaceAll(pkgCommand, TMP_PATH_VAR, tmpDirPath);
135
+    }
136
++   free(pkgCommand);
137
++
138
++   sLog(log_info, "Actual deployment command: %s\n", command);
139
+ 
140
+    if (archiveType == VMWAREDEPLOYPKG_PAYLOAD_TYPE_CAB) {
141
+-      if (!ExtractCabPackage(packageName, EXTRACTPATH)) {
142
++      if (!ExtractCabPackage(packageName, tmpDirPath)) {
143
++         free(tmpDirPath);
144
+          free(command);
145
+          return DEPLOY_ERROR;
146
+       }
147
+    } else if (archiveType == VMWAREDEPLOYPKG_PAYLOAD_TYPE_ZIP) {
148
+-      if (!ExtractZipPackage(packageName, EXTRACTPATH)) {
149
++      if (!ExtractZipPackage(packageName, tmpDirPath)) {
150
++         free(tmpDirPath);
151
+          free(command);
152
+          return DEPLOY_ERROR;
153
+       }
154
+@@ -1040,10 +1072,8 @@
155
+       cloudInitEnabled = TRUE;
156
+       sSkipReboot = TRUE;
157
+       free(command);
158
+-      deployStatus =  CloudInitSetup(EXTRACTPATH);
159
++      deployStatus =  CloudInitSetup(tmpDirPath);
160
+    } else {
161
+-      // Run the deployment command
162
+-      sLog(log_info, "Launching deployment %s.  \n", command);
163
+       deploymentResult = ForkExecAndWaitCommand(command);
164
+       free(command);
165
+ 
166
+@@ -1089,7 +1119,7 @@
167
+        * of the sucess/failure of the customization so that at the end of it we
168
+        * always have nics enabled.
169
+        */
170
+-      nics = GetNicsToEnable(EXTRACTPATH);
171
++      nics = GetNicsToEnable(tmpDirPath);
172
+       if (nics) {
173
+          // XXX: Sleep before the last SetCustomizationStatusInVmx
174
+          //      This is a temporary-hack for PR 422790
175
+@@ -1104,22 +1134,23 @@
176
+       }
177
+    }
178
+ 
179
+-   cleanupCommand = malloc(strlen(CLEANUPCMD) + strlen(CLEANUPPATH) + 1);
180
++   cleanupCommand = malloc(strlen(CLEANUPCMD) + strlen(tmpDirPath) + 1);
181
+    if (!cleanupCommand) {
182
+       SetDeployError("Error allocating memory.");
183
++      free(tmpDirPath);
184
+       return DEPLOY_ERROR;
185
+    }
186
+ 
187
+    strcpy(cleanupCommand, CLEANUPCMD);
188
+-   strcat(cleanupCommand, CLEANUPPATH);
189
++   strcat(cleanupCommand, tmpDirPath);
190
+ 
191
+    sLog(log_info, "Launching cleanup. \n");
192
+    if (ForkExecAndWaitCommand(cleanupCommand) != 0) {
193
+-      sLog(log_warning, "Error while clean up. Error removing directory %s. (%s)",
194
+-           EXTRACTPATH, strerror (errno));
195
+-      //TODO: What should be done if cleanup fails ??
196
++      sLog(log_warning, "Error while clean up tmp directory %s: (%s)",
197
++           tmpDirPath, strerror (errno));
198
+    }
199
+    free (cleanupCommand);
200
++   free(tmpDirPath);
201
+ 
202
+    if (flags & VMWAREDEPLOYPKG_HEADER_FLAGS_SKIP_REBOOT) {
203
+       forceSkipReboot = true;
204
+@@ -1388,61 +1419,6 @@
205
+    return retval;
206
+ }
207
+ 
208
+-/**
209
+- * Sets up the path for exracting file. For e.g. if the file is /a/b/c/d.abc
210
+- * then it creates /a/b/c (skips if any of the directories along the path
211
+- * exists). If the the path ends in '/', then the the entire input is assumed
212
+- * to be a directory and is created as such.
213
+- *
214
+- * @param path  IN: Complete path of the file
215
+- * @return TRUE on success
216
+- */
217
+-
218
+-Bool
219
+-CreateDir(const char* path)
220
+-{
221
+-   struct stat stats;
222
+-   char* token;
223
+-   char* copy;
224
+-
225
+-   // make a copy we can modify
226
+-   copy = strdup(path);
227
+-
228
+-   // walk through the path (it employs in string replacement)
229
+-   for (token = copy + 1; *token; ++token) {
230
+-
231
+-      // find
232
+-      if (*token != '/') {
233
+-         continue;
234
+-      }
235
+-
236
+-      /*
237
+-       * cut it off here for e.g. on first iteration /a/b/c/d.abc will have
238
+-       * token /a, on second /a/b etc
239
+-       */
240
+-      *token = 0;
241
+-
242
+-      sLog(log_debug, "Creating directory %s", copy);
243
+-
244
+-      // ignore if the directory exists
245
+-      if (!((stat(copy, &stats) == 0) && S_ISDIR(stats.st_mode))) {
246
+-         // make directory and check error (accessible only by owner)
247
+-         if (mkdir(copy, 0700) == -1) {
248
+-            sLog(log_error, "Unable to create directory %s (%s)", copy,
249
+-                 strerror(errno));
250
+-            free(copy);
251
+-            return FALSE;
252
+-         }
253
+-      }
254
+-
255
+-      // restore the token
256
+-      *token = '/';
257
+-   }
258
+-
259
+-   free(copy);
260
+-   return TRUE;
261
+-}
262
+-
263
+ //......................................................................................
264
+ 
265
+ /**
... ...
@@ -1,7 +1,7 @@
1 1
 Summary:        Usermode tools for VmWare virts
2 2
 Name:           open-vm-tools
3 3
 Version:        10.1.5
4
-Release:        2%{?dist}
4
+Release:        3%{?dist}
5 5
 License:        LGPLv2+
6 6
 URL:            https://github.com/vmware/open-vm-tools
7 7
 Group:          Applications/System
... ...
@@ -13,11 +13,12 @@ Source1:        gosc-scripts-1.0.tar.gz
13 13
 %define sha1 gosc-scripts-1.0=5031dd9b3b0569a40d2ee0caaa55a1cbf782345e
14 14
 Source2:        vmtoolsd.service
15 15
 Source3:        vgauthd.service
16
-Patch0:         GOSC-libDeploy.patch
16
+Patch0:         open-vm-tools-tmp-race.patch
17 17
 Patch1:         IPv6Support.patch
18 18
 Patch2:         hostnameReCustomizationFix.patch
19 19
 Patch3:         PureIPv6-hosts.patch
20 20
 Patch4:         open-vm-tools-sysmacros.patch
21
+Patch5:         GOSC-libDeploy.patch
21 22
 BuildRequires:  glib-devel
22 23
 BuildRequires:  xerces-c-devel
23 24
 BuildRequires:  xml-security-c-devel
... ...
@@ -41,11 +42,12 @@ VmWare virtualization user mode tools
41 41
 %prep
42 42
 %setup -q -n %{name}-stable-%{version}/%{name}
43 43
 %setup -a 1 -n %{name}-stable-%{version}/%{name}
44
-%patch0 -p2
44
+%patch0 -p0
45 45
 %patch1 -p0
46 46
 %patch2 -p0
47 47
 %patch3 -p0
48 48
 %patch4 -p1
49
+%patch5 -p1
49 50
 %build
50 51
 touch ChangeLog
51 52
 autoreconf -i
... ...
@@ -103,26 +105,28 @@ fi
103 103
 
104 104
 
105 105
 %changelog
106
-*   Fri Mar 24 2017 Alexey Makhalov <amakhalov@vmware.com> 10.1.5-2
107
--   Added *-sysmacros.patch to fix build issue with glibc-2.25
108
-*   Fri Mar 03 2017 Kumar Kaushik <kaushikk@vmware.com> 10.1.5-1
109
--   Updating version to 10.1.5
110
-*   Wed Dec 07 2016 Xiaolin Li <xiaolinl@vmware.com> 10.1.0-2
111
--   BuildRequires Linux-PAM-devel
112
-*   Mon Nov 21 2016 Kumar Kaushik <kaushikk@vmware.com> 10.1.0-1
113
--   Updating version to 10.1.0
114
-*   Wed Oct 05 2016 Kumar Kaushik <kaushikk@vmware.com> 10.0.5-14
115
--   Adding proper entry to /etc/hosts for IPv6.
116
-*   Tue Oct 04 2016 ChangLee <changLee@vmware.com> 10.0.5-13
117
--   Modified %check
118
-*   Thu Jun 23 2016 Kumar Kaushik <kaushikk@vmware.com> 10.0.5-12
119
--   Avoiding recustomization of hostname, bug#1678537.
120
-*   Mon Jun 13 2016 Kumar Kaushik <kaushikk@vmware.com> 10.0.5-11
121
--   Adding IPv6 Support for VCHA in customization.
122
-*   Tue May 24 2016 Priyesh Padmavilasom <ppadmavilasom@vmware.com> 10.0.5-10
123
--   GA - Bump release of all rpms
124
-*   Wed May 04 2016 Anish Swaminathan <anishs@vmware.com> 10.0.5-9
125
--   Edit scriptlets.
106
+*       Fri Apr 07 2017 Kumar Kaushik <kaushikk@vmware.com> 10.1.5-3
107
+-       Applying tmp race condition patch, PR #1733669
108
+*       Fri Mar 24 2017 Alexey Makhalov <amakhalov@vmware.com> 10.1.5-2
109
+-       Added *-sysmacros.patch to fix build issue with glibc-2.25
110
+*       Fri Mar 03 2017 Kumar Kaushik <kaushikk@vmware.com> 10.1.5-1
111
+-       Updating version to 10.1.5
112
+*       Wed Dec 07 2016 Xiaolin Li <xiaolinl@vmware.com> 10.1.0-2
113
+-       BuildRequires Linux-PAM-devel
114
+*       Mon Nov 21 2016 Kumar Kaushik <kaushikk@vmware.com> 10.1.0-1
115
+-       Updating version to 10.1.0
116
+*       Wed Oct 05 2016 Kumar Kaushik <kaushikk@vmware.com> 10.0.5-14
117
+-       Adding proper entry to /etc/hosts for IPv6.
118
+*       Tue Oct 04 2016 ChangLee <changLee@vmware.com> 10.0.5-13
119
+-       Modified %check
120
+*       Thu Jun 23 2016 Kumar Kaushik <kaushikk@vmware.com> 10.0.5-12
121
+-       Avoiding recustomization of hostname, bug#1678537.
122
+*       Mon Jun 13 2016 Kumar Kaushik <kaushikk@vmware.com> 10.0.5-11
123
+-       Adding IPv6 Support for VCHA in customization.
124
+*       Tue May 24 2016 Priyesh Padmavilasom <ppadmavilasom@vmware.com> 10.0.5-10
125
+-       GA - Bump release of all rpms
126
+*       Wed May 04 2016 Anish Swaminathan <anishs@vmware.com> 10.0.5-9
127
+-       Edit scriptlets.
126 128
 *       Fri Apr 29 2016 Kumar Kaushik <kaushikk@vmware.com> 10.0.5-8
127 129
 -       Combining all GOSC scripts patches and fixing bug#1648133.
128 130
 *       Tue Apr 19 2016 Kumar Kaushik <kaushikk@vmware.com> 10.0.5-7