open-iscsi / tcmu-runner

A daemon that handles the userspace side of the LIO TCM-User backstore.
Apache License 2.0
189 stars 148 forks source link

CVE-2020-28374: SCSI "EXTENDED COPY" (XCOPY) requests sent to a Linux SCSI target (LIO) allow an attacker to read or write anywhere on any LIO backstore #645

Closed sdelafond closed 3 years ago

sdelafond commented 3 years ago

More details are available at https://www.openwall.com/lists/oss-security/2021/01/12/12, but here's the full description:

SCSI "EXTENDED COPY" (XCOPY) requests sent to a Linux SCSI target (LIO) allow an
attacker to read or write anywhere on any LIO backstore configured on the
host, provided the attacker has access to one LUN and knowledge of the victim
backstore's vpd_unit_serial (AKA "wwn"). This is possible regardless of the
transport/HBA settings for the victim backstore.
- with vhost-scsi this can allow VM guests to read or write to images assigned
  to other qemu processes
- with iSCSI this allows CHAP, ACL and network portal isolation bypass
- backstores with no corresponding transport LUN mapping remain vulnerable
- all other LIO transports and backstores which allow for XCOPY processing by
  LIO's target_core_xcopy handler should be considered vulnerable
- tcmu-runner based user backstores are also vulnerable via a similar logic bug

This is due to the way that LIO behaves when processing XCOPY
copy-source/copy-destination (CSCD) descriptors; when attempting to match
CSCD descriptors with corresponding se_devices, target_xcopy_locate_se_dev_e4()
iterates over LIO's global devices list, which includes all configured
backstores, instead of only considering backstores which are exposed to the
initiator via transport layer ACL settings.

Similarly, when LIO is configured to forward SCSI requests to the user-space
tcmu-runner daemon (via target_core_user), tcmu-runner's xcopy_locate_udev()
iterates over all tcmu-runner devices, without considering any transport layer
restrictions.

SuSE has a patch available at https://bugzilla.suse.com/show_bug.cgi?id=1180676, and I'm also attaching it here. Please let me know if you'd like a proper PR instead:

@@ -, +, @@ 
---
 tcmur_cmd_handler.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)
--- a/tcmur_cmd_handler.c
+++ a/tcmur_cmd_handler.c
@@ -1349,6 +1349,18 @@ static int xcopy_parse_parameter_list(struct tcmu_device *dev,
        if (ret != TCMU_STS_OK)
                goto err;

+       /*
+        * tcmu-runner can't determine whether the device(s) referred to in an
+        * XCOPY request should be accessible to the initiator via transport
+        * settings, ACLs, etc. XXX Consequently, we need to fail any
+        * cross-device requests for safety reasons.
+        */
+       if (dev != xcopy->src_dev || dev != xcopy->dst_dev) {
+               tcmu_dev_err(dev, "Cross-device XCOPY not supported\n");
+               ret = TCMU_STS_CP_TGT_DEV_NOTCONN;
+               goto err;
+       }
+
        if (tcmu_dev_get_block_size(xcopy->src_dev) !=
            tcmu_dev_get_block_size(xcopy->dst_dev)) {
                tcmu_dev_err(dev, "The block size of src dev %u != dst dev %u\n",
-- 
carnil commented 3 years ago

Is addressed via https://github.com/open-iscsi/tcmu-runner/pull/644

dillaman commented 3 years ago

Resolved via #644