diff options
Diffstat (limited to 'drivers/scsi')
-rw-r--r-- | drivers/scsi/iscsi_tcp.c | 13 | ||||
-rw-r--r-- | drivers/scsi/libiscsi.c | 60 |
2 files changed, 52 insertions, 21 deletions
diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c index dfaf9fa57340..f2a08f7ed902 100644 --- a/drivers/scsi/iscsi_tcp.c +++ b/drivers/scsi/iscsi_tcp.c | |||
@@ -740,7 +740,6 @@ iscsi_tcp_hdr_dissect(struct iscsi_conn *conn, struct iscsi_hdr *hdr) | |||
740 | struct iscsi_session *session = conn->session; | 740 | struct iscsi_session *session = conn->session; |
741 | struct iscsi_tcp_conn *tcp_conn = conn->dd_data; | 741 | struct iscsi_tcp_conn *tcp_conn = conn->dd_data; |
742 | struct iscsi_cmd_task *ctask; | 742 | struct iscsi_cmd_task *ctask; |
743 | uint32_t itt; | ||
744 | 743 | ||
745 | /* verify PDU length */ | 744 | /* verify PDU length */ |
746 | tcp_conn->in.datalen = ntoh24(hdr->dlength); | 745 | tcp_conn->in.datalen = ntoh24(hdr->dlength); |
@@ -758,7 +757,7 @@ iscsi_tcp_hdr_dissect(struct iscsi_conn *conn, struct iscsi_hdr *hdr) | |||
758 | 757 | ||
759 | opcode = hdr->opcode & ISCSI_OPCODE_MASK; | 758 | opcode = hdr->opcode & ISCSI_OPCODE_MASK; |
760 | /* verify itt (itt encoding: age+cid+itt) */ | 759 | /* verify itt (itt encoding: age+cid+itt) */ |
761 | rc = iscsi_verify_itt(conn, hdr, &itt); | 760 | rc = iscsi_verify_itt(conn, hdr->itt); |
762 | if (rc) | 761 | if (rc) |
763 | return rc; | 762 | return rc; |
764 | 763 | ||
@@ -767,7 +766,10 @@ iscsi_tcp_hdr_dissect(struct iscsi_conn *conn, struct iscsi_hdr *hdr) | |||
767 | 766 | ||
768 | switch(opcode) { | 767 | switch(opcode) { |
769 | case ISCSI_OP_SCSI_DATA_IN: | 768 | case ISCSI_OP_SCSI_DATA_IN: |
770 | ctask = session->cmds[itt]; | 769 | ctask = iscsi_itt_to_ctask(conn, hdr->itt); |
770 | if (!ctask) | ||
771 | return ISCSI_ERR_BAD_ITT; | ||
772 | |||
771 | spin_lock(&conn->session->lock); | 773 | spin_lock(&conn->session->lock); |
772 | rc = iscsi_data_rsp(conn, ctask); | 774 | rc = iscsi_data_rsp(conn, ctask); |
773 | spin_unlock(&conn->session->lock); | 775 | spin_unlock(&conn->session->lock); |
@@ -810,7 +812,10 @@ iscsi_tcp_hdr_dissect(struct iscsi_conn *conn, struct iscsi_hdr *hdr) | |||
810 | rc = iscsi_complete_pdu(conn, hdr, NULL, 0); | 812 | rc = iscsi_complete_pdu(conn, hdr, NULL, 0); |
811 | break; | 813 | break; |
812 | case ISCSI_OP_R2T: | 814 | case ISCSI_OP_R2T: |
813 | ctask = session->cmds[itt]; | 815 | ctask = iscsi_itt_to_ctask(conn, hdr->itt); |
816 | if (!ctask) | ||
817 | return ISCSI_ERR_BAD_ITT; | ||
818 | |||
814 | if (ahslen) | 819 | if (ahslen) |
815 | rc = ISCSI_ERR_AHSLEN; | 820 | rc = ISCSI_ERR_AHSLEN; |
816 | else if (ctask->sc->sc_data_direction == DMA_TO_DEVICE) { | 821 | else if (ctask->sc->sc_data_direction == DMA_TO_DEVICE) { |
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index 79bc49fd7f12..4bc63c4b3c10 100644 --- a/drivers/scsi/libiscsi.c +++ b/drivers/scsi/libiscsi.c | |||
@@ -640,6 +640,10 @@ static int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr, | |||
640 | uint32_t itt; | 640 | uint32_t itt; |
641 | 641 | ||
642 | conn->last_recv = jiffies; | 642 | conn->last_recv = jiffies; |
643 | rc = iscsi_verify_itt(conn, hdr->itt); | ||
644 | if (rc) | ||
645 | return rc; | ||
646 | |||
643 | if (hdr->itt != RESERVED_ITT) | 647 | if (hdr->itt != RESERVED_ITT) |
644 | itt = get_itt(hdr->itt); | 648 | itt = get_itt(hdr->itt); |
645 | else | 649 | else |
@@ -776,27 +780,22 @@ int iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr, | |||
776 | } | 780 | } |
777 | EXPORT_SYMBOL_GPL(iscsi_complete_pdu); | 781 | EXPORT_SYMBOL_GPL(iscsi_complete_pdu); |
778 | 782 | ||
779 | /* verify itt (itt encoding: age+cid+itt) */ | 783 | int iscsi_verify_itt(struct iscsi_conn *conn, itt_t itt) |
780 | int iscsi_verify_itt(struct iscsi_conn *conn, struct iscsi_hdr *hdr, | ||
781 | uint32_t *ret_itt) | ||
782 | { | 784 | { |
783 | struct iscsi_session *session = conn->session; | 785 | struct iscsi_session *session = conn->session; |
784 | struct iscsi_cmd_task *ctask; | 786 | struct iscsi_cmd_task *ctask; |
785 | uint32_t itt; | ||
786 | 787 | ||
787 | if (hdr->itt != RESERVED_ITT) { | 788 | if (itt == RESERVED_ITT) |
788 | if (((__force u32)hdr->itt & ISCSI_AGE_MASK) != | 789 | return 0; |
789 | (session->age << ISCSI_AGE_SHIFT)) { | ||
790 | iscsi_conn_printk(KERN_ERR, conn, | ||
791 | "received itt %x expected session " | ||
792 | "age (%x)\n", (__force u32)hdr->itt, | ||
793 | session->age & ISCSI_AGE_MASK); | ||
794 | return ISCSI_ERR_BAD_ITT; | ||
795 | } | ||
796 | 790 | ||
797 | itt = get_itt(hdr->itt); | 791 | if (((__force u32)itt & ISCSI_AGE_MASK) != |
798 | } else | 792 | (session->age << ISCSI_AGE_SHIFT)) { |
799 | itt = ~0U; | 793 | iscsi_conn_printk(KERN_ERR, conn, |
794 | "received itt %x expected session age (%x)\n", | ||
795 | (__force u32)itt, | ||
796 | session->age & ISCSI_AGE_MASK); | ||
797 | return ISCSI_ERR_BAD_ITT; | ||
798 | } | ||
800 | 799 | ||
801 | if (itt < session->cmds_max) { | 800 | if (itt < session->cmds_max) { |
802 | ctask = session->cmds[itt]; | 801 | ctask = session->cmds[itt]; |
@@ -817,11 +816,38 @@ int iscsi_verify_itt(struct iscsi_conn *conn, struct iscsi_hdr *hdr, | |||
817 | } | 816 | } |
818 | } | 817 | } |
819 | 818 | ||
820 | *ret_itt = itt; | ||
821 | return 0; | 819 | return 0; |
822 | } | 820 | } |
823 | EXPORT_SYMBOL_GPL(iscsi_verify_itt); | 821 | EXPORT_SYMBOL_GPL(iscsi_verify_itt); |
824 | 822 | ||
823 | struct iscsi_cmd_task * | ||
824 | iscsi_itt_to_ctask(struct iscsi_conn *conn, itt_t itt) | ||
825 | { | ||
826 | struct iscsi_session *session = conn->session; | ||
827 | struct iscsi_cmd_task *ctask; | ||
828 | uint32_t i; | ||
829 | |||
830 | if (iscsi_verify_itt(conn, itt)) | ||
831 | return NULL; | ||
832 | |||
833 | if (itt == RESERVED_ITT) | ||
834 | return NULL; | ||
835 | |||
836 | i = get_itt(itt); | ||
837 | if (i >= session->cmds_max) | ||
838 | return NULL; | ||
839 | |||
840 | ctask = session->cmds[i]; | ||
841 | if (!ctask->sc) | ||
842 | return NULL; | ||
843 | |||
844 | if (ctask->sc->SCp.phase != session->age) | ||
845 | return NULL; | ||
846 | |||
847 | return ctask; | ||
848 | } | ||
849 | EXPORT_SYMBOL_GPL(iscsi_itt_to_ctask); | ||
850 | |||
825 | void iscsi_conn_failure(struct iscsi_conn *conn, enum iscsi_err err) | 851 | void iscsi_conn_failure(struct iscsi_conn *conn, enum iscsi_err err) |
826 | { | 852 | { |
827 | struct iscsi_session *session = conn->session; | 853 | struct iscsi_session *session = conn->session; |