2022-04-06 13:57:00

by Xiaoke Wang

[permalink] [raw]
Subject: [PATCH v2 1/2] staging: r8188eu: fix potential memory leak in _rtw_init_xmit_priv()

From: Xiaoke Wang <[email protected]>

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.

Signed-off-by: Xiaoke Wang <[email protected]>
---
ChangeLog:
v1->v2 update the description and adjust the sequence of patches.
drivers/staging/r8188eu/core/rtw_xmit.c | 32 ++++++++++++++++++-------
1 file changed, 24 insertions(+), 8 deletions(-)

diff --git a/drivers/staging/r8188eu/core/rtw_xmit.c b/drivers/staging/r8188eu/core/rtw_xmit.c
index aede8ef..865b2fc 100644
--- a/drivers/staging/r8188eu/core/rtw_xmit.c
+++ b/drivers/staging/r8188eu/core/rtw_xmit.c
@@ -112,7 +112,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 *)N_BYTE_ALIGMENT((size_t)(pxmitpriv->pallocated_xmitbuf), 4);
@@ -134,7 +134,7 @@ s32 _rtw_init_xmit_priv(struct xmit_priv *pxmitpriv, struct adapter *padapter)
msleep(10);
res = rtw_os_xmit_resource_alloc(padapter, pxmitbuf, (MAX_XMITBUF_SZ + XMITBUF_ALIGN_SZ));
if (res == _FAIL)
- goto exit;
+ goto free_xmitbuf;
}

pxmitbuf->flags = XMIT_VO_QUEUE;
@@ -152,7 +152,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 *)N_BYTE_ALIGMENT((size_t)(pxmitpriv->pallocated_xmit_extbuf), 4);
@@ -167,10 +167,8 @@ s32 _rtw_init_xmit_priv(struct xmit_priv *pxmitpriv, struct adapter *padapter)
pxmitbuf->ext_tag = true;

res = rtw_os_xmit_resource_alloc(padapter, pxmitbuf, max_xmit_extbuf_size + XMITBUF_ALIGN_SZ);
- if (res == _FAIL) {
- res = _FAIL;
- goto exit;
- }
+ if (res == _FAIL)
+ goto free_xmit_extbuf;

list_add_tail(&pxmitbuf->list, &pxmitpriv->free_xmit_extbuf_queue.queue);
pxmitbuf++;
@@ -200,8 +198,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-- > 0) {
+ rtw_os_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-- > 0) {
+ rtw_os_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;
}

--


2022-04-06 13:57:01

by Xiaoke Wang

[permalink] [raw]
Subject: [PATCH v2 2/2] staging: r8188eu: check the return of kzalloc()

From: Xiaoke Wang <[email protected]>

kzalloc() is a memory allocation function which can return NULL when
some internal memory errors happen. So it is better to handle the return
of it to prevent potential wrong memory access.

Besides, to propagate the error to the caller, the type of
rtw_alloc_hwxmits() is changed and another check is added in its caller.
Then if kzalloc() fails, the caller will properly jump to the
corresponding error hanlding code.

Signed-off-by: Xiaoke Wang <[email protected]>
---
ChangeLog:
v1->v2 update the description and adjust the sequence of patches.
drivers/staging/r8188eu/core/rtw_xmit.c | 10 ++++++++--
drivers/staging/r8188eu/include/rtw_xmit.h | 2 +-
2 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/drivers/staging/r8188eu/core/rtw_xmit.c b/drivers/staging/r8188eu/core/rtw_xmit.c
index 865b2fc..92a1ad3 100644
--- a/drivers/staging/r8188eu/core/rtw_xmit.c
+++ b/drivers/staging/r8188eu/core/rtw_xmit.c
@@ -176,7 +176,9 @@ s32 _rtw_init_xmit_priv(struct xmit_priv *pxmitpriv, struct adapter *padapter)

pxmitpriv->free_xmit_extbuf_cnt = num_xmit_extbuf;

- rtw_alloc_hwxmits(padapter);
+ res = rtw_alloc_hwxmits(padapter);
+ if (res == _FAIL)
+ goto free_xmit_extbuf;
rtw_init_hwxmits(pxmitpriv->hwxmits, pxmitpriv->hwxmit_entry);

for (i = 0; i < 4; i++)
@@ -1490,7 +1492,7 @@ s32 rtw_xmit_classifier(struct adapter *padapter, struct xmit_frame *pxmitframe)
return res;
}

-void rtw_alloc_hwxmits(struct adapter *padapter)
+s32 rtw_alloc_hwxmits(struct adapter *padapter)
{
struct hw_xmit *hwxmits;
struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
@@ -1498,6 +1500,8 @@ void rtw_alloc_hwxmits(struct adapter *padapter)
pxmitpriv->hwxmit_entry = HWXMIT_ENTRY;

pxmitpriv->hwxmits = kzalloc(sizeof(struct hw_xmit) * pxmitpriv->hwxmit_entry, GFP_KERNEL);
+ if (!pxmitpriv->hwxmits)
+ return _FAIL;

hwxmits = pxmitpriv->hwxmits;

@@ -1514,6 +1518,8 @@ void rtw_alloc_hwxmits(struct adapter *padapter)
hwxmits[3] .sta_queue = &pxmitpriv->bk_pending;
} else {
}
+
+ return _SUCCESS;
}

void rtw_free_hwxmits(struct adapter *padapter)
diff --git a/drivers/staging/r8188eu/include/rtw_xmit.h b/drivers/staging/r8188eu/include/rtw_xmit.h
index b2df148..fa35776 100644
--- a/drivers/staging/r8188eu/include/rtw_xmit.h
+++ b/drivers/staging/r8188eu/include/rtw_xmit.h
@@ -341,7 +341,7 @@ s32 rtw_txframes_sta_ac_pending(struct adapter *padapter,
void rtw_init_hwxmits(struct hw_xmit *phwxmit, int entry);
s32 _rtw_init_xmit_priv(struct xmit_priv *pxmitpriv, struct adapter *padapter);
void _rtw_free_xmit_priv(struct xmit_priv *pxmitpriv);
-void rtw_alloc_hwxmits(struct adapter *padapter);
+s32 rtw_alloc_hwxmits(struct adapter *padapter);
void rtw_free_hwxmits(struct adapter *padapter);
s32 rtw_xmit(struct adapter *padapter, struct sk_buff **pkt);

--

2022-04-06 21:52:29

by Pavel Skripkin

[permalink] [raw]
Subject: Re: [PATCH v2 2/2] staging: r8188eu: check the return of kzalloc()

Hi Xkernel,

On 4/6/22 07:30, [email protected] wrote:
> From: Xiaoke Wang <[email protected]>
>
> kzalloc() is a memory allocation function which can return NULL when
> some internal memory errors happen. So it is better to handle the return
> of it to prevent potential wrong memory access.
>
> Besides, to propagate the error to the caller, the type of
> rtw_alloc_hwxmits() is changed and another check is added in its caller.
> Then if kzalloc() fails, the caller will properly jump to the
> corresponding error hanlding code.
>
> Signed-off-by: Xiaoke Wang <[email protected]>
> ---
> ChangeLog:
> v1->v2 update the description and adjust the sequence of patches.
> drivers/staging/r8188eu/core/rtw_xmit.c | 10 ++++++++--
> drivers/staging/r8188eu/include/rtw_xmit.h | 2 +-
> 2 files changed, 9 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/staging/r8188eu/core/rtw_xmit.c b/drivers/staging/r8188eu/core/rtw_xmit.c
> index 865b2fc..92a1ad3 100644
> --- a/drivers/staging/r8188eu/core/rtw_xmit.c
> +++ b/drivers/staging/r8188eu/core/rtw_xmit.c
> @@ -176,7 +176,9 @@ s32 _rtw_init_xmit_priv(struct xmit_priv *pxmitpriv, struct adapter *padapter)
>
> pxmitpriv->free_xmit_extbuf_cnt = num_xmit_extbuf;
>
> - rtw_alloc_hwxmits(padapter);
> + res = rtw_alloc_hwxmits(padapter);
> + if (res == _FAIL)
> + goto free_xmit_extbuf;
> rtw_init_hwxmits(pxmitpriv->hwxmits, pxmitpriv->hwxmit_entry);
>
> for (i = 0; i < 4; i++)
> @@ -1490,7 +1492,7 @@ s32 rtw_xmit_classifier(struct adapter *padapter, struct xmit_frame *pxmitframe)
> return res;
> }
>
> -void rtw_alloc_hwxmits(struct adapter *padapter)
> +s32 rtw_alloc_hwxmits(struct adapter *padapter)
> {

What about plain 'int'? I know that s32 is typedef for 'int', but 'int'
looks more natural

just my 2c,


With regards,
Pavel Skripkin

2022-04-07 06:13:33

by Xiaoke Wang

[permalink] [raw]
Subject: Re: [PATCH v2 2/2] staging: r8188eu: check the return of kzalloc()

On Thursday, April 7, 2022 3:22 AM +0800, [email protected] wrote:
> > -void rtw_alloc_hwxmits(struct adapter *padapter)
> > +s32 rtw_alloc_hwxmits(struct adapter *padapter)
> > {
>
> What about plain 'int'? I know that s32 is typedef for 'int', but 'int'
> looks more natural
>

I agree with you.
Since the type of `_rtw_init_xmit_priv` is `s32`, I directly changed the
type of `rtw_alloc_hwxmits` to `s32` (they are neighbors in rtw_xmit.h).
In fact, there are many places where `s32` appears together with `int`
in related files, so maybe we can leave it as a future work to make all
of them a unified form.

Regards,
Xiaoke Wang

2022-04-07 20:44:44

by Greg Kroah-Hartman

[permalink] [raw]
Subject: Re: [PATCH v2 2/2] staging: r8188eu: check the return of kzalloc()

On Thu, Apr 07, 2022 at 10:03:49AM +0800, [email protected] wrote:
> On Thursday, April 7, 2022 3:22 AM +0800, [email protected] wrote:
> > > -void rtw_alloc_hwxmits(struct adapter *padapter)
> > > +s32 rtw_alloc_hwxmits(struct adapter *padapter)
> > > {
> >
> > What about plain 'int'? I know that s32 is typedef for 'int', but 'int'
> > looks more natural
> >
>
> I agree with you.
> Since the type of `_rtw_init_xmit_priv` is `s32`, I directly changed the
> type of `rtw_alloc_hwxmits` to `s32` (they are neighbors in rtw_xmit.h).
> In fact, there are many places where `s32` appears together with `int`
> in related files, so maybe we can leave it as a future work to make all
> of them a unified form.

No, get this one right to start with.

thanks,

greg k-h