
From: Stefan Haberland <sth@linux.ibm.com> [ 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: Qian Cai <cai@lca.pw> Reviewed-by: Jan Hoeppner <hoeppner@linux.ibm.com> Signed-off-by: Stefan Haberland <sth@linux.ibm.com> Signed-off-by: Jens Axboe <axboe@kernel.dk> Signed-off-by: Sasha Levin <sashal@kernel.org> Signed-off-by: Yang Yingliang <yangyingliang@huawei.com> --- drivers/s390/block/dasd_eckd.c | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c index 108fb1c..a2e34c8 100644 --- a/drivers/s390/block/dasd_eckd.c +++ b/drivers/s390/block/dasd_eckd.c @@ -1770,7 +1770,7 @@ static void dasd_eckd_kick_validate_server(struct dasd_device *device) dasd_free_block(device->block); device->block = NULL; out_err1: - kfree(private->conf_data); + dasd_eckd_clear_conf_data(device); kfree(device->private); device->private = NULL; return rc; @@ -1779,7 +1779,6 @@ static void dasd_eckd_kick_validate_server(struct dasd_device *device) static void dasd_eckd_uncheck_device(struct dasd_device *device) { struct dasd_eckd_private *private = device->private; - int i; if (!private) return; @@ -1789,21 +1788,7 @@ static void dasd_eckd_uncheck_device(struct dasd_device *device) private->sneq = NULL; private->vdsneq = NULL; private->gneq = NULL; - private->conf_len = 0; - 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; + dasd_eckd_clear_conf_data(device); } static struct dasd_ccw_req * -- 1.8.3