]>
Commit | Line | Data |
---|---|---|
2cb7cef9 BS |
1 | From: Gerald Schaefer <geraldsc@de.ibm.com> |
2 | Subject: zfcp: Don't call zfcp_fsf_req_free on NULL pointer | |
3 | References: bnc#484767,LTC#52234 | |
4 | ||
5 | Symptom: Reading adapter statistics from user space on a full | |
6 | queue might lead to the attempt of freeing memory on | |
7 | a NULL pointer. | |
8 | Problem: The error path for the queue full case is wrong in the code. | |
9 | Solution: Only free the FSF request if it has been sucessfully allocated | |
10 | before | |
11 | ||
12 | Acked-by: John Jolly <jjolly@suse.de> | |
13 | --- | |
14 | drivers/s390/scsi/zfcp_fsf.c | 18 ++++++++++++------ | |
15 | 1 file changed, 12 insertions(+), 6 deletions(-) | |
16 | ||
17 | --- a/drivers/s390/scsi/zfcp_fsf.c 2009-03-16 15:34:34.000000000 +0100 | |
18 | +++ b/drivers/s390/scsi/zfcp_fsf.c 2009-03-16 16:04:01.000000000 +0100 | |
19 | @@ -1256,13 +1256,13 @@ int zfcp_fsf_exchange_config_data_sync(s | |
20 | ||
21 | spin_lock_bh(&adapter->req_q_lock); | |
22 | if (zfcp_fsf_req_sbal_get(adapter)) | |
23 | - goto out; | |
24 | + goto out_unlock; | |
25 | ||
26 | req = zfcp_fsf_req_create(adapter, FSF_QTCB_EXCHANGE_CONFIG_DATA, | |
27 | 0, NULL); | |
28 | if (IS_ERR(req)) { | |
29 | retval = PTR_ERR(req); | |
30 | - goto out; | |
31 | + goto out_unlock; | |
32 | } | |
33 | ||
34 | sbale = zfcp_qdio_sbale_req(req); | |
35 | @@ -1281,14 +1281,16 @@ int zfcp_fsf_exchange_config_data_sync(s | |
36 | ||
37 | zfcp_fsf_start_timer(req, ZFCP_FSF_REQUEST_TIMEOUT); | |
38 | retval = zfcp_fsf_req_send(req); | |
39 | -out: | |
40 | spin_unlock_bh(&adapter->req_q_lock); | |
41 | if (!retval) | |
42 | wait_event(req->completion_wq, | |
43 | req->status & ZFCP_STATUS_FSFREQ_COMPLETED); | |
44 | ||
45 | zfcp_fsf_req_free(req); | |
46 | + return retval; | |
47 | ||
48 | +out_unlock: | |
49 | + spin_unlock_bh(&adapter->req_q_lock); | |
50 | return retval; | |
51 | } | |
52 | ||
53 | @@ -1355,13 +1357,13 @@ int zfcp_fsf_exchange_port_data_sync(str | |
54 | ||
55 | spin_lock_bh(&adapter->req_q_lock); | |
56 | if (zfcp_fsf_req_sbal_get(adapter)) | |
57 | - goto out; | |
58 | + goto out_unlock; | |
59 | ||
60 | req = zfcp_fsf_req_create(adapter, FSF_QTCB_EXCHANGE_PORT_DATA, 0, | |
61 | NULL); | |
62 | if (IS_ERR(req)) { | |
63 | retval = PTR_ERR(req); | |
64 | - goto out; | |
65 | + goto out_unlock; | |
66 | } | |
67 | ||
68 | if (data) | |
69 | @@ -1374,14 +1376,18 @@ int zfcp_fsf_exchange_port_data_sync(str | |
70 | req->handler = zfcp_fsf_exchange_port_data_handler; | |
71 | zfcp_fsf_start_timer(req, ZFCP_FSF_REQUEST_TIMEOUT); | |
72 | retval = zfcp_fsf_req_send(req); | |
73 | -out: | |
74 | spin_unlock_bh(&adapter->req_q_lock); | |
75 | + | |
76 | if (!retval) | |
77 | wait_event(req->completion_wq, | |
78 | req->status & ZFCP_STATUS_FSFREQ_COMPLETED); | |
79 | zfcp_fsf_req_free(req); | |
80 | ||
81 | return retval; | |
82 | + | |
83 | +out_unlock: | |
84 | + spin_unlock_bh(&adapter->req_q_lock); | |
85 | + return retval; | |
86 | } | |
87 | ||
88 | static void zfcp_fsf_open_port_handler(struct zfcp_fsf_req *req) |