-From foo@baz Sun Aug 26 09:13:00 CEST 2018
+From 39e729351eec2fe292396096cd8bb152824c37a1 Mon Sep 17 00:00:00 2001
From: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
Date: Thu, 21 Jun 2018 17:22:52 +0200
-Subject: usb: gadget: u_audio: protect stream runtime fields with stream spinlock
-
-From: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
+Subject: [PATCH 23/82] usb: gadget: u_audio: protect stream runtime fields
+ with stream spinlock
[ Upstream commit 56bc61587daadef67712068f251c4ef2e3932d94 ]
consistently reproduce BUG: KASAN: use-after-free [2]]
[1] Instrumentation to reproduce issue [2]:
- diff --git a/drivers/usb/gadget/function/u_audio.c b/drivers/usb/gadget/function/u_audio.c
- index a72295c953bb..bd0b308024fe 100644
- --- a/drivers/usb/gadget/function/u_audio.c
- +++ b/drivers/usb/gadget/function/u_audio.c
- @@ -16,6 +16,7 @@
- #include <sound/core.h>
- #include <sound/pcm.h>
- #include <sound/pcm_params.h>
- +#include <linux/delay.h>
-
- #include "u_audio.h"
-
- @@ -147,6 +148,8 @@ static void u_audio_iso_complete(struct usb_ep *ep, struct usb_request *req)
-
- spin_unlock_irqrestore(&prm->lock, flags);
-
- + udelay(500); //delay here to increase probability of parallel activities
- +
- /* Pack USB load in ALSA ring buffer */
- pending = prm->dma_bytes - hw_ptr;
+# diff --git a/drivers/usb/gadget/function/u_audio.c b/drivers/usb/gadget/function/u_audio.c
+# index a72295c953bb..bd0b308024fe 100644
+# --- a/drivers/usb/gadget/function/u_audio.c
+# +++ b/drivers/usb/gadget/function/u_audio.c
+# @@ -16,6 +16,7 @@
+# #include <sound/core.h>
+# #include <sound/pcm.h>
+# #include <sound/pcm_params.h>
+# +#include <linux/delay.h>
+#
+# #include "u_audio.h"
+#
+# @@ -147,6 +148,8 @@ static void u_audio_iso_complete(struct usb_ep *ep, struct usb_request *req)
+#
+# spin_unlock_irqrestore(&prm->lock, flags);
+#
+# + udelay(500); //delay here to increase probability of parallel activities
+# +
+# /* Pack USB load in ALSA ring buffer */
+# pending = prm->dma_bytes - hw_ptr;
[2] After applying [1], below BUG occurs on Rcar-H3-Salvator-X board:
==================================================================
Fixes: 132fcb460839 ("usb: gadget: Add Audio Class 2.0 Driver")
Signed-off-by: Eugeniu Rosca <erosca@de.adit-jv.com>
-
Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
-
Signed-off-by: Sasha Levin <alexander.levin@microsoft.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
- drivers/usb/gadget/function/u_audio.c | 13 ++++++++++++-
- 1 file changed, 12 insertions(+), 1 deletion(-)
+ drivers/usb/gadget/function/u_audio.c | 10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+diff --git a/drivers/usb/gadget/function/u_audio.c b/drivers/usb/gadget/function/u_audio.c
+index e9644137f720..d3a639297e06 100644
--- a/drivers/usb/gadget/function/u_audio.c
+++ b/drivers/usb/gadget/function/u_audio.c
-@@ -25,6 +25,7 @@
- #include <sound/core.h>
- #include <sound/pcm.h>
- #include <sound/pcm_params.h>
-+#include <linux/delay.h>
-
- #include "u_audio.h"
-
-@@ -88,7 +89,7 @@ static const struct snd_pcm_hardware uac
+@@ -88,7 +88,7 @@ static const struct snd_pcm_hardware uac_pcm_hardware = {
static void u_audio_iso_complete(struct usb_ep *ep, struct usb_request *req)
{
unsigned pending;
unsigned int hw_ptr;
int status = req->status;
struct uac_req *ur = req->context;
-@@ -115,7 +116,14 @@ static void u_audio_iso_complete(struct
+@@ -115,7 +115,14 @@ static void u_audio_iso_complete(struct usb_ep *ep, struct usb_request *req)
if (!substream)
goto exit;
spin_lock_irqsave(&prm->lock, flags);
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
-@@ -146,6 +154,8 @@ static void u_audio_iso_complete(struct
-
- spin_unlock_irqrestore(&prm->lock, flags);
-
-+ udelay(500); //delay here to increase probability of parallel activities
-+
- /* Pack USB load in ALSA ring buffer */
- pending = runtime->dma_bytes - hw_ptr;
-
-@@ -174,6 +184,7 @@ static void u_audio_iso_complete(struct
+@@ -174,6 +181,7 @@ static void u_audio_iso_complete(struct usb_ep *ep, struct usb_request *req)
prm->hw_ptr = (hw_ptr + req->actual) % runtime->dma_bytes;
hw_ptr = prm->hw_ptr;
spin_unlock_irqrestore(&prm->lock, flags);
if ((hw_ptr % snd_pcm_lib_period_bytes(substream)) < req->actual)
snd_pcm_period_elapsed(substream);
+--
+2.18.0
+