From: Greg Kroah-Hartman Date: Fri, 9 Dec 2011 22:06:20 +0000 (-0800) Subject: 3.1 patches X-Git-Tag: v3.0.14~16 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=04d68239550ab7cb2bcd738cca55e53d566cd215;p=thirdparty%2Fkernel%2Fstable-queue.git 3.1 patches added patches: iscsi-target-add-missing-f_bit-for-iscsi_tm_rsp.patch iscsi-target-fix-residual-count-hanlding-remove-iscsi_cmd-residual_count.patch target-file-walk-properly-over-sg-list.patch target-fix-page-length-in-emulated-inquiry-vpd-page-86h.patch target-handle-0-correctly-in-transport_get_sectors_6.patch target-reject-scsi-data-overflow-for-fabrics-using-transport_generic_map_mem_to_cmd.patch --- diff --git a/queue-3.1/iscsi-target-add-missing-f_bit-for-iscsi_tm_rsp.patch b/queue-3.1/iscsi-target-add-missing-f_bit-for-iscsi_tm_rsp.patch new file mode 100644 index 00000000000..561f54cf969 --- /dev/null +++ b/queue-3.1/iscsi-target-add-missing-f_bit-for-iscsi_tm_rsp.patch @@ -0,0 +1,33 @@ +From 7ae0b1038f9f7d4c91e9afd4dbbc98210bf1a241 Mon Sep 17 00:00:00 2001 +From: Nicholas Bellinger +Date: Sun, 27 Nov 2011 22:25:14 -0800 +Subject: iscsi-target: Add missing F_BIT for iscsi_tm_rsp + +From: Nicholas Bellinger + +commit 7ae0b1038f9f7d4c91e9afd4dbbc98210bf1a241 upstream. + +This patch sets the missing ISCSI_FLAG_CMD_FINAL bit in +iscsit_send_task_mgt_rsp() for a struct iscsi_tm_rsp PDU. + +This usage is hardcoded for all TM response PDUs in RFC-3720 +section 10.6. + +Reported-by: whucecil +Signed-off-by: Nicholas Bellinger +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/target/iscsi/iscsi_target.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/target/iscsi/iscsi_target.c ++++ b/drivers/target/iscsi/iscsi_target.c +@@ -3134,6 +3134,7 @@ static int iscsit_send_task_mgt_rsp( + hdr = (struct iscsi_tm_rsp *) cmd->pdu; + memset(hdr, 0, ISCSI_HDR_LEN); + hdr->opcode = ISCSI_OP_SCSI_TMFUNC_RSP; ++ hdr->flags = ISCSI_FLAG_CMD_FINAL; + hdr->response = iscsit_convert_tcm_tmr_rsp(se_tmr); + hdr->itt = cpu_to_be32(cmd->init_task_tag); + cmd->stat_sn = conn->stat_sn++; diff --git a/queue-3.1/iscsi-target-fix-residual-count-hanlding-remove-iscsi_cmd-residual_count.patch b/queue-3.1/iscsi-target-fix-residual-count-hanlding-remove-iscsi_cmd-residual_count.patch new file mode 100644 index 00000000000..dd4afb5f60c --- /dev/null +++ b/queue-3.1/iscsi-target-fix-residual-count-hanlding-remove-iscsi_cmd-residual_count.patch @@ -0,0 +1,75 @@ +From 7e46cf02687e40197ae07c623e660be2a2720064 Mon Sep 17 00:00:00 2001 +From: Nicholas Bellinger +Date: Tue, 15 Nov 2011 23:59:00 -0800 +Subject: iscsi-target: Fix residual count hanlding + remove iscsi_cmd->residual_count + +From: Nicholas Bellinger + +commit 7e46cf02687e40197ae07c623e660be2a2720064 upstream. + +This patch fixes iscsi-target handling of underflow where residual data is +causing an OOPs by using the incorrect iscsi_cmd_t->data_length initially +assigned in iscsit_allocate_se_cmd(). It resets iscsi_cmd_t->data_length +from se_cmd_t->data_length after transport_generic_allocate_tasks() +has been invoked in iscsit_handle_scsi_cmd() RX context, and converts +iscsi_cmd->residual_count usage to access iscsi_cmd->se_cmd.residual_count +to get the proper residual count set by target-core. + +Reported-by: +Cc: Christoph Hellwig +Cc: Andy Grover +Signed-off-by: Nicholas Bellinger +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/target/iscsi/iscsi_target.c | 10 ++++++---- + drivers/target/iscsi/iscsi_target_core.h | 1 - + 2 files changed, 6 insertions(+), 5 deletions(-) + +--- a/drivers/target/iscsi/iscsi_target.c ++++ b/drivers/target/iscsi/iscsi_target.c +@@ -1043,6 +1043,8 @@ done: + */ + send_check_condition = 1; + } else { ++ cmd->data_length = cmd->se_cmd.data_length; ++ + if (iscsit_decide_list_to_build(cmd, payload_length) < 0) + return iscsit_add_reject_from_cmd( + ISCSI_REASON_BOOKMARK_NO_RESOURCES, +@@ -2512,10 +2514,10 @@ static int iscsit_send_data_in( + if (hdr->flags & ISCSI_FLAG_DATA_STATUS) { + if (cmd->se_cmd.se_cmd_flags & SCF_OVERFLOW_BIT) { + hdr->flags |= ISCSI_FLAG_DATA_OVERFLOW; +- hdr->residual_count = cpu_to_be32(cmd->residual_count); ++ hdr->residual_count = cpu_to_be32(cmd->se_cmd.residual_count); + } else if (cmd->se_cmd.se_cmd_flags & SCF_UNDERFLOW_BIT) { + hdr->flags |= ISCSI_FLAG_DATA_UNDERFLOW; +- hdr->residual_count = cpu_to_be32(cmd->residual_count); ++ hdr->residual_count = cpu_to_be32(cmd->se_cmd.residual_count); + } + } + hton24(hdr->dlength, datain.length); +@@ -3017,10 +3019,10 @@ static int iscsit_send_status( + hdr->flags |= ISCSI_FLAG_CMD_FINAL; + if (cmd->se_cmd.se_cmd_flags & SCF_OVERFLOW_BIT) { + hdr->flags |= ISCSI_FLAG_CMD_OVERFLOW; +- hdr->residual_count = cpu_to_be32(cmd->residual_count); ++ hdr->residual_count = cpu_to_be32(cmd->se_cmd.residual_count); + } else if (cmd->se_cmd.se_cmd_flags & SCF_UNDERFLOW_BIT) { + hdr->flags |= ISCSI_FLAG_CMD_UNDERFLOW; +- hdr->residual_count = cpu_to_be32(cmd->residual_count); ++ hdr->residual_count = cpu_to_be32(cmd->se_cmd.residual_count); + } + hdr->response = cmd->iscsi_response; + hdr->cmd_status = cmd->se_cmd.scsi_status; +--- a/drivers/target/iscsi/iscsi_target_core.h ++++ b/drivers/target/iscsi/iscsi_target_core.h +@@ -395,7 +395,6 @@ struct iscsi_cmd { + u32 pdu_send_order; + /* Current struct iscsi_pdu in struct iscsi_cmd->pdu_list */ + u32 pdu_start; +- u32 residual_count; + /* Next struct iscsi_seq to send in struct iscsi_cmd->seq_list */ + u32 seq_send_order; + /* Number of struct iscsi_seq in struct iscsi_cmd->seq_list */ diff --git a/queue-3.1/series b/queue-3.1/series index 8328c6a6feb..0c729c852e9 100644 --- a/queue-3.1/series +++ b/queue-3.1/series @@ -18,3 +18,9 @@ mm-ensure-that-pfn_valid-is-called-once-per-pageblock-when-reserving-pageblocks. mm-vmalloc-check-for-page-allocation-failure-before-vmlist-insertion.patch fix-apparmor-dereferencing-potentially-freed-dentry-sanitize-__d_path-api.patch tomoyo-fix-pathname-handling-of-disconnected-paths.patch +target-reject-scsi-data-overflow-for-fabrics-using-transport_generic_map_mem_to_cmd.patch +iscsi-target-fix-residual-count-hanlding-remove-iscsi_cmd-residual_count.patch +target-handle-0-correctly-in-transport_get_sectors_6.patch +target-fix-page-length-in-emulated-inquiry-vpd-page-86h.patch +iscsi-target-add-missing-f_bit-for-iscsi_tm_rsp.patch +target-file-walk-properly-over-sg-list.patch diff --git a/queue-3.1/target-file-walk-properly-over-sg-list.patch b/queue-3.1/target-file-walk-properly-over-sg-list.patch new file mode 100644 index 00000000000..b74443b9ab0 --- /dev/null +++ b/queue-3.1/target-file-walk-properly-over-sg-list.patch @@ -0,0 +1,63 @@ +From 9649fa1b8764f64c8cc4293e197e14cd46fe7205 Mon Sep 17 00:00:00 2001 +From: Sebastian Andrzej Siewior +Date: Mon, 28 Nov 2011 12:33:10 +0100 +Subject: target/file: walk properly over sg list + +From: Sebastian Andrzej Siewior + +commit 9649fa1b8764f64c8cc4293e197e14cd46fe7205 upstream. + +This patch changes fileio to use for_each_sg() when walking se_task->task_sg +memory passed into from loopback LLD struct scsi_cmnd scatterlist memory. + +This addresses an issue where FILEIO backends with loopback where hitting the +following OOPs with mkfs.ext2: + +|kernel BUG at include/linux/scatterlist.h:97! +|invalid opcode: 0000 [#1] PREEMPT SMP +|Modules linked in: sd_mod tcm_loop target_core_stgt scsi_tgt target_core_pscsi target_core_file target_core_iblock target_core_mod configfs scsi_mod +| +|Pid: 671, comm: LIO_fileio Not tainted 3.1.0-rc10+ #139 Bochs Bochs +|EIP: 0060:[] EFLAGS: 00010202 CPU: 0 +|EIP is at fd_do_task+0x396/0x420 [target_core_file] +| [] __transport_execute_tasks+0xd4/0x190 [target_core_mod] +| [] transport_execute_tasks+0x3c/0xf0 [target_core_mod] +|EIP: [] fd_do_task+0x396/0x420 [target_core_file] SS:ESP 0068:dea47e90 + +Signed-off-by: Sebastian Andrzej Siewior +Cc: Christoph Hellwig +Signed-off-by: Nicholas Bellinger +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/target/target_core_file.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +--- a/drivers/target/target_core_file.c ++++ b/drivers/target/target_core_file.c +@@ -288,9 +288,9 @@ static int fd_do_readv(struct se_task *t + return -ENOMEM; + } + +- for (i = 0; i < task->task_sg_nents; i++) { +- iov[i].iov_len = sg[i].length; +- iov[i].iov_base = sg_virt(&sg[i]); ++ for_each_sg(task->task_sg, sg, task->task_sg_nents, i) { ++ iov[i].iov_len = sg->length; ++ iov[i].iov_base = sg_virt(sg); + } + + old_fs = get_fs(); +@@ -340,9 +340,9 @@ static int fd_do_writev(struct se_task * + return -ENOMEM; + } + +- for (i = 0; i < task->task_sg_nents; i++) { +- iov[i].iov_len = sg[i].length; +- iov[i].iov_base = sg_virt(&sg[i]); ++ for_each_sg(task->task_sg, sg, task->task_sg_nents, i) { ++ iov[i].iov_len = sg->length; ++ iov[i].iov_base = sg_virt(sg); + } + + old_fs = get_fs(); diff --git a/queue-3.1/target-fix-page-length-in-emulated-inquiry-vpd-page-86h.patch b/queue-3.1/target-fix-page-length-in-emulated-inquiry-vpd-page-86h.patch new file mode 100644 index 00000000000..3d68dfa4d9e --- /dev/null +++ b/queue-3.1/target-fix-page-length-in-emulated-inquiry-vpd-page-86h.patch @@ -0,0 +1,30 @@ +From 1289a0571c037b4757f60597d646aedb70361ec3 Mon Sep 17 00:00:00 2001 +From: Roland Dreier +Date: Tue, 22 Nov 2011 13:51:34 -0800 +Subject: target: Fix page length in emulated INQUIRY VPD page 86h + +From: Roland Dreier + +commit 1289a0571c037b4757f60597d646aedb70361ec3 upstream. + +The LSB of the page length is at offset 3, not 2. + +Signed-off-by: Roland Dreier +Signed-off-by: Nicholas Bellinger +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/target/target_core_cdb.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/target/target_core_cdb.c ++++ b/drivers/target/target_core_cdb.c +@@ -477,7 +477,7 @@ target_emulate_evpd_86(struct se_cmd *cm + if (cmd->data_length < 60) + return 0; + +- buf[2] = 0x3c; ++ buf[3] = 0x3c; + /* Set HEADSUP, ORDSUP, SIMPSUP */ + buf[5] = 0x07; + diff --git a/queue-3.1/target-handle-0-correctly-in-transport_get_sectors_6.patch b/queue-3.1/target-handle-0-correctly-in-transport_get_sectors_6.patch new file mode 100644 index 00000000000..f5e5f3655a9 --- /dev/null +++ b/queue-3.1/target-handle-0-correctly-in-transport_get_sectors_6.patch @@ -0,0 +1,46 @@ +From 9b5cd7f37e1e018432111333e2a67f78ba41edfe Mon Sep 17 00:00:00 2001 +From: Roland Dreier +Date: Tue, 22 Nov 2011 13:51:33 -0800 +Subject: target: Handle 0 correctly in transport_get_sectors_6() + +From: Roland Dreier + +commit 9b5cd7f37e1e018432111333e2a67f78ba41edfe upstream. + +SBC-3 says: + + A TRANSFER LENGTH field set to zero specifies that 256 logical + blocks shall be written. Any other value specifies the number + of logical blocks that shall be written. + +The old code was always just returning the value in the TRANSFER LENGTH +byte. Fix this to return 256 if the byte is 0. + +Signed-off-by: Roland Dreier +Signed-off-by: Nicholas Bellinger +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/target/target_core_transport.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +--- a/drivers/target/target_core_transport.c ++++ b/drivers/target/target_core_transport.c +@@ -2562,10 +2562,15 @@ static inline u32 transport_get_sectors_ + + /* + * Everything else assume TYPE_DISK Sector CDB location. +- * Use 8-bit sector value. ++ * Use 8-bit sector value. SBC-3 says: ++ * ++ * A TRANSFER LENGTH field set to zero specifies that 256 ++ * logical blocks shall be written. Any other value ++ * specifies the number of logical blocks that shall be ++ * written. + */ + type_disk: +- return (u32)cdb[4]; ++ return cdb[4] ? : 256; + } + + static inline u32 transport_get_sectors_10( diff --git a/queue-3.1/target-reject-scsi-data-overflow-for-fabrics-using-transport_generic_map_mem_to_cmd.patch b/queue-3.1/target-reject-scsi-data-overflow-for-fabrics-using-transport_generic_map_mem_to_cmd.patch new file mode 100644 index 00000000000..7706857770a --- /dev/null +++ b/queue-3.1/target-reject-scsi-data-overflow-for-fabrics-using-transport_generic_map_mem_to_cmd.patch @@ -0,0 +1,48 @@ +From fef58a6096770ed6ab49103a430cc755254a74d9 Mon Sep 17 00:00:00 2001 +From: Nicholas Bellinger +Date: Tue, 15 Nov 2011 22:13:24 -0800 +Subject: target: Reject SCSI data overflow for fabrics using transport_generic_map_mem_to_cmd + +From: Nicholas Bellinger + +commit fef58a6096770ed6ab49103a430cc755254a74d9 upstream. + +This patch changes transport_generic_map_mem_to_cmd() to reject SCSI data +overflow and to send exception status with CHECK_CONDITION + TCM_INVALID_CDB_FIELD +for fabrics that are passing a pre-populated struct scatterlist (eg: tcm_loop +and iscsi-target) being mapped into se_cmd->t_data_sg and se_cmd->t_data_nents. + +This addresses an OOPs where transport_allocate_data_tasks() would walk +the incorrect post OVERFLOW cmd->data_length value beyond the end of +the passed scatterlist. + +Cc: Christoph Hellwig +Cc: Andy Grover +Signed-off-by: Nicholas Bellinger +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/target/target_core_transport.c | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +--- a/drivers/target/target_core_transport.c ++++ b/drivers/target/target_core_transport.c +@@ -3873,6 +3873,18 @@ int transport_generic_map_mem_to_cmd( + + if ((cmd->se_cmd_flags & SCF_SCSI_DATA_SG_IO_CDB) || + (cmd->se_cmd_flags & SCF_SCSI_CONTROL_SG_IO_CDB)) { ++ /* ++ * Reject SCSI data overflow with map_mem_to_cmd() as incoming ++ * scatterlists already have been set to follow what the fabric ++ * passes for the original expected data transfer length. ++ */ ++ if (cmd->se_cmd_flags & SCF_OVERFLOW_BIT) { ++ pr_warn("Rejecting SCSI DATA overflow for fabric using" ++ " SCF_PASSTHROUGH_SG_TO_MEM_NOALLOC\n"); ++ cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; ++ cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; ++ return -EINVAL; ++ } + + cmd->t_data_sg = sgl; + cmd->t_data_nents = sgl_count;