File 0004-ScaleIO-Prevent-usage-of-unsafe-volumes.patch of Package openstack-cinder
From 234aab19f1677a337abd4cc37ede5dc5e455f258 Mon Sep 17 00:00:00 2001
From: Eric Young <eric.young@dell.com>
Date: Thu, 22 Mar 2018 20:24:01 -0400
Subject: [PATCH] ScaleIO: Prevent usage of unsafe volumes
It is possible for volumes, created from storage pools
which have zero-padding disabled, to contain previous data. This
change prevents these volumes from being created by default. A
user can override this behavior by acknowleding the possibility
with a configuration option.
This is a squash of the four commits that led to the final state in
rocky to not allow the creation of any type of non-zero-padded volumes
to be created. This adds a config option that defaults to the safe
behavior. It is backporting a new config option, and a change in default
behavior, but it should be acceptable in this case so that the security
vulnerability can be addressed.
Closes-Bug: #1784871
Change-Id: I62f8f48b1624fc9abb7427bd4ca51f7873d35b96
Closes-bug: #1699573
(cherry picked from commit f0cef07bef5ea8ed29179ee3774df5f4a634ba86)
(cherry picked from commit 6309c097e653c5f8b40e0602950d0ef54a9efb37)
(cherry picked from commit 2dc52153215bb6a37532a959c5c98239be21bb56)
---
diff --git a/cinder/tests/unit/volume/drivers/emc/scaleio/mocks.py b/cinder/tests/unit/volume/drivers/emc/scaleio/mocks.py
index 4dee67d..9372d6d 100644
--- a/cinder/tests/unit/volume/drivers/emc/scaleio/mocks.py
+++ b/cinder/tests/unit/volume/drivers/emc/scaleio/mocks.py
@@ -70,6 +70,9 @@
def unmanage(self, volume):
pass
+ def _is_volume_creation_safe(self, _pd, _sp):
+ return True
+
class MockHTTPSResponse(requests.Response):
"""Mock HTTP Response
diff --git a/cinder/volume/drivers/emc/scaleio.py b/cinder/volume/drivers/emc/scaleio.py
index fba7945..b3e18ae 100644
--- a/cinder/volume/drivers/emc/scaleio.py
+++ b/cinder/volume/drivers/emc/scaleio.py
@@ -77,7 +77,13 @@
'driver. This replaces the general '
'max_over_subscription_ratio which has no effect '
'in this driver.'
- 'Maximum value allowed for ScaleIO is 10.0.')
+ 'Maximum value allowed for ScaleIO is 10.0.'),
+ cfg.BoolOpt('sio_allow_non_padded_volumes',
+ default=False,
+ help='Allow volumes to be created in Storage Pools '
+ 'when zero padding is disabled. This option should '
+ 'not be enabled if multiple tenants will utilize '
+ 'volumes from a shared Storage Pool.'),
]
CONF.register_opts(scaleio_opts)
@@ -322,6 +328,34 @@
{'id': id, 'name': encoded_name})
return encoded_name
+ def _is_volume_creation_safe(self,
+ protection_domain,
+ storage_pool):
+ """Checks if volume creation is safe or not.
+
+ Using volumes with zero padding disabled can lead to existing data
+ being read off of a newly created volume.
+ """
+ # if we have been told to allow unsafe volumes
+ if self.configuration.sio_allow_non_padded_volumes:
+ # Enabled regardless of type, so safe to proceed
+ return True
+
+ try:
+ properties = self._get_storage_pool_properties(protection_domain,
+ storage_pool)
+ padded = properties['zeroPaddingEnabled']
+ except Exception:
+ msg = (_("Unable to retrieve properties for pool, %(pool)s") %
+ {'pool': storage_pool})
+ raise exception.InvalidInput(reason=msg)
+
+ # zero padded storage pools are safe
+ if padded:
+ return True
+ # if we got here, it's unsafe
+ return False
+
def create_volume(self, volume):
"""Creates a scaleIO volume."""
self._check_volume_size(volume.size)
@@ -445,6 +479,23 @@
else:
provisioning = "ThickProvisioned"
+ allowed = self._is_volume_creation_safe(protection_domain_name,
+ storage_pool_name)
+ if not allowed:
+ # Do not allow thick volume creation on this backend.
+ # Volumes may leak data between tenants.
+ LOG.error(_LE("Volume creation rejected due to "
+ "zero padding being disabled for pool, "
+ "%(dom)s:%(pool)s. "
+ "This behaviour can be changed by setting "
+ "the configuration option "
+ "sio_allow_non_padded_volumes = True."),
+ {'dom': protection_domain_name,
+ 'pool': storage_pool_name})
+ msg = _("Volume creation rejected due to "
+ "unsafe backend configuration.")
+ raise exception.VolumeBackendAPIException(data=msg)
+
# units.Mi = 1024 ** 2
volume_size_kb = volume.size * units.Mi
params = {'protectionDomainId': domain_id,
diff --git a/releasenotes/notes/scaleio-zeropadding-a0273c56c4d14fca.yaml b/releasenotes/notes/scaleio-zeropadding-a0273c56c4d14fca.yaml
new file mode 100644
index 0000000..18f3c42
--- /dev/null
+++ b/releasenotes/notes/scaleio-zeropadding-a0273c56c4d14fca.yaml
@@ -0,0 +1,8 @@
+---
+security:
+ - |
+ Removed the ability to create volumes in a ScaleIO Storage Pool that has
+ zero-padding disabled. A new configuration option
+ ``sio_allow_non_padded_volumes`` has been added to override this new
+ behavior and allow unpadded volumes, but should not be enabled if multiple
+ tenants will utilize volumes from a shared Storage Pool.