--- Begin Message ---
- To: Debian Bug Tracking System <submit@bugs.debian.org>
- Subject: stretch-pu: package open-vm-tools/2:10.1.5-5055683-4+deb9u1
- From: Bernd Zeimetz <bzed@debian.org>
- Date: Tue, 25 Jul 2017 14:23:26 +0200
- Message-id: <150098540650.12868.12590379653329561665.reportbug@think.wals.bzed.at>
Package: release.debian.org
Severity: normal
Tags: stretch
User: release.debian.org@packages.debian.org
Usertags: pu
Hi release team,
as discussed in #869633 I'd like to fix CVE-2015-5191 in
open-vm-tools with the next stretch pointrelease.
A debdiff is attached, I'll upload it to stable(-pu) as
soon as I have an ack from you.
Thanks,
Bernd
--
Bernd Zeimetz Debian GNU/Linux Developer
http://bzed.de http://www.debian.org
GPG Fingerprint: ECA1 E3F2 8E11 2432 D485 DD95 EB36 171A 6FF9 435F
diff --git a/debian/changelog b/debian/changelog
index 97fd671f..4bac2108 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,10 @@
+open-vm-tools (2:10.1.5-5055683-4+deb9u1) stable; urgency=medium
+
+ * [dec8df6] Upstream fix for CVE-2015-5191 (Closes: #869633)
+ * [ff10dcb] Update gbp.conf for stretch.
+
+ -- Bernd Zeimetz <bzed@debian.org> Tue, 25 Jul 2017 11:40:02 +0200
+
open-vm-tools (2:10.1.5-5055683-4) unstable; urgency=medium
* [27689b3] Load the fuse module before mounting /run/vmblock-fuse.
diff --git a/debian/gbp.conf b/debian/gbp.conf
index bf4163e8..64996533 100644
--- a/debian/gbp.conf
+++ b/debian/gbp.conf
@@ -1,3 +1,5 @@
+[DEFAULT]
+debian-branch = stretch
[buildpackage]
sign-tags = True
posttag = git push && git push --tags
diff --git a/debian/patches/debian/cve-2015-5191.patch b/debian/patches/debian/cve-2015-5191.patch
new file mode 100644
index 00000000..3312be08
--- /dev/null
+++ b/debian/patches/debian/cve-2015-5191.patch
@@ -0,0 +1,413 @@
+commit 22e58289f71232310d30cf162b83b5151a937bac
+Author: Oliver Kurth <okurth@vmware.com>
+Date: Thu Jul 6 17:00:55 2017 -0700
+
+ randomly generate tmp directory name
+
+diff --git a/open-vm-tools/libDeployPkg/linuxDeployment.c b/open-vm-tools/libDeployPkg/linuxDeployment.c
+index 1c8f7855..8e536a97 100644
+--- a/open-vm-tools/libDeployPkg/linuxDeployment.c
++++ b/open-vm-tools/libDeployPkg/linuxDeployment.c
+@@ -43,6 +43,8 @@
+ #include "mspackWrapper.h"
+ #include "rpcout.h"
+ #include "toolsDeployPkg.h"
++#include <strutil.h>
++#include <util.h>
+
+ /*
+ * These are covered by #ifndef to give the ability to change these
+@@ -52,12 +54,17 @@
+
+ #define CLEANUPCMD "/bin/rm -r -f "
+
+-#ifndef EXTRACTPATH
+-#define EXTRACTPATH "/tmp/.vmware/linux/deploy"
++#ifndef TMP_PATH_VAR
++#define TMP_PATH_VAR "/tmp/.vmware/linux/deploy"
+ #endif
+
+-#ifndef CLEANUPPATH
+-#define CLEANUPPATH "/tmp/.vmware"
++#ifndef IMC_TMP_PATH_VAR
++#define IMC_TMP_PATH_VAR "@@IMC_TMP_PATH_VAR@@"
++#endif
++
++// '/tmp' below will be addressed by PR 1601405.
++#ifndef TMP_DIR_PATH_PATTERN
++#define TMP_DIR_PATH_PATTERN "/tmp/.vmware-imgcust-dXXXXXX"
+ #endif
+
+ #ifndef BASEFILENAME
+@@ -115,13 +122,14 @@ struct List {
+ // Private functions
+ static Bool GetPackageInfo(const char* pkgName, char** cmd, uint8* type, uint8* flags);
+ static Bool ExtractZipPackage(const char* pkg, const char* dest);
+-static Bool CreateDir(const char *path);
+ static void Init(void);
+ static struct List* AddToList(struct List* head, const char* token);
+ static int ListSize(struct List* head);
+ static int Touch(const char* state);
+ static int UnTouch(const char* state);
+ static int TransitionState(const char* stateFrom, const char* stateTo);
++static bool CopyFileToDirectory(const char* srcPath, const char* destPath,
++ const char* fileName);
+ static int Deploy(const char* pkgName);
+ static char** GetFormattedCommandLine(const char* command);
+ static int ForkExecAndWaitCommand(const char* command);
+@@ -151,8 +159,17 @@ static LogFunction sLog = NoLogging;
+ NORETURN void
+ Panic(const char *fmtstr, ...)
+ {
+- /* Ignored */
+- sLog(log_warning, "Panic callback invoked. \n");
++ va_list args;
++
++ char *tmp = Util_SafeMalloc(MAXSTRING);
++
++ va_start(args, fmtstr);
++ vsprintf(tmp, fmtstr, args);
++
++ sLog(log_error, "Panic callback invoked: %s\n", tmp);
++
++ free(tmp);
++
+ exit(1);
+ }
+
+@@ -169,12 +186,19 @@ Panic(const char *fmtstr, ...)
+ *
+ **/
+ void
+-Debug(const char *fmtstr,
+- va_list args)
++Debug(const char *fmtstr, ...)
+ {
+- /* Ignored */
+ #ifdef VMX86_DEBUG
+- sLog(log_warning, "Debug callback invoked. \n");
++ va_list args;
++
++ char *tmp = Util_SafeMalloc(MAXSTRING);
++
++ va_start(args, fmtstr);
++ vsprintf(tmp, fmtstr, args);
++
++ sLog(log_debug, "Debug callback invoked: %s\n", tmp);
++
++ free(tmp);
+ #endif
+ }
+
+@@ -874,11 +898,13 @@ static int
+ CloudInitSetup(const char *tmpDirPath)
+ {
+ int deployStatus = DEPLOY_ERROR;
+- const char *cloudInitTmpDirPath = "/var/run/vmware-imc";
++ static const char *cloudInitTmpDirPath = "/var/run/vmware-imc";
+ int forkExecResult;
+ char command[1024];
+ Bool cloudInitTmpDirCreated = FALSE;
+
++ sLog(log_info, "Creating temp directory %s to copy customization files",
++ cloudInitTmpDirPath);
+ snprintf(command, sizeof(command),
+ "/bin/mkdir -p %s", cloudInitTmpDirPath);
+ command[sizeof(command) - 1] = '\0';
+@@ -893,26 +919,9 @@ CloudInitSetup(const char *tmpDirPath)
+
+ cloudInitTmpDirCreated = TRUE;
+
+- snprintf(command, sizeof(command),
+- "/bin/rm -f %s/cust.cfg %s/nics.txt",
+- cloudInitTmpDirPath, cloudInitTmpDirPath);
+- command[sizeof(command) - 1] = '\0';
+-
+- forkExecResult = ForkExecAndWaitCommand(command);
+-
+- snprintf(command, sizeof(command),
+- "/bin/cp %s/cust.cfg %s/cust.cfg",
+- tmpDirPath, cloudInitTmpDirPath);
+- command[sizeof(command) - 1] = '\0';
+-
+- forkExecResult = ForkExecAndWaitCommand(command);
+-
+- if (forkExecResult != 0) {
+- SetDeployError("Error copying cust.cfg file: %s",
+- strerror(errno));
+- goto done;
+- }
+-
++ // Copy required files for cloud-init to a temp name initially and then
++ // rename in order to avoid race conditions with partial writes.
++ sLog(log_info, "Check if nics.txt exists. Copy if exists, skip otherwise");
+ snprintf(command, sizeof(command),
+ "/usr/bin/test -f %s/nics.txt", tmpDirPath);
+ command[sizeof(command) - 1] = '\0';
+@@ -925,26 +934,27 @@ CloudInitSetup(const char *tmpDirPath)
+ * We need to copy the nics.txt only if it exists.
+ */
+ if (forkExecResult == 0) {
+- snprintf(command, sizeof(command),
+- "/bin/cp %s/nics.txt %s/nics.txt",
+- tmpDirPath, cloudInitTmpDirPath);
+- command[sizeof(command) - 1] = '\0';
+-
+- forkExecResult = ForkExecAndWaitCommand(command);
+- if (forkExecResult != 0) {
+- SetDeployError("Error copying nics.txt file: %s",
+- strerror(errno));
++ sLog(log_info, "nics.txt file exists. Copying..");
++ if(!CopyFileToDirectory(tmpDirPath, cloudInitTmpDirPath, "nics.txt")) {
+ goto done;
+- }
++ }
++ }
++
++ sLog(log_info, "Copying main configuration file cust.cfg");
++ if(!CopyFileToDirectory(tmpDirPath, cloudInitTmpDirPath, "cust.cfg")) {
++ goto done;
+ }
+
+ deployStatus = DEPLOY_SUCCESS;
+
+ done:
+ if (DEPLOY_SUCCESS == deployStatus) {
++ sLog(log_info, "Deployment for cloud-init succeeded.");
+ TransitionState(INPROGRESS, DONE);
+ } else {
++ sLog(log_error, "Deployment for cloud-init failed.");
+ if (cloudInitTmpDirCreated) {
++ sLog(log_info, "Removing temporary folder %s", cloudInitTmpDirPath);
+ snprintf(command, sizeof(command),
+ "/bin/rm -rf %s",
+ cloudInitTmpDirPath);
+@@ -964,6 +974,34 @@ done:
+
+ //......................................................................................
+
++static bool
++CopyFileToDirectory(const char* srcPath, const char* destPath,
++ const char* fileName)
++{
++ char command[1024];
++ int forkExecResult;
++ snprintf(command, sizeof(command), "/bin/cp %s/%s %s/%s.tmp", srcPath,
++ fileName, destPath, fileName);
++ command[sizeof(command) - 1] = '\0';
++ forkExecResult = ForkExecAndWaitCommand(command);
++ if (forkExecResult != 0) {
++ SetDeployError("Error while copying file %s: %s", fileName,
++ strerror(errno));
++ return false;
++ }
++ snprintf(command, sizeof(command), "/bin/mv -f %s/%s.tmp %s/%s", destPath,
++ fileName, destPath, fileName);
++ command[sizeof(command) - 1] = '\0';
++
++ forkExecResult = ForkExecAndWaitCommand(command);
++ if (forkExecResult != 0) {
++ SetDeployError("Error while renaming temp file %s: %s", fileName,
++ strerror(errno));
++ return false;
++ }
++ return true;
++}
++
+ /**
+ *
+ * Core function which takes care of deployment in Linux.
+@@ -979,6 +1017,7 @@ static int
+ Deploy(const char* packageName)
+ {
+ int deployStatus = DEPLOY_SUCCESS;
++ char* pkgCommand = NULL;
+ char* command = NULL;
+ int deploymentResult = 0;
+ char *nics;
+@@ -986,6 +1025,7 @@ Deploy(const char* packageName)
+ uint8 archiveType;
+ uint8 flags;
+ bool forceSkipReboot = false;
++ char *tmpDirPath;
+ Bool cloudInitEnabled = FALSE;
+ const char *cloudInitConfigFilePath = "/etc/cloud/cloud.cfg";
+ char cloudCommand[1024];
+@@ -998,52 +1038,62 @@ Deploy(const char* packageName)
+ TOOLSDEPLOYPKG_ERROR_SUCCESS,
+ NULL);
+
++ tmpDirPath = mkdtemp((char *)Util_SafeStrdup(TMP_DIR_PATH_PATTERN));
++ if (tmpDirPath == NULL) {
++ SetDeployError("Error creating tmp dir: %s", strerror(errno));
++ return DEPLOY_ERROR;
++ }
++
+ sLog(log_info, "Reading cabinet file %s. \n", packageName);
+
+ // Get the command to execute
+- if (!GetPackageInfo(packageName, &command, &archiveType, &flags)) {
++ if (!GetPackageInfo(packageName, &pkgCommand, &archiveType, &flags)) {
+ SetDeployError("Error extracting package header information. (%s)",
+ GetDeployError());
++ free(tmpDirPath);
+ return DEPLOY_ERROR;
+ }
+
+- // Print the header command
+-#ifdef VMX86_DEBUG
+- sLog(log_debug, "Header command: %s \n ", command);
+-#endif
+-
+- // create the destination directory
+- if (!CreateDir(EXTRACTPATH "/")) {
+- free(command);
+- return DEPLOY_ERROR;
++ sLog(log_info, "Original deployment command: %s\n", pkgCommand);
++ if (strstr(pkgCommand, IMC_TMP_PATH_VAR) != NULL) {
++ command = StrUtil_ReplaceAll(pkgCommand, IMC_TMP_PATH_VAR, tmpDirPath);
++ } else {
++ command = StrUtil_ReplaceAll(pkgCommand, TMP_PATH_VAR, tmpDirPath);
+ }
++ free(pkgCommand);
++
++ sLog(log_info, "Actual deployment command: %s\n", command);
+
+ if (archiveType == VMWAREDEPLOYPKG_PAYLOAD_TYPE_CAB) {
+- if (!ExtractCabPackage(packageName, EXTRACTPATH)) {
++ if (!ExtractCabPackage(packageName, tmpDirPath)) {
++ free(tmpDirPath);
+ free(command);
+ return DEPLOY_ERROR;
+ }
+ } else if (archiveType == VMWAREDEPLOYPKG_PAYLOAD_TYPE_ZIP) {
+- if (!ExtractZipPackage(packageName, EXTRACTPATH)) {
++ if (!ExtractZipPackage(packageName, tmpDirPath)) {
++ free(tmpDirPath);
+ free(command);
+ return DEPLOY_ERROR;
+ }
+ }
+
+ // check if cloud-init installed
++ sLog(log_info, "Checking if cloud-init is installed");
+ snprintf(cloudCommand, sizeof(cloudCommand),
+ "/usr/bin/cloud-init -h");
+ cloudCommand[sizeof(cloudCommand) - 1] = '\0';
+ forkExecResult = ForkExecAndWaitCommand(cloudCommand);
+ // if cloud-init is installed, check if it is enabled
+ if (forkExecResult == 0 && IsCloudInitEnabled(cloudInitConfigFilePath)) {
++ sLog(log_info, "cloud-init is installed and enabled");
+ cloudInitEnabled = TRUE;
+ sSkipReboot = TRUE;
+ free(command);
+- deployStatus = CloudInitSetup(EXTRACTPATH);
++ deployStatus = CloudInitSetup(tmpDirPath);
+ } else {
+- // Run the deployment command
+- sLog(log_info, "Launching deployment %s. \n", command);
++ sLog(log_info, "cloud-init is either not installed or the flag to enable \
++ cloud-init is not set.\n Executing traditional GOSC workflow");
+ deploymentResult = ForkExecAndWaitCommand(command);
+ free(command);
+
+@@ -1089,7 +1139,7 @@ Deploy(const char* packageName)
+ * of the sucess/failure of the customization so that at the end of it we
+ * always have nics enabled.
+ */
+- nics = GetNicsToEnable(EXTRACTPATH);
++ nics = GetNicsToEnable(tmpDirPath);
+ if (nics) {
+ // XXX: Sleep before the last SetCustomizationStatusInVmx
+ // This is a temporary-hack for PR 422790
+@@ -1104,22 +1154,23 @@ Deploy(const char* packageName)
+ }
+ }
+
+- cleanupCommand = malloc(strlen(CLEANUPCMD) + strlen(CLEANUPPATH) + 1);
++ cleanupCommand = malloc(strlen(CLEANUPCMD) + strlen(tmpDirPath) + 1);
+ if (!cleanupCommand) {
+ SetDeployError("Error allocating memory.");
++ free(tmpDirPath);
+ return DEPLOY_ERROR;
+ }
+
+ strcpy(cleanupCommand, CLEANUPCMD);
+- strcat(cleanupCommand, CLEANUPPATH);
++ strcat(cleanupCommand, tmpDirPath);
+
+ sLog(log_info, "Launching cleanup. \n");
+ if (ForkExecAndWaitCommand(cleanupCommand) != 0) {
+- sLog(log_warning, "Error while clean up. Error removing directory %s. (%s)",
+- EXTRACTPATH, strerror (errno));
+- //TODO: What should be done if cleanup fails ??
++ sLog(log_warning, "Error while clean up tmp directory %s: (%s)",
++ tmpDirPath, strerror (errno));
+ }
+ free (cleanupCommand);
++ free(tmpDirPath);
+
+ if (flags & VMWAREDEPLOYPKG_HEADER_FLAGS_SKIP_REBOOT) {
+ forceSkipReboot = true;
+@@ -1388,61 +1439,6 @@ ForkExecAndWaitCommand(const char* command)
+ return retval;
+ }
+
+-/**
+- * Sets up the path for exracting file. For e.g. if the file is /a/b/c/d.abc
+- * then it creates /a/b/c (skips if any of the directories along the path
+- * exists). If the the path ends in '/', then the the entire input is assumed
+- * to be a directory and is created as such.
+- *
+- * @param path IN: Complete path of the file
+- * @return TRUE on success
+- */
+-
+-Bool
+-CreateDir(const char* path)
+-{
+- struct stat stats;
+- char* token;
+- char* copy;
+-
+- // make a copy we can modify
+- copy = strdup(path);
+-
+- // walk through the path (it employs in string replacement)
+- for (token = copy + 1; *token; ++token) {
+-
+- // find
+- if (*token != '/') {
+- continue;
+- }
+-
+- /*
+- * cut it off here for e.g. on first iteration /a/b/c/d.abc will have
+- * token /a, on second /a/b etc
+- */
+- *token = 0;
+-
+- sLog(log_debug, "Creating directory %s", copy);
+-
+- // ignore if the directory exists
+- if (!((stat(copy, &stats) == 0) && S_ISDIR(stats.st_mode))) {
+- // make directory and check error (accessible only by owner)
+- if (mkdir(copy, 0700) == -1) {
+- sLog(log_error, "Unable to create directory %s (%s)", copy,
+- strerror(errno));
+- free(copy);
+- return FALSE;
+- }
+- }
+-
+- // restore the token
+- *token = '/';
+- }
+-
+- free(copy);
+- return TRUE;
+-}
+-
+ //......................................................................................
+
+ /**
diff --git a/debian/patches/series b/debian/patches/series
index a0c9a7b4..2c8fbff7 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -4,3 +4,4 @@ debian/max_nic_count
from_arch/0001-Fix-vmxnet-module-on-kernels-3.16.patch
debian/enable_vmhgfs-fuse_by_default
debian/vmxnet_fix_kernel_4.7.patch
+debian/cve-2015-5191.patch
--- End Message ---