mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2025-01-07 14:24:18 +08:00
staging: r8712: Fix memory leak in _r8712_init_xmit_priv()
commitac83631230
upstream. In the above mentioned routine, memory is allocated in several places. If the first succeeds and a later one fails, the routine will leak memory. This patch fixes commit2865d42c78
("staging: r8712u: Add the new driver to the mainline kernel"). A potential memory leak in r8712_xmit_resource_alloc() is also addressed. Fixes:2865d42c78
("staging: r8712u: Add the new driver to the mainline kernel") Reported-by: syzbot+cf71097ffb6755df8251@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/x/log.txt?x=11ac3fa0a80000 Cc: stable@vger.kernel.org Cc: Nam Cao <namcaov@gmail.com> Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net> Reviewed-by: Nam Cao <namcaov@gmail.com> Link: https://lore.kernel.org/r/20230714175417.18578-1-Larry.Finger@lwfinger.net Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
ba2975efe9
commit
acacdbe0f7
@ -21,6 +21,7 @@
|
||||
#include "osdep_intf.h"
|
||||
#include "usb_ops.h"
|
||||
|
||||
#include <linux/usb.h>
|
||||
#include <linux/ieee80211.h>
|
||||
|
||||
static const u8 P802_1H_OUI[P80211_OUI_LEN] = {0x00, 0x00, 0xf8};
|
||||
@ -55,6 +56,7 @@ int _r8712_init_xmit_priv(struct xmit_priv *pxmitpriv,
|
||||
sint i;
|
||||
struct xmit_buf *pxmitbuf;
|
||||
struct xmit_frame *pxframe;
|
||||
int j;
|
||||
|
||||
memset((unsigned char *)pxmitpriv, 0, sizeof(struct xmit_priv));
|
||||
spin_lock_init(&pxmitpriv->lock);
|
||||
@ -117,11 +119,8 @@ int _r8712_init_xmit_priv(struct xmit_priv *pxmitpriv,
|
||||
_init_queue(&pxmitpriv->pending_xmitbuf_queue);
|
||||
pxmitpriv->pallocated_xmitbuf =
|
||||
kmalloc(NR_XMITBUFF * sizeof(struct xmit_buf) + 4, GFP_ATOMIC);
|
||||
if (!pxmitpriv->pallocated_xmitbuf) {
|
||||
kfree(pxmitpriv->pallocated_frame_buf);
|
||||
pxmitpriv->pallocated_frame_buf = NULL;
|
||||
return -ENOMEM;
|
||||
}
|
||||
if (!pxmitpriv->pallocated_xmitbuf)
|
||||
goto clean_up_frame_buf;
|
||||
pxmitpriv->pxmitbuf = pxmitpriv->pallocated_xmitbuf + 4 -
|
||||
((addr_t)(pxmitpriv->pallocated_xmitbuf) & 3);
|
||||
pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmitbuf;
|
||||
@ -129,13 +128,17 @@ int _r8712_init_xmit_priv(struct xmit_priv *pxmitpriv,
|
||||
INIT_LIST_HEAD(&pxmitbuf->list);
|
||||
pxmitbuf->pallocated_buf =
|
||||
kmalloc(MAX_XMITBUF_SZ + XMITBUF_ALIGN_SZ, GFP_ATOMIC);
|
||||
if (!pxmitbuf->pallocated_buf)
|
||||
return -ENOMEM;
|
||||
if (!pxmitbuf->pallocated_buf) {
|
||||
j = 0;
|
||||
goto clean_up_alloc_buf;
|
||||
}
|
||||
pxmitbuf->pbuf = pxmitbuf->pallocated_buf + XMITBUF_ALIGN_SZ -
|
||||
((addr_t) (pxmitbuf->pallocated_buf) &
|
||||
(XMITBUF_ALIGN_SZ - 1));
|
||||
if (r8712_xmit_resource_alloc(padapter, pxmitbuf))
|
||||
return -ENOMEM;
|
||||
if (r8712_xmit_resource_alloc(padapter, pxmitbuf)) {
|
||||
j = 1;
|
||||
goto clean_up_alloc_buf;
|
||||
}
|
||||
list_add_tail(&pxmitbuf->list,
|
||||
&(pxmitpriv->free_xmitbuf_queue.queue));
|
||||
pxmitbuf++;
|
||||
@ -146,6 +149,28 @@ int _r8712_init_xmit_priv(struct xmit_priv *pxmitpriv,
|
||||
init_hwxmits(pxmitpriv->hwxmits, pxmitpriv->hwxmit_entry);
|
||||
tasklet_setup(&pxmitpriv->xmit_tasklet, r8712_xmit_bh);
|
||||
return 0;
|
||||
|
||||
clean_up_alloc_buf:
|
||||
if (j) {
|
||||
/* failure happened in r8712_xmit_resource_alloc()
|
||||
* delete extra pxmitbuf->pallocated_buf
|
||||
*/
|
||||
kfree(pxmitbuf->pallocated_buf);
|
||||
}
|
||||
for (j = 0; j < i; j++) {
|
||||
int k;
|
||||
|
||||
pxmitbuf--; /* reset pointer */
|
||||
kfree(pxmitbuf->pallocated_buf);
|
||||
for (k = 0; k < 8; k++) /* delete xmit urb's */
|
||||
usb_free_urb(pxmitbuf->pxmit_urb[k]);
|
||||
}
|
||||
kfree(pxmitpriv->pallocated_xmitbuf);
|
||||
pxmitpriv->pallocated_xmitbuf = NULL;
|
||||
clean_up_frame_buf:
|
||||
kfree(pxmitpriv->pallocated_frame_buf);
|
||||
pxmitpriv->pallocated_frame_buf = NULL;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
void _free_xmit_priv(struct xmit_priv *pxmitpriv)
|
||||
|
@ -118,6 +118,12 @@ int r8712_xmit_resource_alloc(struct _adapter *padapter,
|
||||
for (i = 0; i < 8; i++) {
|
||||
pxmitbuf->pxmit_urb[i] = usb_alloc_urb(0, GFP_KERNEL);
|
||||
if (!pxmitbuf->pxmit_urb[i]) {
|
||||
int k;
|
||||
|
||||
for (k = i - 1; k >= 0; k--) {
|
||||
/* handle allocation errors part way through loop */
|
||||
usb_free_urb(pxmitbuf->pxmit_urb[k]);
|
||||
}
|
||||
netdev_err(padapter->pnetdev, "pxmitbuf->pxmit_urb[i] == NULL\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user