diff options
author | Nicholas Bellinger <nab@linux-iscsi.org> | 2017-05-11 03:23:08 -0400 |
---|---|---|
committer | Nicholas Bellinger <nab@linux-iscsi.org> | 2017-05-11 04:01:05 -0400 |
commit | 984a9d4c40bed351a92ed31f0723a710444295da (patch) | |
tree | 8c6d4d75f51aa8e64a6c53e8f0891130c84184be /drivers | |
parent | bd2c52d733f126ff75f99c537a27655b2db07e28 (diff) |
Revert "target: Fix VERIFY and WRITE VERIFY command parsing"
This reverts commit 0e2eb7d12eaa8e391bf5615d4271bb87a649caaa
Author: Bart Van Assche <bart.vanassche@sandisk.com>
Date: Thu Mar 30 10:12:39 2017 -0700
target: Fix VERIFY and WRITE VERIFY command parsing
This patch broke existing behaviour for WRITE_VERIFY because
it dropped the original SCF_SCSI_DATA_CDB assignment for
bytchk = 0 so target_cmd_size_check() no longer rejected
this case, allowing an overflow case to trigger an OOPs
in iscsi-target.
Since the short term and long term fixes are still being
discussed, revert it for now since it's late in the merge
window and try again in v4.13-rc1.
Conflicts:
drivers/target/target_core_sbc.c
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/target/target_core_sbc.c | 74 |
1 files changed, 10 insertions, 64 deletions
diff --git a/drivers/target/target_core_sbc.c b/drivers/target/target_core_sbc.c index a0ad618f1b1a..4316f7b65fb7 100644 --- a/drivers/target/target_core_sbc.c +++ b/drivers/target/target_core_sbc.c | |||
@@ -831,60 +831,6 @@ sbc_check_dpofua(struct se_device *dev, struct se_cmd *cmd, unsigned char *cdb) | |||
831 | return 0; | 831 | return 0; |
832 | } | 832 | } |
833 | 833 | ||
834 | /** | ||
835 | * sbc_parse_verify - parse VERIFY, VERIFY_16 and WRITE VERIFY commands | ||
836 | * @cmd: (in) structure that describes the SCSI command to be parsed. | ||
837 | * @sectors: (out) Number of logical blocks on the storage medium that will be | ||
838 | * affected by the SCSI command. | ||
839 | * @bufflen: (out) Expected length of the SCSI Data-Out buffer. | ||
840 | */ | ||
841 | static sense_reason_t sbc_parse_verify(struct se_cmd *cmd, int *sectors, | ||
842 | u32 *bufflen) | ||
843 | { | ||
844 | struct se_device *dev = cmd->se_dev; | ||
845 | u8 *cdb = cmd->t_task_cdb; | ||
846 | u8 bytchk = (cdb[1] >> 1) & 3; | ||
847 | sense_reason_t ret; | ||
848 | |||
849 | switch (cdb[0]) { | ||
850 | case VERIFY: | ||
851 | case WRITE_VERIFY: | ||
852 | *sectors = transport_get_sectors_10(cdb); | ||
853 | cmd->t_task_lba = transport_lba_32(cdb); | ||
854 | break; | ||
855 | case VERIFY_16: | ||
856 | case WRITE_VERIFY_16: | ||
857 | *sectors = transport_get_sectors_16(cdb); | ||
858 | cmd->t_task_lba = transport_lba_64(cdb); | ||
859 | break; | ||
860 | default: | ||
861 | WARN_ON_ONCE(true); | ||
862 | return TCM_UNSUPPORTED_SCSI_OPCODE; | ||
863 | } | ||
864 | |||
865 | if (sbc_check_dpofua(dev, cmd, cdb)) | ||
866 | return TCM_INVALID_CDB_FIELD; | ||
867 | |||
868 | ret = sbc_check_prot(dev, cmd, cdb, *sectors, true); | ||
869 | if (ret) | ||
870 | return ret; | ||
871 | |||
872 | switch (bytchk) { | ||
873 | case 0: | ||
874 | *bufflen = 0; | ||
875 | break; | ||
876 | case 1: | ||
877 | *bufflen = sbc_get_size(cmd, *sectors); | ||
878 | cmd->se_cmd_flags |= SCF_SCSI_DATA_CDB; | ||
879 | break; | ||
880 | default: | ||
881 | pr_err("Unsupported BYTCHK value %d for SCSI opcode %#x\n", | ||
882 | bytchk, cdb[0]); | ||
883 | return TCM_INVALID_CDB_FIELD; | ||
884 | } | ||
885 | return TCM_NO_SENSE; | ||
886 | } | ||
887 | |||
888 | sense_reason_t | 834 | sense_reason_t |
889 | sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops) | 835 | sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops) |
890 | { | 836 | { |
@@ -952,6 +898,7 @@ sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops) | |||
952 | cmd->execute_cmd = sbc_execute_rw; | 898 | cmd->execute_cmd = sbc_execute_rw; |
953 | break; | 899 | break; |
954 | case WRITE_10: | 900 | case WRITE_10: |
901 | case WRITE_VERIFY: | ||
955 | sectors = transport_get_sectors_10(cdb); | 902 | sectors = transport_get_sectors_10(cdb); |
956 | cmd->t_task_lba = transport_lba_32(cdb); | 903 | cmd->t_task_lba = transport_lba_32(cdb); |
957 | 904 | ||
@@ -965,13 +912,6 @@ sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops) | |||
965 | cmd->se_cmd_flags |= SCF_SCSI_DATA_CDB; | 912 | cmd->se_cmd_flags |= SCF_SCSI_DATA_CDB; |
966 | cmd->execute_cmd = sbc_execute_rw; | 913 | cmd->execute_cmd = sbc_execute_rw; |
967 | break; | 914 | break; |
968 | case WRITE_VERIFY: | ||
969 | case WRITE_VERIFY_16: | ||
970 | ret = sbc_parse_verify(cmd, §ors, &size); | ||
971 | if (ret) | ||
972 | return ret; | ||
973 | cmd->execute_cmd = sbc_execute_rw; | ||
974 | goto check_lba; | ||
975 | case WRITE_12: | 915 | case WRITE_12: |
976 | sectors = transport_get_sectors_12(cdb); | 916 | sectors = transport_get_sectors_12(cdb); |
977 | cmd->t_task_lba = transport_lba_32(cdb); | 917 | cmd->t_task_lba = transport_lba_32(cdb); |
@@ -987,6 +927,7 @@ sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops) | |||
987 | cmd->execute_cmd = sbc_execute_rw; | 927 | cmd->execute_cmd = sbc_execute_rw; |
988 | break; | 928 | break; |
989 | case WRITE_16: | 929 | case WRITE_16: |
930 | case WRITE_VERIFY_16: | ||
990 | sectors = transport_get_sectors_16(cdb); | 931 | sectors = transport_get_sectors_16(cdb); |
991 | cmd->t_task_lba = transport_lba_64(cdb); | 932 | cmd->t_task_lba = transport_lba_64(cdb); |
992 | 933 | ||
@@ -1169,9 +1110,14 @@ sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops) | |||
1169 | break; | 1110 | break; |
1170 | case VERIFY: | 1111 | case VERIFY: |
1171 | case VERIFY_16: | 1112 | case VERIFY_16: |
1172 | ret = sbc_parse_verify(cmd, §ors, &size); | 1113 | size = 0; |
1173 | if (ret) | 1114 | if (cdb[0] == VERIFY) { |
1174 | return ret; | 1115 | sectors = transport_get_sectors_10(cdb); |
1116 | cmd->t_task_lba = transport_lba_32(cdb); | ||
1117 | } else { | ||
1118 | sectors = transport_get_sectors_16(cdb); | ||
1119 | cmd->t_task_lba = transport_lba_64(cdb); | ||
1120 | } | ||
1175 | cmd->execute_cmd = sbc_emulate_noop; | 1121 | cmd->execute_cmd = sbc_emulate_noop; |
1176 | goto check_lba; | 1122 | goto check_lba; |
1177 | case REZERO_UNIT: | 1123 | case REZERO_UNIT: |