Skip to content

Commit ea49c88

Browse files
committed
Merge tag 'mkp-scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/mkp/scsi
Pull SCSI target fix from Martin Petersen: "This addresses an issue in the SCSI target subsystem. A connected initiator could specify IDs for any configured backing store device, not just the ones explicitly made visible to the host. The remedy is to honor the access control list when doing ID descriptor lookups" * tag 'mkp-scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/mkp/scsi: scsi: target: Fix XCOPY NAA identifier lookup
2 parents a0d54b4 + 2896c93 commit ea49c88

File tree

2 files changed

+71
-49
lines changed

2 files changed

+71
-49
lines changed

drivers/target/target_core_xcopy.c

Lines changed: 70 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -46,60 +46,83 @@ static int target_xcopy_gen_naa_ieee(struct se_device *dev, unsigned char *buf)
4646
return 0;
4747
}
4848

49-
struct xcopy_dev_search_info {
50-
const unsigned char *dev_wwn;
51-
struct se_device *found_dev;
52-
};
53-
49+
/**
50+
* target_xcopy_locate_se_dev_e4_iter - compare XCOPY NAA device identifiers
51+
*
52+
* @se_dev: device being considered for match
53+
* @dev_wwn: XCOPY requested NAA dev_wwn
54+
* @return: 1 on match, 0 on no-match
55+
*/
5456
static int target_xcopy_locate_se_dev_e4_iter(struct se_device *se_dev,
55-
void *data)
57+
const unsigned char *dev_wwn)
5658
{
57-
struct xcopy_dev_search_info *info = data;
5859
unsigned char tmp_dev_wwn[XCOPY_NAA_IEEE_REGEX_LEN];
5960
int rc;
6061

61-
if (!se_dev->dev_attrib.emulate_3pc)
62+
if (!se_dev->dev_attrib.emulate_3pc) {
63+
pr_debug("XCOPY: emulate_3pc disabled on se_dev %p\n", se_dev);
6264
return 0;
65+
}
6366

6467
memset(&tmp_dev_wwn[0], 0, XCOPY_NAA_IEEE_REGEX_LEN);
6568
target_xcopy_gen_naa_ieee(se_dev, &tmp_dev_wwn[0]);
6669

67-
rc = memcmp(&tmp_dev_wwn[0], info->dev_wwn, XCOPY_NAA_IEEE_REGEX_LEN);
68-
if (rc != 0)
69-
return 0;
70-
71-
info->found_dev = se_dev;
72-
pr_debug("XCOPY 0xe4: located se_dev: %p\n", se_dev);
73-
74-
rc = target_depend_item(&se_dev->dev_group.cg_item);
70+
rc = memcmp(&tmp_dev_wwn[0], dev_wwn, XCOPY_NAA_IEEE_REGEX_LEN);
7571
if (rc != 0) {
76-
pr_err("configfs_depend_item attempt failed: %d for se_dev: %p\n",
77-
rc, se_dev);
78-
return rc;
72+
pr_debug("XCOPY: skip non-matching: %*ph\n",
73+
XCOPY_NAA_IEEE_REGEX_LEN, tmp_dev_wwn);
74+
return 0;
7975
}
76+
pr_debug("XCOPY 0xe4: located se_dev: %p\n", se_dev);
8077

81-
pr_debug("Called configfs_depend_item for se_dev: %p se_dev->se_dev_group: %p\n",
82-
se_dev, &se_dev->dev_group);
8378
return 1;
8479
}
8580

86-
static int target_xcopy_locate_se_dev_e4(const unsigned char *dev_wwn,
87-
struct se_device **found_dev)
81+
static int target_xcopy_locate_se_dev_e4(struct se_session *sess,
82+
const unsigned char *dev_wwn,
83+
struct se_device **_found_dev,
84+
struct percpu_ref **_found_lun_ref)
8885
{
89-
struct xcopy_dev_search_info info;
90-
int ret;
91-
92-
memset(&info, 0, sizeof(info));
93-
info.dev_wwn = dev_wwn;
94-
95-
ret = target_for_each_device(target_xcopy_locate_se_dev_e4_iter, &info);
96-
if (ret == 1) {
97-
*found_dev = info.found_dev;
98-
return 0;
99-
} else {
100-
pr_debug_ratelimited("Unable to locate 0xe4 descriptor for EXTENDED_COPY\n");
101-
return -EINVAL;
86+
struct se_dev_entry *deve;
87+
struct se_node_acl *nacl;
88+
struct se_lun *this_lun = NULL;
89+
struct se_device *found_dev = NULL;
90+
91+
/* cmd with NULL sess indicates no associated $FABRIC_MOD */
92+
if (!sess)
93+
goto err_out;
94+
95+
pr_debug("XCOPY 0xe4: searching for: %*ph\n",
96+
XCOPY_NAA_IEEE_REGEX_LEN, dev_wwn);
97+
98+
nacl = sess->se_node_acl;
99+
rcu_read_lock();
100+
hlist_for_each_entry_rcu(deve, &nacl->lun_entry_hlist, link) {
101+
struct se_device *this_dev;
102+
int rc;
103+
104+
this_lun = rcu_dereference(deve->se_lun);
105+
this_dev = rcu_dereference_raw(this_lun->lun_se_dev);
106+
107+
rc = target_xcopy_locate_se_dev_e4_iter(this_dev, dev_wwn);
108+
if (rc) {
109+
if (percpu_ref_tryget_live(&this_lun->lun_ref))
110+
found_dev = this_dev;
111+
break;
112+
}
102113
}
114+
rcu_read_unlock();
115+
if (found_dev == NULL)
116+
goto err_out;
117+
118+
pr_debug("lun_ref held for se_dev: %p se_dev->se_dev_group: %p\n",
119+
found_dev, &found_dev->dev_group);
120+
*_found_dev = found_dev;
121+
*_found_lun_ref = &this_lun->lun_ref;
122+
return 0;
123+
err_out:
124+
pr_debug_ratelimited("Unable to locate 0xe4 descriptor for EXTENDED_COPY\n");
125+
return -EINVAL;
103126
}
104127

105128
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_descriptors(struct se_cmd *se_cmd,
246269

247270
switch (xop->op_origin) {
248271
case XCOL_SOURCE_RECV_OP:
249-
rc = target_xcopy_locate_se_dev_e4(xop->dst_tid_wwn,
250-
&xop->dst_dev);
272+
rc = target_xcopy_locate_se_dev_e4(se_cmd->se_sess,
273+
xop->dst_tid_wwn,
274+
&xop->dst_dev,
275+
&xop->remote_lun_ref);
251276
break;
252277
case XCOL_DEST_RECV_OP:
253-
rc = target_xcopy_locate_se_dev_e4(xop->src_tid_wwn,
254-
&xop->src_dev);
278+
rc = target_xcopy_locate_se_dev_e4(se_cmd->se_sess,
279+
xop->src_tid_wwn,
280+
&xop->src_dev,
281+
&xop->remote_lun_ref);
255282
break;
256283
default:
257284
pr_err("XCOPY CSCD descriptor IDs not found in CSCD list - "
@@ -391,18 +418,12 @@ static int xcopy_pt_get_cmd_state(struct se_cmd *se_cmd)
391418

392419
static void xcopy_pt_undepend_remotedev(struct xcopy_op *xop)
393420
{
394-
struct se_device *remote_dev;
395-
396421
if (xop->op_origin == XCOL_SOURCE_RECV_OP)
397-
remote_dev = xop->dst_dev;
422+
pr_debug("putting dst lun_ref for %p\n", xop->dst_dev);
398423
else
399-
remote_dev = xop->src_dev;
400-
401-
pr_debug("Calling configfs_undepend_item for"
402-
" remote_dev: %p remote_dev->dev_group: %p\n",
403-
remote_dev, &remote_dev->dev_group.cg_item);
424+
pr_debug("putting src lun_ref for %p\n", xop->src_dev);
404425

405-
target_undepend_item(&remote_dev->dev_group.cg_item);
426+
percpu_ref_put(xop->remote_lun_ref);
406427
}
407428

408429
static void xcopy_pt_release_cmd(struct se_cmd *se_cmd)

drivers/target/target_core_xcopy.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ struct xcopy_op {
2727
struct se_device *dst_dev;
2828
unsigned char dst_tid_wwn[XCOPY_NAA_IEEE_REGEX_LEN];
2929
unsigned char local_dev_wwn[XCOPY_NAA_IEEE_REGEX_LEN];
30+
struct percpu_ref *remote_lun_ref;
3031

3132
sector_t src_lba;
3233
sector_t dst_lba;

0 commit comments

Comments
 (0)