diff --git a/SOURCES/Track-Linux-filesystem-id-FSID-for-quiesced-frozen-filesystems.patch b/SOURCES/Track-Linux-filesystem-id-FSID-for-quiesced-frozen-filesystems.patch new file mode 100644 index 0000000..7aa0a52 --- /dev/null +++ b/SOURCES/Track-Linux-filesystem-id-FSID-for-quiesced-frozen-filesystems.patch @@ -0,0 +1,206 @@ +From 9d458c53a7a656d4d1ba3a28d090cce82ac4af0e Mon Sep 17 00:00:00 2001 +From: Katy Feng +Date: Tue, 17 Jan 2023 19:08:33 -0800 +Subject: [PATCH] Track Linux filesystem id (FSID) for quiesced (frozen) + filesystems + +Tracking the filesystem FSID along with each file descriptor (FD) +as the ioctl FIFREEZE is done. An EBUSY could be seen because of +an attempt to freeze the same superblock more than once depending +on the OS configuration (e.g. usage of bind mounts). An EBUSY could +also mean another process has locked or frozen that filesystem. + +When an EBUSY is received, the filesyste FSID is checked against the +list of filesystems that have already be quiesced. If not previously +seen, a warning that the filesystem is controlled by another process +is logged and the quiesced snapshot request will be rejected. +--- + .../lib/syncDriver/syncDriverLinux.c | 112 +++++++++++++++--- + 1 file changed, 96 insertions(+), 16 deletions(-) + +diff --git a/open-vm-tools/lib/syncDriver/syncDriverLinux.c b/open-vm-tools/lib/syncDriver/syncDriverLinux.c +index eef65a2eb..6d9a35687 100644 +--- a/open-vm-tools/lib/syncDriver/syncDriverLinux.c ++++ b/open-vm-tools/lib/syncDriver/syncDriverLinux.c +@@ -1,5 +1,5 @@ + /********************************************************* +- * Copyright (C) 2011-2018 VMware, Inc. All rights reserved. ++ * Copyright (C) 2011-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 +@@ -32,6 +32,7 @@ + #include + #include + #include ++#include + #include "debug.h" + #include "dynbuf.h" + #include "syncDriverInt.h" +@@ -43,12 +44,53 @@ + #endif + + ++ ++typedef struct LinuxFsInfo { ++ int fd; ++ fsid_t fsid; ++} LinuxFsInfo; ++ + typedef struct LinuxDriver { + SyncHandle driver; + size_t fdCnt; +- int *fds; ++ LinuxFsInfo *fds; + } LinuxDriver; + ++static ++const fsid_t MISSING_FSID = {}; ++ ++ ++/* ++ ******************************************************************************* ++ * LinuxFiFsIdMatch -- ++ * ++ * Check the collection of filesystems previously frozen for the specific ++ * FSID. ++ * ++ * @param[in] fds List of LinuxFsInfo data for filesystems previously ++ * frozen. ++ * @param[in] count Number of fds in the list. ++ * @param[in] nfsid The Filesystem ID of interest. ++ * ++ * @return TRUE if the FSID matches one previously processed. Otherwise FALSE ++ * ++ ******************************************************************************* ++ */ ++ ++static Bool ++LinuxFiFsIdMatch(const LinuxFsInfo *fds, ++ const size_t count, ++ const fsid_t *nfsid) { ++ size_t i; ++ ++ for (i = 0; i < count; i++) { ++ if (fds[i].fsid.__val[0] == nfsid->__val[0] && ++ fds[i].fsid.__val[1] == nfsid->__val[1]) { ++ return TRUE; ++ } ++ } ++ return FALSE; ++} + + /* + ******************************************************************************* +@@ -75,9 +117,11 @@ LinuxFiThaw(const SyncDriverHandle handle) + * Thaw in the reverse order of freeze + */ + for (i = sync->fdCnt; i > 0; i--) { +- Debug(LGPFX "Thawing fd=%d.\n", sync->fds[i-1]); +- if (ioctl(sync->fds[i-1], FITHAW) == -1) { +- Debug(LGPFX "Thaw failed for fd=%d.\n", sync->fds[i-1]); ++ int fd = sync->fds[i-1].fd; ++ ++ Debug(LGPFX "Thawing fd=%d.\n", fd); ++ if (ioctl(fd, FITHAW) == -1) { ++ Debug(LGPFX "Thaw failed for fd=%d.\n", fd); + err = SD_ERROR; + } + } +@@ -108,8 +152,10 @@ LinuxFiClose(SyncDriverHandle handle) + * Close in the reverse order of open + */ + for (i = sync->fdCnt; i > 0; i--) { +- Debug(LGPFX "Closing fd=%d.\n", sync->fds[i-1]); +- close(sync->fds[i-1]); ++ int fd = sync->fds[i-1].fd; ++ ++ Debug(LGPFX "Closing fd=%d.\n", fd); ++ close(fd); + } + free(sync->fds); + free(sync); +@@ -196,8 +242,11 @@ LinuxDriver_Freeze(const GSList *paths, + */ + while (paths != NULL) { + int fd; ++ LinuxFsInfo fsInfo; + struct stat sbuf; ++ struct statfs fsbuf; + const char *path = paths->data; ++ + Debug(LGPFX "opening path '%s'.\n", path); + paths = g_slist_next(paths); + fd = open(path, O_RDONLY); +@@ -258,23 +307,53 @@ LinuxDriver_Freeze(const GSList *paths, + continue; + } + ++ if (fstatfs(fd, &fsbuf) == 0) { ++ fsInfo.fsid = fsbuf.f_fsid; ++ } else { ++ Debug(LGPFX "failed to get file system id for path '%s'.\n", path); ++ fsInfo.fsid = MISSING_FSID; ++ } + Debug(LGPFX "freezing path '%s' (fd=%d).\n", path, fd); + if (ioctl(fd, FIFREEZE) == -1) { + int ioctlerr = errno; ++ ++ close(fd); ++ Debug(LGPFX "freeze on '%s' returned: %d (%s)\n", ++ path, ioctlerr, strerror(ioctlerr)); ++ /* ++ * 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 ++ * attempt will fail. ++ */ ++ if (ioctlerr == EBUSY) { ++ if (LinuxFiFsIdMatch(DynBuf_Get(&fds), ++ DynBuf_GetSize(&fds), ++ &fsInfo.fsid)) { ++ /* ++ * We have previous knowledge of this file system by another ++ * mount point. Safe to ignore. ++ */ ++ Debug(LGPFX "skipping path '%s' - previously frozen", path); ++ continue; ++ } ++ /* ++ * It appears that this FS has been locked or frozen by another ++ * process. We cannot proceed with the quiesced snapshot request. ++ */ ++ Warning(LGPFX "'%s' appears locked or frozen by another process. " ++ "Cannot complete the quiesced snapshot request.\n", path); ++ } + /* + * If the ioctl does not exist, Linux will return ENOTTY. If it's not + * supported on the device, we get EOPNOTSUPP. Ignore the latter, + * since freezing does not make sense for all fs types, and some + * Linux fs drivers may not have been hooked up in the running kernel. +- * +- * Also ignore EBUSY since we may try to freeze the same superblock +- * more than once depending on the OS configuration (e.g., usage of +- * bind mounts). + */ +- close(fd); +- Debug(LGPFX "freeze on '%s' returned: %d (%s)\n", +- path, ioctlerr, strerror(ioctlerr)); +- if (ioctlerr != EBUSY && ioctlerr != EOPNOTSUPP) { ++ if (ioctlerr != EOPNOTSUPP) { + Debug(LGPFX "failed to freeze '%s': %d (%s)\n", + path, ioctlerr, strerror(ioctlerr)); + err = first && ioctlerr == ENOTTY ? SD_UNAVAILABLE : SD_ERROR; +@@ -282,7 +361,8 @@ LinuxDriver_Freeze(const GSList *paths, + } + } else { + Debug(LGPFX "successfully froze '%s' (fd=%d).\n", path, fd); +- if (!DynBuf_Append(&fds, &fd, sizeof fd)) { ++ fsInfo.fd = fd; ++ if (!DynBuf_Append(&fds, &fsInfo, sizeof fsInfo)) { + if (ioctl(fd, FITHAW) == -1) { + Warning(LGPFX "failed to thaw '%s': %d (%s)\n", + path, errno, strerror(errno)); diff --git a/SPECS/open-vm-tools.spec b/SPECS/open-vm-tools.spec index 605549a..ef61b25 100644 --- a/SPECS/open-vm-tools.spec +++ b/SPECS/open-vm-tools.spec @@ -32,7 +32,7 @@ Name: open-vm-tools Version: %{toolsversion} -Release: 2%{?dist}.alma +Release: 2%{?dist}.2.alma.1 Summary: Open Virtual Machine Tools for virtual machines hosted on VMware License: GPLv2 URL: https://github.com/vmware/%{name} @@ -54,6 +54,9 @@ ExclusiveArch: %{ix86} x86_64 aarch64 #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 +# 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 BuildRequires: autoconf BuildRequires: automake @@ -412,6 +415,9 @@ fi %{_bindir}/vmware-vgauth-smoketest %changelog +* Tue Sep 12 2023 Eduard Abdullin - 12.1.5-1.el8_8.2.alma.1 +- Track Linux filesystem id (FSID) for quiesced (frozen) filesystems + * Wed Jul 12 2023 Andrew Lukoshko - 12.1.5-2.el8_8.alma - [CISA Major Incident] CVE-2023-20867 open-vm-tools: authentication bypass vulnerability in the vgauth module