[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20220228172143.763528498@linuxfoundation.org>
Date: Mon, 28 Feb 2022 18:23:46 +0100
From: Greg Kroah-Hartman <gregkh@...uxfoundation.org>
To: linux-kernel@...r.kernel.org
Cc: Greg Kroah-Hartman <gregkh@...uxfoundation.org>,
stable@...r.kernel.org, stable <stable@...nel.org>,
Daehwan Jung <dh10.jung@...sung.com>
Subject: [PATCH 4.9 19/29] usb: gadget: rndis: add spinlock for rndis response list
From: Daehwan Jung <dh10.jung@...sung.com>
commit aaaba1c86d04dac8e49bf508b492f81506257da3 upstream.
There's no lock for rndis response list. It could cause list corruption
if there're two different list_add at the same time like below.
It's better to add in rndis_add_response / rndis_free_response
/ rndis_get_next_response to prevent any race condition on response list.
[ 361.894299] [1: irq/191-dwc3:16979] list_add corruption.
next->prev should be prev (ffffff80651764d0),
but was ffffff883dc36f80. (next=ffffff80651764d0).
[ 361.904380] [1: irq/191-dwc3:16979] Call trace:
[ 361.904391] [1: irq/191-dwc3:16979] __list_add_valid+0x74/0x90
[ 361.904401] [1: irq/191-dwc3:16979] rndis_msg_parser+0x168/0x8c0
[ 361.904409] [1: irq/191-dwc3:16979] rndis_command_complete+0x24/0x84
[ 361.904417] [1: irq/191-dwc3:16979] usb_gadget_giveback_request+0x20/0xe4
[ 361.904426] [1: irq/191-dwc3:16979] dwc3_gadget_giveback+0x44/0x60
[ 361.904434] [1: irq/191-dwc3:16979] dwc3_ep0_complete_data+0x1e8/0x3a0
[ 361.904442] [1: irq/191-dwc3:16979] dwc3_ep0_interrupt+0x29c/0x3dc
[ 361.904450] [1: irq/191-dwc3:16979] dwc3_process_event_entry+0x78/0x6cc
[ 361.904457] [1: irq/191-dwc3:16979] dwc3_process_event_buf+0xa0/0x1ec
[ 361.904465] [1: irq/191-dwc3:16979] dwc3_thread_interrupt+0x34/0x5c
Fixes: f6281af9d62e ("usb: gadget: rndis: use list_for_each_entry_safe")
Cc: stable <stable@...nel.org>
Signed-off-by: Daehwan Jung <dh10.jung@...sung.com>
Link: https://lore.kernel.org/r/1645507768-77687-1-git-send-email-dh10.jung@samsung.com
Signed-off-by: Greg Kroah-Hartman <gregkh@...uxfoundation.org>
---
drivers/usb/gadget/function/rndis.c | 8 ++++++++
drivers/usb/gadget/function/rndis.h | 1 +
2 files changed, 9 insertions(+)
--- a/drivers/usb/gadget/function/rndis.c
+++ b/drivers/usb/gadget/function/rndis.c
@@ -924,6 +924,7 @@ struct rndis_params *rndis_register(void
params->resp_avail = resp_avail;
params->v = v;
INIT_LIST_HEAD(¶ms->resp_queue);
+ spin_lock_init(¶ms->resp_lock);
pr_debug("%s: configNr = %d\n", __func__, i);
return params;
@@ -1017,12 +1018,14 @@ void rndis_free_response(struct rndis_pa
{
rndis_resp_t *r, *n;
+ spin_lock(¶ms->resp_lock);
list_for_each_entry_safe(r, n, ¶ms->resp_queue, list) {
if (r->buf == buf) {
list_del(&r->list);
kfree(r);
}
}
+ spin_unlock(¶ms->resp_lock);
}
EXPORT_SYMBOL_GPL(rndis_free_response);
@@ -1032,14 +1035,17 @@ u8 *rndis_get_next_response(struct rndis
if (!length) return NULL;
+ spin_lock(¶ms->resp_lock);
list_for_each_entry_safe(r, n, ¶ms->resp_queue, list) {
if (!r->send) {
r->send = 1;
*length = r->length;
+ spin_unlock(¶ms->resp_lock);
return r->buf;
}
}
+ spin_unlock(¶ms->resp_lock);
return NULL;
}
EXPORT_SYMBOL_GPL(rndis_get_next_response);
@@ -1056,7 +1062,9 @@ static rndis_resp_t *rndis_add_response(
r->length = length;
r->send = 0;
+ spin_lock(¶ms->resp_lock);
list_add_tail(&r->list, ¶ms->resp_queue);
+ spin_unlock(¶ms->resp_lock);
return r;
}
--- a/drivers/usb/gadget/function/rndis.h
+++ b/drivers/usb/gadget/function/rndis.h
@@ -194,6 +194,7 @@ typedef struct rndis_params
void (*resp_avail)(void *v);
void *v;
struct list_head resp_queue;
+ spinlock_t resp_lock;
} rndis_params;
/* RNDIS Message parser and other useless functions */
Powered by blists - more mailing lists