diff options
author | Olaf Kirch <olaf.kirch@oracle.com> | 2007-12-13 13:43:36 -0500 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2008-01-11 19:28:43 -0500 |
commit | 03766a1d4e4520066d3ed2097bfdf6e606aba828 (patch) | |
tree | 56757a1710b8f1f2e0b243a5d727c7e24de6f210 /drivers/scsi | |
parent | a8ac6311cc21d78fa284cd43f56df2063f536bf1 (diff) |
[SCSI] iscsi_tcp: stop leaking r2t_info's when the incoming R2T is bad
iscsi_r2t_rsp checks the incoming R2T for sanity, and if it
thinks it's fishy, it will drop it silently. In this case, we
leaked an r2t_info object. If we do this often enough, we run
into a BUG_ON some time later.
Removed r2t wrappers and update patch by Mike Christie
Signed-off-by: Olaf Kirch <olaf.kirch@oracle.com>
Signed-off-by: Mike Christie <michaelc@cs.wisc.edu>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/scsi')
-rw-r--r-- | drivers/scsi/iscsi_tcp.c | 6 |
1 files changed, 5 insertions, 1 deletions
diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c index 7212fe95a66d..ecba606e6521 100644 --- a/drivers/scsi/iscsi_tcp.c +++ b/drivers/scsi/iscsi_tcp.c | |||
@@ -658,6 +658,8 @@ iscsi_r2t_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) | |||
658 | r2t->data_length = be32_to_cpu(rhdr->data_length); | 658 | r2t->data_length = be32_to_cpu(rhdr->data_length); |
659 | if (r2t->data_length == 0) { | 659 | if (r2t->data_length == 0) { |
660 | printk(KERN_ERR "iscsi_tcp: invalid R2T with zero data len\n"); | 660 | printk(KERN_ERR "iscsi_tcp: invalid R2T with zero data len\n"); |
661 | __kfifo_put(tcp_ctask->r2tpool.queue, (void*)&r2t, | ||
662 | sizeof(void*)); | ||
661 | spin_unlock(&session->lock); | 663 | spin_unlock(&session->lock); |
662 | return ISCSI_ERR_DATALEN; | 664 | return ISCSI_ERR_DATALEN; |
663 | } | 665 | } |
@@ -669,10 +671,12 @@ iscsi_r2t_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) | |||
669 | 671 | ||
670 | r2t->data_offset = be32_to_cpu(rhdr->data_offset); | 672 | r2t->data_offset = be32_to_cpu(rhdr->data_offset); |
671 | if (r2t->data_offset + r2t->data_length > scsi_bufflen(ctask->sc)) { | 673 | if (r2t->data_offset + r2t->data_length > scsi_bufflen(ctask->sc)) { |
672 | spin_unlock(&session->lock); | ||
673 | printk(KERN_ERR "iscsi_tcp: invalid R2T with data len %u at " | 674 | printk(KERN_ERR "iscsi_tcp: invalid R2T with data len %u at " |
674 | "offset %u and total length %d\n", r2t->data_length, | 675 | "offset %u and total length %d\n", r2t->data_length, |
675 | r2t->data_offset, scsi_bufflen(ctask->sc)); | 676 | r2t->data_offset, scsi_bufflen(ctask->sc)); |
677 | __kfifo_put(tcp_ctask->r2tpool.queue, (void*)&r2t, | ||
678 | sizeof(void*)); | ||
679 | spin_unlock(&session->lock); | ||
676 | return ISCSI_ERR_DATALEN; | 680 | return ISCSI_ERR_DATALEN; |
677 | } | 681 | } |
678 | 682 | ||