Skip to content

Commit 6d8e7e7

Browse files
logostmartinkpetersen
authored andcommitted
scsi: target: Fix protect handling in WRITE SAME(32)
WRITE SAME(32) command handling reads WRPROTECT at the wrong offset in 1st byte instead of 10th byte. Link: https://lore.kernel.org/r/[email protected] Fixes: afd73f1 ("target: Perform PROTECT sanity checks for WRITE_SAME") Signed-off-by: Dmitry Bogdanov <[email protected]> Signed-off-by: Martin K. Petersen <[email protected]>
1 parent e746f34 commit 6d8e7e7

File tree

1 file changed

+17
-18
lines changed

1 file changed

+17
-18
lines changed

drivers/target/target_core_sbc.c

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
#include "target_core_alua.h"
2626

2727
static sense_reason_t
28-
sbc_check_prot(struct se_device *, struct se_cmd *, unsigned char *, u32, bool);
28+
sbc_check_prot(struct se_device *, struct se_cmd *, unsigned char, u32, bool);
2929
static sense_reason_t sbc_execute_unmap(struct se_cmd *cmd);
3030

3131
static sense_reason_t
@@ -279,14 +279,14 @@ static inline unsigned long long transport_lba_64_ext(unsigned char *cdb)
279279
}
280280

281281
static sense_reason_t
282-
sbc_setup_write_same(struct se_cmd *cmd, unsigned char *flags, struct sbc_ops *ops)
282+
sbc_setup_write_same(struct se_cmd *cmd, unsigned char flags, struct sbc_ops *ops)
283283
{
284284
struct se_device *dev = cmd->se_dev;
285285
sector_t end_lba = dev->transport->get_blocks(dev) + 1;
286286
unsigned int sectors = sbc_get_write_same_sectors(cmd);
287287
sense_reason_t ret;
288288

289-
if ((flags[0] & 0x04) || (flags[0] & 0x02)) {
289+
if ((flags & 0x04) || (flags & 0x02)) {
290290
pr_err("WRITE_SAME PBDATA and LBDATA"
291291
" bits not supported for Block Discard"
292292
" Emulation\n");
@@ -308,15 +308,15 @@ sbc_setup_write_same(struct se_cmd *cmd, unsigned char *flags, struct sbc_ops *o
308308
}
309309

310310
/* We always have ANC_SUP == 0 so setting ANCHOR is always an error */
311-
if (flags[0] & 0x10) {
311+
if (flags & 0x10) {
312312
pr_warn("WRITE SAME with ANCHOR not supported\n");
313313
return TCM_INVALID_CDB_FIELD;
314314
}
315315
/*
316316
* Special case for WRITE_SAME w/ UNMAP=1 that ends up getting
317317
* translated into block discard requests within backend code.
318318
*/
319-
if (flags[0] & 0x08) {
319+
if (flags & 0x08) {
320320
if (!ops->execute_unmap)
321321
return TCM_UNSUPPORTED_SCSI_OPCODE;
322322

@@ -331,7 +331,7 @@ sbc_setup_write_same(struct se_cmd *cmd, unsigned char *flags, struct sbc_ops *o
331331
if (!ops->execute_write_same)
332332
return TCM_UNSUPPORTED_SCSI_OPCODE;
333333

334-
ret = sbc_check_prot(dev, cmd, &cmd->t_task_cdb[0], sectors, true);
334+
ret = sbc_check_prot(dev, cmd, flags >> 5, sectors, true);
335335
if (ret)
336336
return ret;
337337

@@ -717,10 +717,9 @@ sbc_set_prot_op_checks(u8 protect, bool fabric_prot, enum target_prot_type prot_
717717
}
718718

719719
static sense_reason_t
720-
sbc_check_prot(struct se_device *dev, struct se_cmd *cmd, unsigned char *cdb,
720+
sbc_check_prot(struct se_device *dev, struct se_cmd *cmd, unsigned char protect,
721721
u32 sectors, bool is_write)
722722
{
723-
u8 protect = cdb[1] >> 5;
724723
int sp_ops = cmd->se_sess->sup_prot_ops;
725724
int pi_prot_type = dev->dev_attrib.pi_prot_type;
726725
bool fabric_prot = false;
@@ -768,7 +767,7 @@ sbc_check_prot(struct se_device *dev, struct se_cmd *cmd, unsigned char *cdb,
768767
fallthrough;
769768
default:
770769
pr_err("Unable to determine pi_prot_type for CDB: 0x%02x "
771-
"PROTECT: 0x%02x\n", cdb[0], protect);
770+
"PROTECT: 0x%02x\n", cmd->t_task_cdb[0], protect);
772771
return TCM_INVALID_CDB_FIELD;
773772
}
774773

@@ -843,7 +842,7 @@ sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops)
843842
if (sbc_check_dpofua(dev, cmd, cdb))
844843
return TCM_INVALID_CDB_FIELD;
845844

846-
ret = sbc_check_prot(dev, cmd, cdb, sectors, false);
845+
ret = sbc_check_prot(dev, cmd, cdb[1] >> 5, sectors, false);
847846
if (ret)
848847
return ret;
849848

@@ -857,7 +856,7 @@ sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops)
857856
if (sbc_check_dpofua(dev, cmd, cdb))
858857
return TCM_INVALID_CDB_FIELD;
859858

860-
ret = sbc_check_prot(dev, cmd, cdb, sectors, false);
859+
ret = sbc_check_prot(dev, cmd, cdb[1] >> 5, sectors, false);
861860
if (ret)
862861
return ret;
863862

@@ -871,7 +870,7 @@ sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops)
871870
if (sbc_check_dpofua(dev, cmd, cdb))
872871
return TCM_INVALID_CDB_FIELD;
873872

874-
ret = sbc_check_prot(dev, cmd, cdb, sectors, false);
873+
ret = sbc_check_prot(dev, cmd, cdb[1] >> 5, sectors, false);
875874
if (ret)
876875
return ret;
877876

@@ -892,7 +891,7 @@ sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops)
892891
if (sbc_check_dpofua(dev, cmd, cdb))
893892
return TCM_INVALID_CDB_FIELD;
894893

895-
ret = sbc_check_prot(dev, cmd, cdb, sectors, true);
894+
ret = sbc_check_prot(dev, cmd, cdb[1] >> 5, sectors, true);
896895
if (ret)
897896
return ret;
898897

@@ -906,7 +905,7 @@ sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops)
906905
if (sbc_check_dpofua(dev, cmd, cdb))
907906
return TCM_INVALID_CDB_FIELD;
908907

909-
ret = sbc_check_prot(dev, cmd, cdb, sectors, true);
908+
ret = sbc_check_prot(dev, cmd, cdb[1] >> 5, sectors, true);
910909
if (ret)
911910
return ret;
912911

@@ -921,7 +920,7 @@ sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops)
921920
if (sbc_check_dpofua(dev, cmd, cdb))
922921
return TCM_INVALID_CDB_FIELD;
923922

924-
ret = sbc_check_prot(dev, cmd, cdb, sectors, true);
923+
ret = sbc_check_prot(dev, cmd, cdb[1] >> 5, sectors, true);
925924
if (ret)
926925
return ret;
927926

@@ -980,7 +979,7 @@ sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops)
980979
size = sbc_get_size(cmd, 1);
981980
cmd->t_task_lba = get_unaligned_be64(&cdb[12]);
982981

983-
ret = sbc_setup_write_same(cmd, &cdb[10], ops);
982+
ret = sbc_setup_write_same(cmd, cdb[10], ops);
984983
if (ret)
985984
return ret;
986985
break;
@@ -1079,7 +1078,7 @@ sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops)
10791078
size = sbc_get_size(cmd, 1);
10801079
cmd->t_task_lba = get_unaligned_be64(&cdb[2]);
10811080

1082-
ret = sbc_setup_write_same(cmd, &cdb[1], ops);
1081+
ret = sbc_setup_write_same(cmd, cdb[1], ops);
10831082
if (ret)
10841083
return ret;
10851084
break;
@@ -1097,7 +1096,7 @@ sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops)
10971096
* Follow sbcr26 with WRITE_SAME (10) and check for the existence
10981097
* of byte 1 bit 3 UNMAP instead of original reserved field
10991098
*/
1100-
ret = sbc_setup_write_same(cmd, &cdb[1], ops);
1099+
ret = sbc_setup_write_same(cmd, cdb[1], ops);
11011100
if (ret)
11021101
return ret;
11031102
break;

0 commit comments

Comments
 (0)