aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorXiaoke Wang <xkernel.wang@foxmail.com>2022-09-13 21:24:05 +0800
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2022-09-24 13:08:44 +0200
commitf44641bfc4e81fb2f37a92fb13afdc7c63c9114b (patch)
treebaf836e2652bdffa833370af8908eb963f834888
parentstaging: r8188eu: add kfree() on an error path of rtw_xmit_resource_alloc() (diff)
downloadlinux-dev-f44641bfc4e81fb2f37a92fb13afdc7c63c9114b.tar.xz
linux-dev-f44641bfc4e81fb2f37a92fb13afdc7c63c9114b.zip
staging: r8188eu: fix potential memory leak in _rtw_init_xmit_priv()
In _rtw_init_xmit_priv(), there are several error paths for allocation failures just jump to the `exit` section. However, there is no action will be performed, so the allocated resources are not properly released, which leads to various memory leaks. To properly release them, this patch unifies the error handling code and several error handling paths are added. According to the allocation sequence, if the validation fails, it will jump to its corresponding error tag to release the resources. Tested-by: Philipp Hortmann <philipp.g.hortmann@gmail.com> # Edimax N150 Signed-off-by: Xiaoke Wang <xkernel.wang@foxmail.com> Link: https://lore.kernel.org/r/tencent_DB57E4F270F4539485C32B05FDAF8394310A@qq.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/staging/r8188eu/core/rtw_xmit.c30
1 files changed, 24 insertions, 6 deletions
diff --git a/drivers/staging/r8188eu/core/rtw_xmit.c b/drivers/staging/r8188eu/core/rtw_xmit.c
index 13ecd108c86b..fbbbdf2856c6 100644
--- a/drivers/staging/r8188eu/core/rtw_xmit.c
+++ b/drivers/staging/r8188eu/core/rtw_xmit.c
@@ -134,7 +134,7 @@ s32 _rtw_init_xmit_priv(struct xmit_priv *pxmitpriv, struct adapter *padapter)
if (!pxmitpriv->pallocated_xmitbuf) {
res = _FAIL;
- goto exit;
+ goto free_frame_buf;
}
pxmitpriv->pxmitbuf = (u8 *)ALIGN((size_t)(pxmitpriv->pallocated_xmitbuf), 4);
@@ -156,7 +156,7 @@ s32 _rtw_init_xmit_priv(struct xmit_priv *pxmitpriv, struct adapter *padapter)
msleep(10);
res = rtw_xmit_resource_alloc(padapter, pxmitbuf, (MAX_XMITBUF_SZ + XMITBUF_ALIGN_SZ));
if (res == _FAIL)
- goto exit;
+ goto free_xmitbuf;
}
pxmitbuf->flags = XMIT_VO_QUEUE;
@@ -174,7 +174,7 @@ s32 _rtw_init_xmit_priv(struct xmit_priv *pxmitpriv, struct adapter *padapter)
if (!pxmitpriv->pallocated_xmit_extbuf) {
res = _FAIL;
- goto exit;
+ goto free_xmitbuf;
}
pxmitpriv->pxmit_extbuf = (u8 *)ALIGN((size_t)(pxmitpriv->pallocated_xmit_extbuf), 4);
@@ -191,7 +191,7 @@ s32 _rtw_init_xmit_priv(struct xmit_priv *pxmitpriv, struct adapter *padapter)
res = rtw_xmit_resource_alloc(padapter, pxmitbuf, max_xmit_extbuf_size + XMITBUF_ALIGN_SZ);
if (res == _FAIL) {
res = _FAIL;
- goto exit;
+ goto free_xmit_extbuf;
}
list_add_tail(&pxmitbuf->list, &pxmitpriv->free_xmit_extbuf_queue.queue);
@@ -202,7 +202,7 @@ s32 _rtw_init_xmit_priv(struct xmit_priv *pxmitpriv, struct adapter *padapter)
if (rtw_alloc_hwxmits(padapter)) {
res = _FAIL;
- goto exit;
+ goto free_xmit_extbuf;
}
rtw_init_hwxmits(pxmitpriv->hwxmits, pxmitpriv->hwxmit_entry);
@@ -226,8 +226,26 @@ s32 _rtw_init_xmit_priv(struct xmit_priv *pxmitpriv, struct adapter *padapter)
rtl8188eu_init_xmit_priv(padapter);
-exit:
+ return _SUCCESS;
+free_xmit_extbuf:
+ pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmit_extbuf;
+ while (i--) {
+ rtw_xmit_resource_free(padapter, pxmitbuf, (max_xmit_extbuf_size + XMITBUF_ALIGN_SZ));
+ pxmitbuf++;
+ }
+ vfree(pxmitpriv->pallocated_xmit_extbuf);
+ i = NR_XMITBUFF;
+free_xmitbuf:
+ pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmitbuf;
+ while (i--) {
+ rtw_xmit_resource_free(padapter, pxmitbuf, (MAX_XMITBUF_SZ + XMITBUF_ALIGN_SZ));
+ pxmitbuf++;
+ }
+ vfree(pxmitpriv->pallocated_xmitbuf);
+free_frame_buf:
+ vfree(pxmitpriv->pallocated_frame_buf);
+exit:
return res;
}