提交 2a2ed960 编写于 作者: S Stefan Haberland 提交者: Yang Yingliang

s390/dasd: fix memleak in path handling error case

[ Upstream commit 00b39f698a4f1ee897227cace2e3937fc4412270 ]

If for whatever reason the dasd_eckd_check_characteristics() function
exits after at least some paths have their configuration data
allocated those data is never freed again. In the error case the
device->private pointer is set to NULL and dasd_eckd_uncheck_device()
will exit without freeing the path data because of this NULL pointer.

Fix by calling dasd_eckd_clear_conf_data() for error cases.

Also use dasd_eckd_clear_conf_data() in dasd_eckd_uncheck_device()
to avoid code duplication.
Reported-by: NQian Cai <cai@lca.pw>
Reviewed-by: NJan Hoeppner <hoeppner@linux.ibm.com>
Signed-off-by: NStefan Haberland <sth@linux.ibm.com>
Signed-off-by: NJens Axboe <axboe@kernel.dk>
Signed-off-by: NSasha Levin <sashal@kernel.org>
Signed-off-by: NYang Yingliang <yangyingliang@huawei.com>
上级 3c207ca2
...@@ -1770,7 +1770,7 @@ dasd_eckd_check_characteristics(struct dasd_device *device) ...@@ -1770,7 +1770,7 @@ dasd_eckd_check_characteristics(struct dasd_device *device)
dasd_free_block(device->block); dasd_free_block(device->block);
device->block = NULL; device->block = NULL;
out_err1: out_err1:
kfree(private->conf_data); dasd_eckd_clear_conf_data(device);
kfree(device->private); kfree(device->private);
device->private = NULL; device->private = NULL;
return rc; return rc;
...@@ -1779,7 +1779,6 @@ dasd_eckd_check_characteristics(struct dasd_device *device) ...@@ -1779,7 +1779,6 @@ dasd_eckd_check_characteristics(struct dasd_device *device)
static void dasd_eckd_uncheck_device(struct dasd_device *device) static void dasd_eckd_uncheck_device(struct dasd_device *device)
{ {
struct dasd_eckd_private *private = device->private; struct dasd_eckd_private *private = device->private;
int i;
if (!private) if (!private)
return; return;
...@@ -1789,21 +1788,7 @@ static void dasd_eckd_uncheck_device(struct dasd_device *device) ...@@ -1789,21 +1788,7 @@ static void dasd_eckd_uncheck_device(struct dasd_device *device)
private->sneq = NULL; private->sneq = NULL;
private->vdsneq = NULL; private->vdsneq = NULL;
private->gneq = NULL; private->gneq = NULL;
private->conf_len = 0; dasd_eckd_clear_conf_data(device);
for (i = 0; i < 8; i++) {
kfree(device->path[i].conf_data);
if ((__u8 *)device->path[i].conf_data ==
private->conf_data) {
private->conf_data = NULL;
private->conf_len = 0;
}
device->path[i].conf_data = NULL;
device->path[i].cssid = 0;
device->path[i].ssid = 0;
device->path[i].chpid = 0;
}
kfree(private->conf_data);
private->conf_data = NULL;
} }
static struct dasd_ccw_req * static struct dasd_ccw_req *
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册