]> git.ipfire.org Git - thirdparty/open-vm-tools.git/commitdiff
Fix an invalid class pointer access when the VSS provider is not installed.
authorOliver Kurth <okurth@vmware.com>
Wed, 3 May 2017 00:15:52 +0000 (17:15 -0700)
committerOliver Kurth <okurth@vmware.com>
Wed, 3 May 2017 00:15:52 +0000 (17:15 -0700)
Customers may disable VSS support by not installing the VMware snapshot
provider, which may lead to the VSS provider being uninitialized, which in
turn can cause an invalid class pointer access during initialization
completion.

This change fixes the issue by checking the provider initialization status
before running the initialization completer.

open-vm-tools/services/plugins/vmbackup/stateMachine.c

index 2a7b16df7de56e2be0343ae6b9109f472ece4b47..5f530dd2faf2331b2065d80a04d1b3ab2b8888fb 100644 (file)
@@ -86,6 +86,8 @@ VM_EMBED_VERSION(VMTOOLSD_VERSION_STRING);
 #define VMBACKUP_CONFIG_GET_INT(config, key, defVal)        \
    VMTools_ConfigGetInteger(config, "vmbackup", key, defVal)
 
+#define VMBACKUP_CFG_ENABLEVSS      "enableVSS"
+
 static VmBackupState *gBackupState = NULL;
 
 static Bool
@@ -871,7 +873,7 @@ VmBackupStartCommon(RpcInData *data,
       const gchar *cfgEntry;
    } providers[] = {
 #if defined(_WIN32)
-      { VmBackup_NewVssProvider, "enableVSS" },
+      { VmBackup_NewVssProvider, VMBACKUP_CFG_ENABLEVSS},
 #endif
       { VmBackup_NewSyncDriverProvider, "enableSyncDriver" },
       { VmBackup_NewNullProvider, NULL },
@@ -884,8 +886,17 @@ VmBackupStartCommon(RpcInData *data,
           * only allow VSS provider
           */
 #if defined(_WIN32)
-         if (VMBACKUP_CONFIG_GET_BOOL(ctx->config, "enableVSS", TRUE)) {
+         if (VMBACKUP_CONFIG_GET_BOOL(ctx->config,
+                                      VMBACKUP_CFG_ENABLEVSS, TRUE)) {
             provider = VmBackup_NewVssProvider();
+            if (provider != NULL) {
+               completer = VmBackup_NewVssCompleter(provider);
+               if (completer == NULL) {
+                  g_warning("VSS completion helper cannot be initialized.");
+                  provider->release(provider);
+                  provider = NULL;
+               }
+            }
          }
 #elif defined(_LINUX) || defined(__linux__)
          /*
@@ -901,10 +912,6 @@ VmBackupStartCommon(RpcInData *data,
          /* If no quiescing is requested only allow null provider */
          provider = VmBackup_NewNullProvider();
       }
-      if (provider == NULL) {
-         g_warning("Requested quiescing cannot be initialized.");
-         goto error;
-      }
    } else {
       /* Instantiate the sync provider. */
       for (i = 0; i < ARRAYSIZE(providers); i++) {
@@ -913,24 +920,30 @@ VmBackupStartCommon(RpcInData *data,
          if (VMBACKUP_CONFIG_GET_BOOL(ctx->config, sp->cfgEntry, TRUE)) {
             provider = sp->ctor();
             if (provider != NULL) {
+#if defined(_WIN32)
+               if (sp->cfgEntry != NULL &&
+                   Str_Strcmp(sp->cfgEntry, VMBACKUP_CFG_ENABLEVSS) == 0) {
+                  completer = VmBackup_NewVssCompleter(provider);
+                  if (completer == NULL) {
+                     g_warning("VSS completion helper cannot be initialized.");
+                     provider->release(provider);
+                     provider = NULL;
+                     continue;
+                  }
+                  break;
+               }
+#else
                break;
+#endif
             }
          }
       }
    }
 
-   ASSERT(provider != NULL);
-
-#if defined(_WIN32)
-   if (VMBACKUP_CONFIG_GET_BOOL(ctx->config, "enableVSS", TRUE)) {
-      completer = VmBackup_NewVssCompleter(provider);
-      if (completer == NULL) {
-         provider->release(provider);
-         g_warning("Requested quiescing cannot be initialized.");
-         goto error;
-      }
+   if (provider == NULL) {
+      g_warning("Requested quiescing cannot be initialized.");
+      goto error;
    }
-#endif
 
    /* Instantiate the backup state and start the operation. */
    gBackupState->ctx = data->appCtx;