diff options
| -rw-r--r-- | drivers/target/target_core_spc.c | 32 |
1 files changed, 16 insertions, 16 deletions
diff --git a/drivers/target/target_core_spc.c b/drivers/target/target_core_spc.c index 556ea1b2cdd8..f87d4cef6d39 100644 --- a/drivers/target/target_core_spc.c +++ b/drivers/target/target_core_spc.c | |||
| @@ -1203,17 +1203,13 @@ sense_reason_t spc_emulate_report_luns(struct se_cmd *cmd) | |||
| 1203 | struct se_dev_entry *deve; | 1203 | struct se_dev_entry *deve; |
| 1204 | struct se_session *sess = cmd->se_sess; | 1204 | struct se_session *sess = cmd->se_sess; |
| 1205 | struct se_node_acl *nacl; | 1205 | struct se_node_acl *nacl; |
| 1206 | struct scsi_lun slun; | ||
| 1206 | unsigned char *buf; | 1207 | unsigned char *buf; |
| 1207 | u32 lun_count = 0, offset = 8; | 1208 | u32 lun_count = 0, offset = 8; |
| 1208 | 1209 | __be32 len; | |
| 1209 | if (cmd->data_length < 16) { | ||
| 1210 | pr_warn("REPORT LUNS allocation length %u too small\n", | ||
| 1211 | cmd->data_length); | ||
| 1212 | return TCM_INVALID_CDB_FIELD; | ||
| 1213 | } | ||
| 1214 | 1210 | ||
| 1215 | buf = transport_kmap_data_sg(cmd); | 1211 | buf = transport_kmap_data_sg(cmd); |
| 1216 | if (!buf) | 1212 | if (cmd->data_length && !buf) |
| 1217 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | 1213 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
| 1218 | 1214 | ||
| 1219 | /* | 1215 | /* |
| @@ -1234,10 +1230,12 @@ sense_reason_t spc_emulate_report_luns(struct se_cmd *cmd) | |||
| 1234 | * See SPC2-R20 7.19. | 1230 | * See SPC2-R20 7.19. |
| 1235 | */ | 1231 | */ |
| 1236 | lun_count++; | 1232 | lun_count++; |
| 1237 | if ((offset + 8) > cmd->data_length) | 1233 | if (offset >= cmd->data_length) |
| 1238 | continue; | 1234 | continue; |
| 1239 | 1235 | ||
| 1240 | int_to_scsilun(deve->mapped_lun, (struct scsi_lun *)&buf[offset]); | 1236 | int_to_scsilun(deve->mapped_lun, &slun); |
| 1237 | memcpy(buf + offset, &slun, | ||
| 1238 | min(8u, cmd->data_length - offset)); | ||
| 1241 | offset += 8; | 1239 | offset += 8; |
| 1242 | } | 1240 | } |
| 1243 | rcu_read_unlock(); | 1241 | rcu_read_unlock(); |
| @@ -1250,16 +1248,18 @@ done: | |||
| 1250 | * If no LUNs are accessible, report virtual LUN 0. | 1248 | * If no LUNs are accessible, report virtual LUN 0. |
| 1251 | */ | 1249 | */ |
| 1252 | if (lun_count == 0) { | 1250 | if (lun_count == 0) { |
| 1253 | int_to_scsilun(0, (struct scsi_lun *)&buf[offset]); | 1251 | int_to_scsilun(0, &slun); |
| 1252 | if (cmd->data_length > 8) | ||
| 1253 | memcpy(buf + offset, &slun, | ||
| 1254 | min(8u, cmd->data_length - offset)); | ||
| 1254 | lun_count = 1; | 1255 | lun_count = 1; |
| 1255 | } | 1256 | } |
| 1256 | 1257 | ||
| 1257 | lun_count *= 8; | 1258 | if (buf) { |
| 1258 | buf[0] = ((lun_count >> 24) & 0xff); | 1259 | len = cpu_to_be32(lun_count * 8); |
| 1259 | buf[1] = ((lun_count >> 16) & 0xff); | 1260 | memcpy(buf, &len, min_t(int, sizeof len, cmd->data_length)); |
| 1260 | buf[2] = ((lun_count >> 8) & 0xff); | 1261 | transport_kunmap_data_sg(cmd); |
| 1261 | buf[3] = (lun_count & 0xff); | 1262 | } |
| 1262 | transport_kunmap_data_sg(cmd); | ||
| 1263 | 1263 | ||
| 1264 | target_complete_cmd_with_length(cmd, GOOD, 8 + lun_count * 8); | 1264 | target_complete_cmd_with_length(cmd, GOOD, 8 + lun_count * 8); |
| 1265 | return 0; | 1265 | return 0; |
