- File descriptor vulnerability in the open-vm-tools

vmware-user-suid-wrapperx on Linux
- Don't accept tokens with unrelated certs
This commit is contained in:
eabdullin 2023-11-16 11:22:40 +03:00
commit 7fcf99aa45
8 changed files with 926 additions and 20 deletions

2
.gitignore vendored
View File

@ -1 +1 @@
SOURCES/open-vm-tools-12.1.5-20735119.tar.gz
SOURCES/open-vm-tools-12.2.5-21855600.tar.gz

View File

@ -1 +1 @@
92cfc4bc23f3f4392a0e925d639aeac37c4aafb5 SOURCES/open-vm-tools-12.1.5-20735119.tar.gz
6bc6e77418cc4a039063a7ca40859535b9bbb339 SOURCES/open-vm-tools-12.2.5-21855600.tar.gz

View File

@ -0,0 +1,255 @@
From 1bfe23d728b74e08f4f65cd9b0093ca73937003a Mon Sep 17 00:00:00 2001
From: Katy Feng <fkaty@vmware.com>
Date: Tue, 17 Oct 2023 15:24:48 -0700
Subject: [PATCH] Don't accept tokens with unrelated certs
If a SAML token has a cert that's not a part of a chain,
fail the token as invalid.
---
open-vm-tools/vgauth/common/certverify.c | 147 +++++++++++++++++-
open-vm-tools/vgauth/common/certverify.h | 6 +-
open-vm-tools/vgauth/common/prefs.h | 4 +-
.../vgauth/serviceImpl/saml-xmlsec1.c | 14 ++
4 files changed, 168 insertions(+), 3 deletions(-)
diff --git a/open-vm-tools/vgauth/common/certverify.c b/open-vm-tools/vgauth/common/certverify.c
index 0ed78edb0..845f59b91 100644
--- a/open-vm-tools/vgauth/common/certverify.c
+++ b/open-vm-tools/vgauth/common/certverify.c
@@ -1,5 +1,5 @@
/*********************************************************
- * Copyright (C) 2011-2016, 2018-2019, 2021-2022 VMware, Inc. All rights reserved.
+ * Copyright (c) 2011-2016, 2018-2019, 2021-2023 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
@@ -914,3 +914,148 @@ done:
return err;
}
+
+
+/*
+ * Finds a cert with a subject (if checkSubj is set) or issuer (if
+ * checkSUbj is unset), matching 'val' in the list
+ * of certs. Returns a match or NULL.
+ */
+
+static X509 *
+FindCert(GList *cList,
+ X509_NAME *val,
+ int checkSubj)
+{
+ GList *l;
+ X509 *c;
+ X509_NAME *v;
+
+ l = cList;
+ while (l != NULL) {
+ c = (X509 *) l->data;
+ if (checkSubj) {
+ v = X509_get_subject_name(c);
+ } else {
+ v = X509_get_issuer_name(c);
+ }
+ if (X509_NAME_cmp(val, v) == 0) {
+ return c;
+ }
+ l = l->next;
+ }
+ return NULL;
+}
+
+
+/*
+ ******************************************************************************
+ * CertVerify_CheckForUnrelatedCerts -- */ /**
+ *
+ * Looks over a list of certs. If it finds that they are not all
+ * part of the same chain, returns failure.
+ *
+ * @param[in] numCerts The number of certs in the chain.
+ * @param[in] pemCerts The chain of certificates to verify.
+ *
+ * @return VGAUTH_E_OK on success, VGAUTH_E_FAIL if unrelated certs are found.
+ *
+ ******************************************************************************
+ */
+
+VGAuthError
+CertVerify_CheckForUnrelatedCerts(int numCerts,
+ const char **pemCerts)
+{
+ VGAuthError err = VGAUTH_E_FAIL;
+ int chainLen = 0;
+ int i;
+ X509 **certs = NULL;
+ GList *rawList = NULL;
+ X509 *baseCert;
+ X509 *curCert;
+ X509_NAME *subject;
+ X509_NAME *issuer;
+
+ /* common single cert case; nothing to do */
+ if (numCerts == 1) {
+ return VGAUTH_E_OK;
+ }
+
+ /* convert all PEM to X509 objects */
+ certs = g_malloc0(numCerts * sizeof(X509 *));
+ for (i = 0; i < numCerts; i++) {
+ certs[i] = CertStringToX509(pemCerts[i]);
+ if (NULL == certs[i]) {
+ g_warning("%s: failed to convert cert to X509\n", __FUNCTION__);
+ goto done;
+ }
+ }
+
+ /* choose the cert to start the chain. shouldn't matter which */
+ baseCert = certs[0];
+
+ /* put the rest into a list */
+ for (i = 1; i < numCerts; i++) {
+ rawList = g_list_append(rawList, certs[i]);
+ }
+
+ /* now chase down to a leaf, looking for certs the baseCert issued */
+ subject = X509_get_subject_name(baseCert);
+ while ((curCert = FindCert(rawList, subject, 0)) != NULL) {
+ /* pull it from the list */
+ rawList = g_list_remove(rawList, curCert);
+ /* set up the next find */
+ subject = X509_get_subject_name(curCert);
+ }
+
+ /*
+ * walk up to the root cert, by finding a cert where the
+ * issuer equals the subject of the current
+ */
+ issuer = X509_get_issuer_name(baseCert);
+ while ((curCert = FindCert(rawList, issuer, 1)) != NULL) {
+ /* pull it from the list */
+ rawList = g_list_remove(rawList, curCert);
+ /* set up the next find */
+ issuer = X509_get_issuer_name(curCert);
+ }
+
+ /*
+ * At this point, anything on the list should be certs that are not part
+ * of the chain that includes the original 'baseCert'.
+ *
+ * For a valid token, the list should be empty.
+ */
+ chainLen = g_list_length(rawList);
+ if (chainLen != 0 ) {
+ GList *l;
+
+ g_warning("%s: %d unrelated certs found in list\n",
+ __FUNCTION__, chainLen);
+
+ /* debug helper */
+ l = rawList;
+ while (l != NULL) {
+ X509* c = (X509 *) l->data;
+ char *s = X509_NAME_oneline(X509_get_subject_name(c), NULL, 0);
+
+ g_debug("%s: unrelated cert subject: %s\n", __FUNCTION__, s);
+ free(s);
+ l = l->next;
+ }
+
+ goto done;
+ }
+
+ g_debug("%s: Success! no unrelated certs found\n", __FUNCTION__);
+ err = VGAUTH_E_OK;
+
+done:
+ g_list_free(rawList);
+ for (i = 0; i < numCerts; i++) {
+ X509_free(certs[i]);
+ }
+ g_free(certs);
+ return err;
+}
diff --git a/open-vm-tools/vgauth/common/certverify.h b/open-vm-tools/vgauth/common/certverify.h
index d7c6410b6..89ec97a10 100644
--- a/open-vm-tools/vgauth/common/certverify.h
+++ b/open-vm-tools/vgauth/common/certverify.h
@@ -1,5 +1,5 @@
/*********************************************************
- * Copyright (C) 2011-2016, 2020 VMware, Inc. All rights reserved.
+ * Copyright (C) 2011-2016, 2020, 2023 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
@@ -67,6 +67,10 @@ VGAuthError CertVerify_CheckSignatureUsingCert(VGAuthHashAlg hash,
size_t signatureLen,
const unsigned char *signature);
+
+VGAuthError CertVerify_CheckForUnrelatedCerts(int numCerts,
+ const char **pemCerts);
+
gchar * CertVerify_StripPEMCert(const gchar *pemCert);
gchar * CertVerify_CertToX509String(const gchar *pemCert);
diff --git a/open-vm-tools/vgauth/common/prefs.h b/open-vm-tools/vgauth/common/prefs.h
index ff116928c..6c58f3f4b 100644
--- a/open-vm-tools/vgauth/common/prefs.h
+++ b/open-vm-tools/vgauth/common/prefs.h
@@ -1,5 +1,5 @@
/*********************************************************
- * Copyright (C) 2011-2019 VMware, Inc. All rights reserved.
+ * Copyright (C) 2011-2019,2023 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
@@ -136,6 +136,8 @@ msgCatalog = /etc/vmware-tools/vgauth/messages
#define VGAUTH_PREF_ALIASSTORE_DIR "aliasStoreDir"
/** The number of seconds slack allowed in either direction in SAML token date checks. */
#define VGAUTH_PREF_CLOCK_SKEW_SECS "clockSkewAdjustment"
+/** If unrelated certificates are allowed in a SAML token */
+#define VGAUTH_PREF_ALLOW_UNRELATED_CERTS "allowUnrelatedCerts"
/** Ticket group name. */
#define VGAUTH_PREF_GROUP_NAME_TICKET "ticket"
diff --git a/open-vm-tools/vgauth/serviceImpl/saml-xmlsec1.c b/open-vm-tools/vgauth/serviceImpl/saml-xmlsec1.c
index 14cba1b5b..57e931626 100644
--- a/open-vm-tools/vgauth/serviceImpl/saml-xmlsec1.c
+++ b/open-vm-tools/vgauth/serviceImpl/saml-xmlsec1.c
@@ -49,6 +49,7 @@
#include "vmxlog.h"
static int gClockSkewAdjustment = VGAUTH_PREF_DEFAULT_CLOCK_SKEW_SECS;
+static gboolean gAllowUnrelatedCerts = FALSE;
static xmlSchemaPtr gParsedSchemas = NULL;
static xmlSchemaValidCtxtPtr gSchemaValidateCtx = NULL;
@@ -369,6 +370,10 @@ LoadPrefs(void)
VGAUTH_PREF_DEFAULT_CLOCK_SKEW_SECS);
Log("%s: Allowing %d of clock skew for SAML date validation\n",
__FUNCTION__, gClockSkewAdjustment);
+ gAllowUnrelatedCerts = Pref_GetBool(gPrefs,
+ VGAUTH_PREF_ALLOW_UNRELATED_CERTS,
+ VGAUTH_PREF_GROUP_NAME_SERVICE,
+ FALSE);
}
@@ -1589,6 +1594,15 @@ SAML_VerifyBearerTokenAndChain(const char *xmlText,
return VGAUTH_E_AUTHENTICATION_DENIED;
}
+ if (!gAllowUnrelatedCerts) {
+ err = CertVerify_CheckForUnrelatedCerts(num, (const char **) certChain);
+ if (err != VGAUTH_E_OK) {
+ VMXLog_Log(VMXLOG_LEVEL_WARNING,
+ "Unrelated certs found in SAML token, failing\n");
+ return VGAUTH_E_AUTHENTICATION_DENIED;
+ }
+ }
+
subj.type = SUBJECT_TYPE_NAMED;
subj.name = *subjNameOut;
err = ServiceVerifyAndCheckTrustCertChainForSubject(num,

View File

@ -0,0 +1,196 @@
From 63f7c79c4aecb14d37cc4ce9da509419e31d394f Mon Sep 17 00:00:00 2001
From: Katy Feng <fkaty@vmware.com>
Date: Tue, 17 Oct 2023 15:24:48 -0700
Subject: [PATCH] File descriptor vulnerability in the open-vm-tools
vmware-user-suid-wrapperx on Linux
Moving the privilege drop logic (dropping privilege to the real uid and
gid of the process for the vmusr service) from suidWrapper to vmtoolsd code.
Now the vmtoolsd is not executed with dropped privileges (started as setuid
program) and the dumpable attribute of the process is not reset.
The unprivileged user will not have access to the privileged file descriptors
in the vmtoolsd vmusr process.
Also, setting the FD_CLOEXEC flag for both uinputFd and blockFd preventing
the file descriptors being inherited any further from the vmtoolsd.
---
open-vm-tools/services/vmtoolsd/mainPosix.c | 78 ++++++++++++++++++-
open-vm-tools/vmware-user-suid-wrapper/main.c | 28 +------
2 files changed, 81 insertions(+), 25 deletions(-)
diff --git a/open-vm-tools/services/vmtoolsd/mainPosix.c b/open-vm-tools/services/vmtoolsd/mainPosix.c
index fd2667cd5..6c52156bc 100644
--- a/open-vm-tools/services/vmtoolsd/mainPosix.c
+++ b/open-vm-tools/services/vmtoolsd/mainPosix.c
@@ -1,5 +1,5 @@
/*********************************************************
- * Copyright (C) 2008-2020,2022 VMware, Inc. All rights reserved.
+ * Copyright (c) 2008-2020,2022-2023 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
@@ -28,10 +28,12 @@
#include <signal.h>
#include <string.h>
#include <unistd.h>
+#include <fcntl.h>
#include <glib/gstdio.h>
#include "file.h"
#include "guestApp.h"
#include "hostinfo.h"
+#include "su.h"
#include "system.h"
#include "unicode.h"
#include "util.h"
@@ -154,6 +156,59 @@ ToolsCoreWorkAroundLoop(ToolsServiceState *state,
}
+/**
+ * Tools function to set close-on-exec flg for the fd.
+ *
+ * @param[in] fd open file descriptor.
+ *
+ * @return TRUE on success, FALSE otherwise.
+ */
+
+static gboolean
+ToolsSetCloexecFlag(int fd)
+{
+ int flags;
+
+ if (fd == -1) {
+ /* fd is not present, no need to manipulate */
+ return TRUE;
+ }
+
+ flags = fcntl(fd, F_GETFD, 0);
+ if (flags < 0) {
+ g_printerr("Couldn't get the flags set for fd %d, error %u.", fd, errno);
+ return FALSE;
+ }
+ flags |= FD_CLOEXEC;
+ if (fcntl(fd, F_SETFD, flags) < 0) {
+ g_printerr("Couldn't set close-on-exec for fd %d, error %u.", fd, errno);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+/**
+ * Tools function to close the fds.
+ */
+
+static void
+ToolsCloseFds(void)
+{
+ if (gState.ctx.blockFD != -1) {
+ close(gState.ctx.blockFD);
+ }
+
+ /*
+ * uinputFD will be available only for wayland.
+ */
+ if (gState.ctx.uinputFD != -1) {
+ close(gState.ctx.uinputFD);
+ }
+}
+
+
/**
* Tools daemon entry function.
*
@@ -210,6 +265,27 @@ main(int argc,
g_free(argvCopy);
argvCopy = NULL;
+ /*
+ * Drops privilege to the real uid and gid of the process
+ * for the "vmusr" service.
+ */
+ if (TOOLS_IS_USER_SERVICE(&gState)) {
+ uid_t uid = getuid();
+ gid_t gid = getgid();
+
+ if ((Id_SetREUid(uid, uid) != 0) ||
+ (Id_SetREGid(gid, gid) != 0)) {
+ g_printerr("could not drop privileges: %s", strerror(errno));
+ ToolsCloseFds();
+ goto exit;
+ }
+ if (!ToolsSetCloexecFlag(gState.ctx.blockFD) ||
+ !ToolsSetCloexecFlag(gState.ctx.uinputFD)) {
+ ToolsCloseFds();
+ goto exit;
+ }
+ }
+
if (gState.pidFile != NULL) {
/*
* If argv[0] is not an absolute path, make it so; all other path
diff --git a/open-vm-tools/vmware-user-suid-wrapper/main.c b/open-vm-tools/vmware-user-suid-wrapper/main.c
index e9d7e5084..73ae9b9bb 100644
--- a/open-vm-tools/vmware-user-suid-wrapper/main.c
+++ b/open-vm-tools/vmware-user-suid-wrapper/main.c
@@ -1,5 +1,5 @@
/*********************************************************
- * Copyright (C) 2007-2018 VMware, Inc. All rights reserved.
+ * Copyright (C) 2007-2018,2023 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
@@ -156,8 +156,7 @@ MaskSignals(void)
*
* Obtains the library directory from the Tools locations database, then
* opens a file descriptor (while still root) to add and remove blocks,
- * drops privilege to the real uid of this process, and finally starts
- * vmware-user.
+ * and finally starts vmware-user.
*
* Results:
* Parent: TRUE on success, FALSE on failure.
@@ -173,8 +172,6 @@ static Bool
StartVMwareUser(char *const envp[])
{
pid_t pid;
- uid_t uid;
- gid_t gid;
int blockFd = -1;
char blockFdStr[8];
int uinputFd = -1;
@@ -191,8 +188,8 @@ StartVMwareUser(char *const envp[])
}
/*
- * Now create a child process, obtain a file descriptor as root, downgrade
- * privilege, and run vmware-user.
+ * Now create a child process, obtain a file descriptor as root and
+ * run vmware-user.
*/
pid = fork();
if (pid == -1) {
@@ -229,23 +226,6 @@ StartVMwareUser(char *const envp[])
}
}
- uid = getuid();
- gid = getgid();
-
- if ((setreuid(uid, uid) != 0) ||
- (setregid(gid, gid) != 0)) {
- Error("could not drop privileges: %s\n", strerror(errno));
- if (blockFd != -1) {
- close(blockFd);
- }
- if (useWayland) {
- if (uinputFd != -1) {
- close(uinputFd);
- }
- }
- return FALSE;
- }
-
/*
* Since vmware-user provides features that don't depend on vmblock, we
* invoke vmware-user even if we couldn't obtain a file descriptor or we

View File

@ -0,0 +1,426 @@
From 6b783bb35d6c860c809ad4e05ef9f5bf5ad81bcc Mon Sep 17 00:00:00 2001
From: Katy Feng <fkaty@vmware.com>
Date: Tue, 22 Aug 2023 11:11:42 -0700
Subject: [PATCH] Provide alternate method to allow (expected) pre-frozen
filesystems
RH-Author: Ani Sinha <None>
RH-MergeRequest: 5: Provide alternate method to allow (expected) pre-frozen filesystems when taking a quiesced snapshot.
RH-Jira: RHEL-2446
RH-Acked-by: Cathy Avery <cavery@redhat.com>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [1/1] 02bb68525844635819d1f4745e606d7ae8519c6d (anisinha/centos-open-vm-tools)
Effective with open-vm-tools 12.2.0, Linux quiesced snapshots will fail if
any filesystem(s) have been prefrozen by other than the vmtoolsd process.
This has been done to assure that filesystems are inactive while the
snapshots are being taken. Some existing prefreeze scripts may be freezing
some filesystem(s). In these cases, the vmtoolsd process must be informed of
anticipated pre-frozen filesystems by providing an "excludedFileSystem" list in
the [vmbackup] section of the tools.conf file.
This change provides a new switch in the tools.conf file to allow pre-frozen
filesystems to be encountered and accepted when doing a quiesced snapshot
operation. With the default value of "false", the "ignoreFrozenFileSystems"
can be configured with a setting of "true" to notify the quiesced snapshot
operation that pre-frozen filesystems are allowed.
(cherry picked from commit 60c3a80ddc2b400366ed05169e16a6bed6501da2)
Signed-off-by: Ani Sinha <anisinha@redhat.com>
---
open-vm-tools/lib/include/syncDriver.h | 5 ++--
open-vm-tools/lib/syncDriver/nullDriver.c | 10 +++++---
open-vm-tools/lib/syncDriver/syncDriverInt.h | 14 +++++++----
.../lib/syncDriver/syncDriverLinux.c | 25 ++++++++++++++-----
.../lib/syncDriver/syncDriverPosix.c | 7 +++---
open-vm-tools/lib/syncDriver/vmSyncDriver.c | 10 +++++---
.../services/plugins/vix/foundryToolsDaemon.c | 14 +++++++++--
.../services/plugins/vmbackup/stateMachine.c | 8 ++++--
.../services/plugins/vmbackup/syncDriverOps.c | 5 ++--
.../services/plugins/vmbackup/vmBackupInt.h | 19 ++++++++------
open-vm-tools/tools.conf | 23 +++++++++++++++++
11 files changed, 103 insertions(+), 37 deletions(-)
diff --git a/open-vm-tools/lib/include/syncDriver.h b/open-vm-tools/lib/include/syncDriver.h
index 20712f66..8ef229d4 100644
--- a/open-vm-tools/lib/include/syncDriver.h
+++ b/open-vm-tools/lib/include/syncDriver.h
@@ -1,5 +1,5 @@
/*********************************************************
- * Copyright (C) 2005-2018 VMware, Inc. All rights reserved.
+ * Copyright (c) 2005-2018, 2023 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
@@ -51,7 +51,8 @@ typedef enum {
Bool SyncDriver_Init(void);
Bool SyncDriver_Freeze(const char *drives, Bool enableNullDriver,
SyncDriverHandle *handle,
- const char *excludedFileSystems);
+ const char *excludedFileSystems,
+ Bool ignoreFrozenFS);
Bool SyncDriver_Thaw(const SyncDriverHandle handle);
SyncDriverStatus SyncDriver_QueryStatus(const SyncDriverHandle handle,
int32 timeout);
diff --git a/open-vm-tools/lib/syncDriver/nullDriver.c b/open-vm-tools/lib/syncDriver/nullDriver.c
index 5e19e208..be96222a 100644
--- a/open-vm-tools/lib/syncDriver/nullDriver.c
+++ b/open-vm-tools/lib/syncDriver/nullDriver.c
@@ -1,5 +1,5 @@
/*********************************************************
- * Copyright (C) 2011-2016 VMware, Inc. All rights reserved.
+ * Copyright (c) 2011-2016, 2023 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
@@ -54,8 +54,9 @@ NullDriverClose(SyncDriverHandle handle)
*
* Calls sync().
*
- * @param[in] paths Unused.
- * @param[out] handle Where to store the operation handle.
+ * @param[in] paths Unused.
+ * @param[out] handle Where to store the operation handle.
+ * @param[in] ignoreFrozenFS Unused.
*
* @return A SyncDriverErr.
*
@@ -64,7 +65,8 @@ NullDriverClose(SyncDriverHandle handle)
SyncDriverErr
NullDriver_Freeze(const GSList *paths,
- SyncDriverHandle *handle)
+ SyncDriverHandle *handle,
+ Bool ignoreFrozenFS)
{
/*
* This is more of a "let's at least do something" than something that
diff --git a/open-vm-tools/lib/syncDriver/syncDriverInt.h b/open-vm-tools/lib/syncDriver/syncDriverInt.h
index 04f37bf2..a5706298 100644
--- a/open-vm-tools/lib/syncDriver/syncDriverInt.h
+++ b/open-vm-tools/lib/syncDriver/syncDriverInt.h
@@ -1,5 +1,5 @@
/*********************************************************
- * Copyright (C) 2011-2017 VMware, Inc. All rights reserved.
+ * Copyright (c) 2011-2017, 2023 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
@@ -41,7 +41,8 @@ typedef enum {
} SyncDriverErr;
typedef SyncDriverErr (*SyncFreezeFn)(const GSList *paths,
- SyncDriverHandle *handle);
+ SyncDriverHandle *handle,
+ Bool ignoreFrozenFs);
typedef struct SyncHandle {
SyncDriverErr (*thaw)(const SyncDriverHandle handle);
@@ -55,15 +56,18 @@ typedef struct SyncHandle {
#if defined(__linux__)
SyncDriverErr
LinuxDriver_Freeze(const GSList *userPaths,
- SyncDriverHandle *handle);
+ SyncDriverHandle *handle,
+ Bool ignoreFrozenFs);
SyncDriverErr
VmSync_Freeze(const GSList *userPaths,
- SyncDriverHandle *handle);
+ SyncDriverHandle *handle,
+ Bool ignoreFrozenFs);
SyncDriverErr
NullDriver_Freeze(const GSList *userPaths,
- SyncDriverHandle *handle);
+ SyncDriverHandle *handle,
+ Bool ignoreFrozenFs);
#endif
#endif
diff --git a/open-vm-tools/lib/syncDriver/syncDriverLinux.c b/open-vm-tools/lib/syncDriver/syncDriverLinux.c
index 6d9a3568..4581098e 100644
--- a/open-vm-tools/lib/syncDriver/syncDriverLinux.c
+++ b/open-vm-tools/lib/syncDriver/syncDriverLinux.c
@@ -199,8 +199,9 @@ LinuxFiGetAttr(const SyncDriverHandle handle, // IN (ignored)
* slow when guest is performing significant IO. Therefore, caller should
* consider running this function in a separate thread.
*
- * @param[in] paths List of paths to freeze.
- * @param[out] handle Handle to use for thawing.
+ * @param[in] paths List of paths to freeze.
+ * @param[out] handle Handle to use for thawing.
+ * @param[in] ignoreFrozenFS Switch to allow EBUSY error.
*
* @return A SyncDriverErr.
*
@@ -209,7 +210,8 @@ LinuxFiGetAttr(const SyncDriverHandle handle, // IN (ignored)
SyncDriverErr
LinuxDriver_Freeze(const GSList *paths,
- SyncDriverHandle *handle)
+ SyncDriverHandle *handle,
+ Bool ignoreFrozenFS)
{
ssize_t count = 0;
Bool first = TRUE;
@@ -324,9 +326,12 @@ LinuxDriver_Freeze(const GSList *paths,
* Previously, an EBUSY error was ignored, assuming that we may try
* to freeze the same superblock more than once depending on the
* OS configuration (e.g., usage of bind mounts).
- * Using the filesystem Id to check if this is a filesystem that we
- * have seen previously and will ignore this FD only if that is
- * the case. Log a warning otherwise since the quiesced snapshot
+ * Use the filesystem Id to check if this filesystem has been
+ * handled before and, if so, ignore it.
+ * Alternatively, allow (ignore) the EBUSY if the
+ * "ignoreFrozenFileSystems" switch inside "vmbackup" section of
+ * tools.conf file is TRUE.
+ * Otherwise, log a warning as the quiesced snapshot
* attempt will fail.
*/
if (ioctlerr == EBUSY) {
@@ -339,6 +344,14 @@ LinuxDriver_Freeze(const GSList *paths,
*/
Debug(LGPFX "skipping path '%s' - previously frozen", path);
continue;
+ } else if (ignoreFrozenFS) {
+ /*
+ * Ignores the EBUSY error if the FS has been frozen by another
+ * process and the 'ignoreFrozenFileSystems' setting is
+ * turned on in tools.conf file.
+ */
+ Debug(LGPFX "Ignoring the frozen filesystem '%s'",path);
+ continue;
}
/*
* It appears that this FS has been locked or frozen by another
diff --git a/open-vm-tools/lib/syncDriver/syncDriverPosix.c b/open-vm-tools/lib/syncDriver/syncDriverPosix.c
index 7b6132ba..27369639 100644
--- a/open-vm-tools/lib/syncDriver/syncDriverPosix.c
+++ b/open-vm-tools/lib/syncDriver/syncDriverPosix.c
@@ -1,5 +1,5 @@
/*********************************************************
- * Copyright (C) 2005-2019 VMware, Inc. All rights reserved.
+ * Copyright (c) 2005-2019, 2023 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
@@ -456,7 +456,8 @@ Bool
SyncDriver_Freeze(const char *userPaths, // IN
Bool enableNullDriver, // IN
SyncDriverHandle *handle, // OUT
- const char *excludedFileSystems) // IN
+ const char *excludedFileSystems, // IN
+ Bool ignoreFrozenFS) // IN
{
GSList *paths = NULL;
SyncDriverErr err = SD_UNAVAILABLE;
@@ -517,7 +518,7 @@ SyncDriver_Freeze(const char *userPaths, // IN
continue;
}
#endif
- err = freezeFn(paths, handle);
+ err = freezeFn(paths, handle, ignoreFrozenFS);
}
/*
diff --git a/open-vm-tools/lib/syncDriver/vmSyncDriver.c b/open-vm-tools/lib/syncDriver/vmSyncDriver.c
index 2bd0e886..a0d4a315 100644
--- a/open-vm-tools/lib/syncDriver/vmSyncDriver.c
+++ b/open-vm-tools/lib/syncDriver/vmSyncDriver.c
@@ -1,5 +1,5 @@
/*********************************************************
- * Copyright (C) 2011-2016 VMware, Inc. All rights reserved.
+ * Copyright (c) 2011-2016, 2023 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
@@ -91,8 +91,9 @@ VmSyncClose(SyncDriverHandle handle)
* Opens a description to the driver's proc node, and if successful, send an
* ioctl to freeze the requested filesystems.
*
- * @param[in] paths List of paths to freeze.
- * @param[out] handle Where to store the handle to use for thawing.
+ * @param[in] paths List of paths to freeze.
+ * @param[out] handle Where to store the handle to use for thawing.
+ * @param[in] ignoreFrozenFS Unused.
*
* @return A SyncDriverErr.
*
@@ -101,7 +102,8 @@ VmSyncClose(SyncDriverHandle handle)
SyncDriverErr
VmSync_Freeze(const GSList *paths,
- SyncDriverHandle *handle)
+ SyncDriverHandle *handle,
+ Bool ignoreFrozenFS)
{
int file;
Bool first = TRUE;
diff --git a/open-vm-tools/services/plugins/vix/foundryToolsDaemon.c b/open-vm-tools/services/plugins/vix/foundryToolsDaemon.c
index 7d45d3f5..079540f1 100644
--- a/open-vm-tools/services/plugins/vix/foundryToolsDaemon.c
+++ b/open-vm-tools/services/plugins/vix/foundryToolsDaemon.c
@@ -1,5 +1,5 @@
/*********************************************************
- * Copyright (C) 2003-2021 VMware, Inc. All rights reserved.
+ * Copyright (c) 2003-2021, 2023 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
@@ -545,6 +545,8 @@ ToolsDaemonTcloSyncDriverFreeze(RpcInData *data)
GKeyFile *confDictRef = ctx->config;
Bool enableNullDriver;
GSource *timer;
+ char *excludedFileSystems;
+ Bool ignoreFrozenFS;
/*
* Parse the arguments
@@ -581,10 +583,18 @@ ToolsDaemonTcloSyncDriverFreeze(RpcInData *data)
"vmbackup",
"enableNullDriver",
FALSE);
+ excludedFileSystems = VMTools_ConfigGetString(confDictRef,
+ "vmbackup",
+ "excludedFileSystems",
+ NULL);
+ ignoreFrozenFS = VMTools_ConfigGetBoolean(confDictRef,
+ "vmbackup",
+ "ignoreFrozenFileSystems",
+ FALSE);
/* Perform the actual freeze. */
if (!SyncDriver_Freeze(driveList, enableNullDriver, &gSyncDriverHandle,
- NULL) ||
+ excludedFileSystems, ignoreFrozenFS) ||
SyncDriver_QueryStatus(gSyncDriverHandle, INFINITE) != SYNCDRIVER_IDLE) {
g_warning("%s: Failed to Freeze drives '%s'\n",
__FUNCTION__, driveList);
diff --git a/open-vm-tools/services/plugins/vmbackup/stateMachine.c b/open-vm-tools/services/plugins/vmbackup/stateMachine.c
index 99f52582..b04565d8 100644
--- a/open-vm-tools/services/plugins/vmbackup/stateMachine.c
+++ b/open-vm-tools/services/plugins/vmbackup/stateMachine.c
@@ -1073,9 +1073,13 @@ VmBackupStartCommon(RpcInData *data,
#if defined(__linux__)
gBackupState->excludedFileSystems =
VMBACKUP_CONFIG_GET_STR(ctx->config, "excludedFileSystems", NULL);
- g_debug("Using excludedFileSystems = \"%s\"\n",
+ gBackupState->ignoreFrozenFS =
+ VMBACKUP_CONFIG_GET_BOOL(ctx->config, "ignoreFrozenFileSystems", FALSE);
+
+ g_debug("Using excludedFileSystems = \"%s\", ignoreFrozenFileSystems = %d\n",
(gBackupState->excludedFileSystems != NULL) ?
- gBackupState->excludedFileSystems : "(null)");
+ gBackupState->excludedFileSystems : "(null)",
+ gBackupState->ignoreFrozenFS);
#endif
g_debug("Quiescing volumes: %s",
(gBackupState->volumes) ? gBackupState->volumes : "(null)");
diff --git a/open-vm-tools/services/plugins/vmbackup/syncDriverOps.c b/open-vm-tools/services/plugins/vmbackup/syncDriverOps.c
index cc01d294..a090ec72 100644
--- a/open-vm-tools/services/plugins/vmbackup/syncDriverOps.c
+++ b/open-vm-tools/services/plugins/vmbackup/syncDriverOps.c
@@ -1,5 +1,5 @@
/*********************************************************
- * Copyright (C) 2007-2019, 2021 VMware, Inc. All rights reserved.
+ * Copyright (C) 2007-2019, 2021, 2023 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
@@ -276,7 +276,8 @@ VmBackupNewDriverOp(VmBackupState *state, // IN
useNullDriverPrefs ?
state->enableNullDriver : FALSE,
op->syncHandle,
- state->excludedFileSystems);
+ state->excludedFileSystems,
+ state->ignoreFrozenFS);
break;
case OP_THAW:
op->manifest = SyncNewManifest(state, *op->syncHandle);
diff --git a/open-vm-tools/services/plugins/vmbackup/vmBackupInt.h b/open-vm-tools/services/plugins/vmbackup/vmBackupInt.h
index 0c912174..65e2e552 100644
--- a/open-vm-tools/services/plugins/vmbackup/vmBackupInt.h
+++ b/open-vm-tools/services/plugins/vmbackup/vmBackupInt.h
@@ -1,5 +1,5 @@
/*********************************************************
- * Copyright (C) 2008-2019 VMware, Inc. All rights reserved.
+ * Copyright (c) 2008-2019, 2023 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
@@ -100,18 +100,22 @@ struct VmBackupSyncCompleter;
* Don't modify the fields directly - rather, use VmBackup_SetCurrentOp,
* which does most of the handling needed by users of the state machine.
*
- * NOTE: The thread for freeze operation modifies currentOp in BackupState
- * which is also accessed by the AsyncCallback driving the state
- * machine (run by main thread). Also, gcc might generate two
- * instructions for writing a 64-bit value. Therefore, protect the
- * access to currentOp and related fields using opLock mutex.
+ * NOTE 1: The thread for freeze operation modifies currentOp in BackupState
+ * which is also accessed by the AsyncCallback driving the state
+ * machine (run by main thread). Also, gcc might generate two
+ * instructions for writing a 64-bit value. Therefore, protect the
+ * access to currentOp and related fields using opLock mutex.
+ *
+ * NOTE 2: Only used by Linux guests, ignored on Windows guests and is
+ * initialized to "false" when the VmBackupState is initialized
+ * at the start of a backup operation.
*/
typedef struct VmBackupState {
ToolsAppCtx *ctx;
VmBackupOp *currentOp;
const char *currentOpName;
- GMutex opLock; // See note above
+ GMutex opLock; // See note 1 above
char *volumes;
char *snapshots;
guint pollPeriod;
@@ -127,6 +131,7 @@ typedef struct VmBackupState {
Bool allowHWProvider;
Bool execScripts;
Bool enableNullDriver;
+ Bool ignoreFrozenFS; // See note 2 above
Bool needsPriv;
gchar *scriptArg;
guint timeout;
diff --git a/open-vm-tools/tools.conf b/open-vm-tools/tools.conf
index e5a03a9c..f238cb59 100644
--- a/open-vm-tools/tools.conf
+++ b/open-vm-tools/tools.conf
@@ -395,6 +395,29 @@
#excludedFileSystems=
+# Linux:
+# It is possible that filesystems are being frozen in pre-freeze scripts
+# to control the order in which those specific filesystems are to be frozen.
+# The vmtoolsd process must be informed of all such filesystems with the help
+# of "excludedFileSystems" setting of tools.conf.
+#
+# A temporary workaround is available (starting from 12.3.0) for admins to allow
+# quiesceing operation to succeed until the "excludedFileSystems" list
+# is configured.
+#
+# If another process thaws the file system while a quiescing operation
+# operation is ongoing, the snapshot may be compromised. Once the
+# "excludedFileSystems" list is configured this setting MUST be unset (or set
+# to false).
+#
+# The value of ignoreFrozenFileSystems is a true or false; the default is
+# false.
+#
+# Set to true to ignore pre-frozen file systems during the quiescing operation.
+#
+# ignoreFrozenFileSystems is Linux only (Not supported on Windows).
+#ignoreFrozenFileSystems=false
+
# execScripts specifies whether to execute scripts as part of the quiescing
# operation. Scripts are executed from the scripts directory along with the
# legacy scripts.
--
2.39.3

View File

@ -1,6 +1,6 @@
[Unit]
Description=VGAuth Service for open-vm-tools
Documentation=http://github.com/vmware/open-vm-tools
Documentation=https://github.com/vmware/open-vm-tools
ConditionVirtualization=vmware
PartOf=vmtoolsd.service

View File

@ -1,6 +1,6 @@
[Unit]
Description=Service for virtual machines hosted on VMware
Documentation=http://github.com/vmware/open-vm-tools
Documentation=https://github.com/vmware/open-vm-tools
ConditionVirtualization=vmware
Requires=vgauthd.service
After=vgauthd.service

View File

@ -1,5 +1,5 @@
################################################################################
### Copyright 2013-2021 VMware, Inc. All rights reserved.
### Copyright 2013-2023 VMware, Inc. All rights reserved.
###
### RPM SPEC file for building open-vm-tools packages.
###
@ -19,9 +19,9 @@
################################################################################
%global _hardened_build 1
%global majorversion 12.1
%global majorversion 12.2
%global minorversion 5
%global toolsbuild 20735119
%global toolsbuild 21855600
%global toolsversion %{majorversion}.%{minorversion}
%global toolsdaemon vmtoolsd
%global vgauthdaemon vgauthd
@ -32,7 +32,7 @@
Name: open-vm-tools
Version: %{toolsversion}
Release: 1%{?dist}.3.alma.1
Release: 3%{?dist}.2.alma.1
Summary: Open Virtual Machine Tools for virtual machines hosted on VMware
License: GPLv2
URL: https://github.com/vmware/%{name}
@ -52,13 +52,16 @@ ExclusiveArch: %{ix86} x86_64 aarch64
%endif
#Patch0: name.patch
# [CISA Major Incident] CVE-2023-20867 open-vm-tools: authentication bypass vulnerability in the vgauth module
Patch1: ovt-Remove-some-dead-code.patch
# For bz#2236544 - CVE-2023-20900 open-vm-tools: SAML token signature bypass [rhel-9]
Patch1: ovt-VGAuth-Allow-only-X509-certs-to-verify-the-SAML-toke.patch
# For RHEL-2446 - [RHEL9.3][ESXi]Latest version of open-vm-tools breaks VM backups
Patch2: ovt-Provide-alternate-method-to-allow-expected-pre-froze.patch
# Patches were taken from:
# https://github.com/vmware/open-vm-tools/commit/9d458c53a7a656d4d1ba3a28d090cce82ac4af0e.patch
Patch2: Track-Linux-filesystem-id-FSID-for-quiesced-frozen-filesystems.patch
# https://gitlab.com/redhat/centos-stream/rpms/open-vm-tools/-/raw/fd4d578cf736199d35bd8531b9a53d2fcabc22ae/ovt-VGAuth-Allow-only-X509-certs-to-verify-the-SAML-toke.patch
Patch3: ovt-VGAuth-Allow-only-X509-certs-to-verify-the-SAML-toke.patch
# https://github.com/vmware/open-vm-tools/commit/1bfe23d728b74e08f4f65cd9b0093ca73937003a
Patch3: Dont-accept-tokens-with-unrelated-certs.patch
# https://github.com/vmware/open-vm-tools/commit/63f7c79c4aecb14d37cc4ce9da509419e31d394f
Patch4: File-descriptor-vulnerability-in-the-open-vm-tools.patch
BuildRequires: autoconf
BuildRequires: automake
@ -417,14 +420,40 @@ fi
%{_bindir}/vmware-vgauth-smoketest
%changelog
* Thu Sep 21 2023 Eduard Abdullin <eabdullin@almalinux.org> - 12.1.5-1.el9_2.3.alma.1
- Allow only X509 certs to verify the SAML token signature.
* Thu Nov 16 2023 Eduard Abdullin <eabdullin@almalinux.org> - 12.2.5-3.2.alma.1
- File descriptor vulnerability in the open-vm-tools
vmware-user-suid-wrapperx on Linux
- Don't accept tokens with unrelated certs
* Tue Sep 12 2023 Eduard Abdullin <eabdullin@almalinux.org> - 12.1.5-1.el9_2.2.alma.1
- Track Linux filesystem id (FSID) for quiesced (frozen) filesystems
* Fri Sep 22 2023 Miroslav Rezanina <mrezanin@redhat.com> - 12.2.5-3
- ovt-Provide-alternate-method-to-allow-expected-pre-froze.patch [RHEL-2446]
- Resolves: RHEL-2446
([RHEL9.3][ESXi]Latest version of open-vm-tools breaks VM backups)
* Wed Jul 12 2023 Andrew Lukoshko <alukoshko@almalinux.org> - 12.1.5-1.el9_2.1.alma
- [CISA Major Incident] CVE-2023-20867 open-vm-tools: authentication bypass vulnerability in the vgauth module
* Fri Sep 08 2023 Miroslav Rezanina <mrezanin@redhat.com> - 12.2.5-2
- ovt-VGAuth-Allow-only-X509-certs-to-verify-the-SAML-toke.patch [bz#2236544]
- Resolves: bz#2236544
(CVE-2023-20900 open-vm-tools: SAML token signature bypass [rhel-9])
* Mon Jul 10 2023 Miroslav Rezanina <mrezanin@redhat.com> - 12.2.5-1
- Rebaer to open-vm-tools 12.2.5
- Resolves: bz#2214862
([ESXi][RHEL9]open-vm-tools version 12.2.5 has been released - please rebase)
* Tue Jun 27 2023 Miroslav Rezanina <mrezanin@redhat.com> - 12.2.0-3
- ovt-Remove-some-dead-code.patch [bz#2215566]
- Resolves: bz#2215566
([CISA Major Incident] CVE-2023-20867 open-vm-tools: authentication bypass vulnerability in the vgauth module [rhel-br-9])
* Tue Jun 20 2023 Miroslav Rezanina <mrezanin@redhat.com> - 12.2.0-2
- ovt-Use-https-instead-of-http-for-documentation-links.patch [bz#2208160]
- Resolves: bz#2208160
([ESXi][RHEL9] URL in service unit files are started from http instead of https)
* Wed May 03 2023 Miroslav Rezanina <mrezanin@redhat.com> - 12.2.0-1
- Rebase to open-vm-tools 12.2.0 [bz#2177086]
- Resolves: bz#2177086
([ESXi][RHEL9]open-vm-tools version 12.2.0 has been released - please rebase)
* Fri Dec 09 2022 Miroslav Rezanina <mrezanin@redhat.com> - 12.1.5-1
- Rebase to open-vm-tools 12.1.5 [bz#2150190]