summaryrefslogtreecommitdiffstats
path: root/drivers/s390/scsi/zfcp_def.h
diff options
context:
space:
mode:
authorHeiko Carstens2007-12-20 12:30:22 +0100
committerJames Bottomley2008-01-12 01:29:00 +0100
commitd1ad09db2fd551d49d65ef040591cb9298e70fb6 (patch)
treee26e31c96068ce3ab58ed14d4e51d68a308d3891 /drivers/s390/scsi/zfcp_def.h
parent[SCSI] megaraid: add __devexit annotation (diff)
downloadkernel-qcow2-linux-d1ad09db2fd551d49d65ef040591cb9298e70fb6.tar.gz
kernel-qcow2-linux-d1ad09db2fd551d49d65ef040591cb9298e70fb6.tar.xz
kernel-qcow2-linux-d1ad09db2fd551d49d65ef040591cb9298e70fb6.zip
[SCSI] zfcp: fix use after free bug.
zfcp_erp_strategy_check_fsfreq() checks if it is safe to access the fsf_req associated with the erp_action that gets passed. To test if it is safe it accesses the fsf_req in order to get its index into the hash list. This is broken since the fsf_req might be freed already and the read index has no meaning. It could lead to memory corruption. Fix this by introducing a new zfcp_reqlist_find_safe() method which just checks if addresses are equal. This is slower, but only gets called in case of error recovery. Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com> Signed-off-by: Christof Schmitt <christof.schmitt@de.ibm.com> Signed-off-by: Martin Peschke <mp3@de.ibm.com> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/s390/scsi/zfcp_def.h')
-rw-r--r--drivers/s390/scsi/zfcp_def.h14
1 files changed, 14 insertions, 0 deletions
diff --git a/drivers/s390/scsi/zfcp_def.h b/drivers/s390/scsi/zfcp_def.h
index 294d0792e82b..9e9f6c1e4e5d 100644
--- a/drivers/s390/scsi/zfcp_def.h
+++ b/drivers/s390/scsi/zfcp_def.h
@@ -1123,6 +1123,20 @@ zfcp_reqlist_find(struct zfcp_adapter *adapter, unsigned long req_id)
return NULL;
}
+static inline struct zfcp_fsf_req *
+zfcp_reqlist_find_safe(struct zfcp_adapter *adapter, struct zfcp_fsf_req *req)
+{
+ struct zfcp_fsf_req *request;
+ unsigned int idx;
+
+ for (idx = 0; idx < REQUEST_LIST_SIZE; idx++) {
+ list_for_each_entry(request, &adapter->req_list[idx], list)
+ if (request == req)
+ return request;
+ }
+ return NULL;
+}
+
/*
* functions needed for reference/usage counting
*/