From e0e2c5cde57d4b0c3af2998c3a591f3db75ce7eb Mon Sep 17 00:00:00 2001 From: Christian Engelmayer Date: Wed, 7 May 2014 21:34:37 +0200 Subject: [PATCH] staging: rtl8188eu: fix potential leak in rtw_mp_pwrtrk() Function rtw_mp_pwrtrk() dynamically allocates a temporary buffer that is not freed in all error paths. Use a centralized exit path and make sure that all memory is freed correctly. Detected by Coverity - 1077715. Signed-off-by: Christian Engelmayer Signed-off-by: Greg Kroah-Hartman --- .../staging/rtl8188eu/os_dep/ioctl_linux.c | 28 +++++++++++-------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c b/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c index ea5e1f838ea3..f04aaa375f0e 100644 --- a/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c +++ b/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c @@ -7119,15 +7119,15 @@ static int rtw_mp_pwrtrk(struct net_device *dev, { u8 enable; u32 thermal; - s32 ret; struct adapter *padapter = rtw_netdev_priv(dev); char *input = kmalloc(wrqu->length, GFP_KERNEL); + int ret = 0; if (!input) return -ENOMEM; if (copy_from_user(input, wrqu->pointer, wrqu->length)) { - kfree(input); - return -EFAULT; + ret = -EFAULT; + goto exit; } _rtw_memset(extra, 0, wrqu->length); @@ -7138,22 +7138,28 @@ static int rtw_mp_pwrtrk(struct net_device *dev, sprintf(extra, "mp tx power tracking stop"); } else if (sscanf(input, "ther =%d", &thermal)) { ret = Hal_SetThermalMeter(padapter, (u8)thermal); - if (ret == _FAIL) - return -EPERM; + if (ret == _FAIL) { + ret = -EPERM; + goto exit; + } sprintf(extra, "mp tx power tracking start, target value =%d ok ", thermal); } else { - kfree(input); - return -EINVAL; + ret = -EINVAL; + goto exit; } } - kfree(input); ret = Hal_SetPowerTracking(padapter, enable); - if (ret == _FAIL) - return -EPERM; + if (ret == _FAIL) { + ret = -EPERM; + goto exit; + } wrqu->length = strlen(extra); - return 0; + +exit: + kfree(input); + return ret; } static int rtw_mp_psd(struct net_device *dev, -- 2.34.1