]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.10-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 12 Jan 2021 18:47:21 +0000 (19:47 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 12 Jan 2021 18:47:21 +0000 (19:47 +0100)
added patches:
scsi-target-fix-xcopy-naa-identifier-lookup.patch

queue-5.10/scsi-target-fix-xcopy-naa-identifier-lookup.patch [new file with mode: 0644]
queue-5.10/series

diff --git a/queue-5.10/scsi-target-fix-xcopy-naa-identifier-lookup.patch b/queue-5.10/scsi-target-fix-xcopy-naa-identifier-lookup.patch
new file mode 100644 (file)
index 0000000..2702e55
--- /dev/null
@@ -0,0 +1,208 @@
+From 2896c93811e39d63a4d9b63ccf12a8fbc226e5e4 Mon Sep 17 00:00:00 2001
+From: David Disseldorp <ddiss@suse.de>
+Date: Tue, 3 Nov 2020 02:21:58 +0100
+Subject: scsi: target: Fix XCOPY NAA identifier lookup
+
+From: David Disseldorp <ddiss@suse.de>
+
+commit 2896c93811e39d63a4d9b63ccf12a8fbc226e5e4 upstream.
+
+When attempting to match EXTENDED COPY CSCD descriptors with corresponding
+se_devices, target_xcopy_locate_se_dev_e4() currently iterates over LIO's
+global devices list which includes all configured backstores.
+
+This change ensures that only initiator-accessible backstores are
+considered during CSCD descriptor lookup, according to the session's
+se_node_acl LUN list.
+
+To avoid LUN removal race conditions, device pinning is changed from being
+configfs based to instead using the se_node_acl lun_ref.
+
+Reference: CVE-2020-28374
+Fixes: cbf031f425fd ("target: Add support for EXTENDED_COPY copy offload emulation")
+Reviewed-by: Lee Duncan <lduncan@suse.com>
+Signed-off-by: David Disseldorp <ddiss@suse.de>
+Signed-off-by: Mike Christie <michael.christie@oracle.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/target/target_core_xcopy.c |  119 +++++++++++++++++++++----------------
+ drivers/target/target_core_xcopy.h |    1 
+ 2 files changed, 71 insertions(+), 49 deletions(-)
+
+--- a/drivers/target/target_core_xcopy.c
++++ b/drivers/target/target_core_xcopy.c
+@@ -46,60 +46,83 @@ static int target_xcopy_gen_naa_ieee(str
+       return 0;
+ }
+-struct xcopy_dev_search_info {
+-      const unsigned char *dev_wwn;
+-      struct se_device *found_dev;
+-};
+-
++/**
++ * target_xcopy_locate_se_dev_e4_iter - compare XCOPY NAA device identifiers
++ *
++ * @se_dev: device being considered for match
++ * @dev_wwn: XCOPY requested NAA dev_wwn
++ * @return: 1 on match, 0 on no-match
++ */
+ static int target_xcopy_locate_se_dev_e4_iter(struct se_device *se_dev,
+-                                            void *data)
++                                            const unsigned char *dev_wwn)
+ {
+-      struct xcopy_dev_search_info *info = data;
+       unsigned char tmp_dev_wwn[XCOPY_NAA_IEEE_REGEX_LEN];
+       int rc;
+-      if (!se_dev->dev_attrib.emulate_3pc)
++      if (!se_dev->dev_attrib.emulate_3pc) {
++              pr_debug("XCOPY: emulate_3pc disabled on se_dev %p\n", se_dev);
+               return 0;
++      }
+       memset(&tmp_dev_wwn[0], 0, XCOPY_NAA_IEEE_REGEX_LEN);
+       target_xcopy_gen_naa_ieee(se_dev, &tmp_dev_wwn[0]);
+-      rc = memcmp(&tmp_dev_wwn[0], info->dev_wwn, XCOPY_NAA_IEEE_REGEX_LEN);
+-      if (rc != 0)
+-              return 0;
+-
+-      info->found_dev = se_dev;
+-      pr_debug("XCOPY 0xe4: located se_dev: %p\n", se_dev);
+-
+-      rc = target_depend_item(&se_dev->dev_group.cg_item);
++      rc = memcmp(&tmp_dev_wwn[0], dev_wwn, XCOPY_NAA_IEEE_REGEX_LEN);
+       if (rc != 0) {
+-              pr_err("configfs_depend_item attempt failed: %d for se_dev: %p\n",
+-                     rc, se_dev);
+-              return rc;
++              pr_debug("XCOPY: skip non-matching: %*ph\n",
++                       XCOPY_NAA_IEEE_REGEX_LEN, tmp_dev_wwn);
++              return 0;
+       }
++      pr_debug("XCOPY 0xe4: located se_dev: %p\n", se_dev);
+-      pr_debug("Called configfs_depend_item for se_dev: %p se_dev->se_dev_group: %p\n",
+-               se_dev, &se_dev->dev_group);
+       return 1;
+ }
+-static int target_xcopy_locate_se_dev_e4(const unsigned char *dev_wwn,
+-                                      struct se_device **found_dev)
++static int target_xcopy_locate_se_dev_e4(struct se_session *sess,
++                                      const unsigned char *dev_wwn,
++                                      struct se_device **_found_dev,
++                                      struct percpu_ref **_found_lun_ref)
+ {
+-      struct xcopy_dev_search_info info;
+-      int ret;
+-
+-      memset(&info, 0, sizeof(info));
+-      info.dev_wwn = dev_wwn;
+-
+-      ret = target_for_each_device(target_xcopy_locate_se_dev_e4_iter, &info);
+-      if (ret == 1) {
+-              *found_dev = info.found_dev;
+-              return 0;
+-      } else {
+-              pr_debug_ratelimited("Unable to locate 0xe4 descriptor for EXTENDED_COPY\n");
+-              return -EINVAL;
++      struct se_dev_entry *deve;
++      struct se_node_acl *nacl;
++      struct se_lun *this_lun = NULL;
++      struct se_device *found_dev = NULL;
++
++      /* cmd with NULL sess indicates no associated $FABRIC_MOD */
++      if (!sess)
++              goto err_out;
++
++      pr_debug("XCOPY 0xe4: searching for: %*ph\n",
++               XCOPY_NAA_IEEE_REGEX_LEN, dev_wwn);
++
++      nacl = sess->se_node_acl;
++      rcu_read_lock();
++      hlist_for_each_entry_rcu(deve, &nacl->lun_entry_hlist, link) {
++              struct se_device *this_dev;
++              int rc;
++
++              this_lun = rcu_dereference(deve->se_lun);
++              this_dev = rcu_dereference_raw(this_lun->lun_se_dev);
++
++              rc = target_xcopy_locate_se_dev_e4_iter(this_dev, dev_wwn);
++              if (rc) {
++                      if (percpu_ref_tryget_live(&this_lun->lun_ref))
++                              found_dev = this_dev;
++                      break;
++              }
+       }
++      rcu_read_unlock();
++      if (found_dev == NULL)
++              goto err_out;
++
++      pr_debug("lun_ref held for se_dev: %p se_dev->se_dev_group: %p\n",
++               found_dev, &found_dev->dev_group);
++      *_found_dev = found_dev;
++      *_found_lun_ref = &this_lun->lun_ref;
++      return 0;
++err_out:
++      pr_debug_ratelimited("Unable to locate 0xe4 descriptor for EXTENDED_COPY\n");
++      return -EINVAL;
+ }
+ static int target_xcopy_parse_tiddesc_e4(struct se_cmd *se_cmd, struct xcopy_op *xop,
+@@ -246,12 +269,16 @@ static int target_xcopy_parse_target_des
+       switch (xop->op_origin) {
+       case XCOL_SOURCE_RECV_OP:
+-              rc = target_xcopy_locate_se_dev_e4(xop->dst_tid_wwn,
+-                                              &xop->dst_dev);
++              rc = target_xcopy_locate_se_dev_e4(se_cmd->se_sess,
++                                              xop->dst_tid_wwn,
++                                              &xop->dst_dev,
++                                              &xop->remote_lun_ref);
+               break;
+       case XCOL_DEST_RECV_OP:
+-              rc = target_xcopy_locate_se_dev_e4(xop->src_tid_wwn,
+-                                              &xop->src_dev);
++              rc = target_xcopy_locate_se_dev_e4(se_cmd->se_sess,
++                                              xop->src_tid_wwn,
++                                              &xop->src_dev,
++                                              &xop->remote_lun_ref);
+               break;
+       default:
+               pr_err("XCOPY CSCD descriptor IDs not found in CSCD list - "
+@@ -391,18 +418,12 @@ static int xcopy_pt_get_cmd_state(struct
+ static void xcopy_pt_undepend_remotedev(struct xcopy_op *xop)
+ {
+-      struct se_device *remote_dev;
+-
+       if (xop->op_origin == XCOL_SOURCE_RECV_OP)
+-              remote_dev = xop->dst_dev;
++              pr_debug("putting dst lun_ref for %p\n", xop->dst_dev);
+       else
+-              remote_dev = xop->src_dev;
+-
+-      pr_debug("Calling configfs_undepend_item for"
+-                " remote_dev: %p remote_dev->dev_group: %p\n",
+-                remote_dev, &remote_dev->dev_group.cg_item);
++              pr_debug("putting src lun_ref for %p\n", xop->src_dev);
+-      target_undepend_item(&remote_dev->dev_group.cg_item);
++      percpu_ref_put(xop->remote_lun_ref);
+ }
+ static void xcopy_pt_release_cmd(struct se_cmd *se_cmd)
+--- a/drivers/target/target_core_xcopy.h
++++ b/drivers/target/target_core_xcopy.h
+@@ -27,6 +27,7 @@ struct xcopy_op {
+       struct se_device *dst_dev;
+       unsigned char dst_tid_wwn[XCOPY_NAA_IEEE_REGEX_LEN];
+       unsigned char local_dev_wwn[XCOPY_NAA_IEEE_REGEX_LEN];
++      struct percpu_ref *remote_lun_ref;
+       sector_t src_lba;
+       sector_t dst_lba;
index 07afe283ab35a770f946365fd9dcf53efe808b88..9bfa27d6c72c40c628e0d2f0ce91588896a730e2 100644 (file)
@@ -140,3 +140,4 @@ x86-mtrr-correct-the-range-check-before-performing-mtrr-type-lookups.patch
 kvm-x86-fix-shift-out-of-bounds-reported-by-ubsan.patch
 xsk-fix-memory-leak-for-failed-bind.patch
 rtlwifi-rise-completion-at-the-last-step-of-firmware-callback.patch
+scsi-target-fix-xcopy-naa-identifier-lookup.patch