Alsa-Devel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/3] ASoC: SOF: Intel: Do not process IPC reply before firmware boot
@ 2022-07-12 12:23 Peter Ujfalusi
  2022-07-12 12:23 ` [PATCH 1/3] ASoC: SOF: Intel: cnl: " Peter Ujfalusi
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Peter Ujfalusi @ 2022-07-12 12:23 UTC (permalink / raw)
  To: lgirdwood, broonie, pierre-louis.bossart
  Cc: alsa-devel, ranjani.sridharan, kai.vehmanen

Hi,

By mistake a developer managed to create a 'corrupted' IPC4 firmware image which
loaded fine to the DSP and after boot it sent an IPC reply before we would have
received the FW_READY message.
It turned out that the image was an IPC3 firmware and the IPC reply was the IPC3
FW_READY notification message which got understood as an IPC4 reply message due
to the difference between the two IPC mechanism.

This caused a NULL pointer dereference since the reply memory will be allocated
after the FW_READY message.

To make sure this will not bite again, skip any spurious reply messages before
the FW_READY.

Regards,
Peter
---
Peter Ujfalusi (3):
  ASoC: SOF: Intel: cnl: Do not process IPC reply before firmware boot
  ASoC: SOF: Intel: hda-ipc: Do not process IPC reply before firmware
    boot
  ASoC: SOF: Intel: mtl: Do not process IPC reply before firmware boot

 sound/soc/sof/intel/cnl.c     | 37 +++++++++++++++++++++------------
 sound/soc/sof/intel/hda-ipc.c | 39 ++++++++++++++++++++++-------------
 sound/soc/sof/intel/mtl.c     | 20 +++++++++++-------
 3 files changed, 62 insertions(+), 34 deletions(-)

-- 
2.37.0


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 1/3] ASoC: SOF: Intel: cnl: Do not process IPC reply before firmware boot
  2022-07-12 12:23 [PATCH 0/3] ASoC: SOF: Intel: Do not process IPC reply before firmware boot Peter Ujfalusi
@ 2022-07-12 12:23 ` Peter Ujfalusi
  2022-07-12 12:23 ` [PATCH 2/3] ASoC: SOF: Intel: hda-ipc: " Peter Ujfalusi
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Peter Ujfalusi @ 2022-07-12 12:23 UTC (permalink / raw)
  To: lgirdwood, broonie, pierre-louis.bossart
  Cc: alsa-devel, ranjani.sridharan, kai.vehmanen

It is not yet clear, but it is possible to create a firmware so broken
that it will send a reply message before a FW_READY message (it is not
yet clear if FW_READY will arrive later).
Since the reply_data is allocated only after the FW_READY message, this
will lead to a NULL pointer dereference if not filtered out.

The issue was reported with IPC4 firmware but the same condition is present
for IPC3.

Reported-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
---
 sound/soc/sof/intel/cnl.c | 37 ++++++++++++++++++++++++-------------
 1 file changed, 24 insertions(+), 13 deletions(-)

diff --git a/sound/soc/sof/intel/cnl.c b/sound/soc/sof/intel/cnl.c
index ccf46fcd6c9a..a064453f0bc3 100644
--- a/sound/soc/sof/intel/cnl.c
+++ b/sound/soc/sof/intel/cnl.c
@@ -60,17 +60,23 @@ irqreturn_t cnl_ipc4_irq_thread(int irq, void *context)
 
 		if (primary & SOF_IPC4_MSG_DIR_MASK) {
 			/* Reply received */
-			struct sof_ipc4_msg *data = sdev->ipc->msg.reply_data;
+			if (likely(sdev->fw_state == SOF_FW_BOOT_COMPLETE)) {
+				struct sof_ipc4_msg *data = sdev->ipc->msg.reply_data;
 
-			data->primary = primary;
-			data->extension = extension;
+				data->primary = primary;
+				data->extension = extension;
 
-			spin_lock_irq(&sdev->ipc_lock);
+				spin_lock_irq(&sdev->ipc_lock);
 
-			snd_sof_ipc_get_reply(sdev);
-			snd_sof_ipc_reply(sdev, data->primary);
+				snd_sof_ipc_get_reply(sdev);
+				snd_sof_ipc_reply(sdev, data->primary);
 
-			spin_unlock_irq(&sdev->ipc_lock);
+				spin_unlock_irq(&sdev->ipc_lock);
+			} else {
+				dev_dbg_ratelimited(sdev->dev,
+						    "IPC reply before FW_READY: %#x|%#x\n",
+						    primary, extension);
+			}
 		} else {
 			/* Notification received */
 			notification_data.primary = primary;
@@ -124,15 +130,20 @@ irqreturn_t cnl_ipc_irq_thread(int irq, void *context)
 					CNL_DSP_REG_HIPCCTL,
 					CNL_DSP_REG_HIPCCTL_DONE, 0);
 
-		spin_lock_irq(&sdev->ipc_lock);
+		if (likely(sdev->fw_state == SOF_FW_BOOT_COMPLETE)) {
+			spin_lock_irq(&sdev->ipc_lock);
 
-		/* handle immediate reply from DSP core */
-		hda_dsp_ipc_get_reply(sdev);
-		snd_sof_ipc_reply(sdev, msg);
+			/* handle immediate reply from DSP core */
+			hda_dsp_ipc_get_reply(sdev);
+			snd_sof_ipc_reply(sdev, msg);
 
-		cnl_ipc_dsp_done(sdev);
+			cnl_ipc_dsp_done(sdev);
 
-		spin_unlock_irq(&sdev->ipc_lock);
+			spin_unlock_irq(&sdev->ipc_lock);
+		} else {
+			dev_dbg_ratelimited(sdev->dev, "IPC reply before FW_READY: %#x\n",
+					    msg);
+		}
 
 		ipc_irq = true;
 	}
-- 
2.37.0


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 2/3] ASoC: SOF: Intel: hda-ipc: Do not process IPC reply before firmware boot
  2022-07-12 12:23 [PATCH 0/3] ASoC: SOF: Intel: Do not process IPC reply before firmware boot Peter Ujfalusi
  2022-07-12 12:23 ` [PATCH 1/3] ASoC: SOF: Intel: cnl: " Peter Ujfalusi
@ 2022-07-12 12:23 ` Peter Ujfalusi
  2022-07-12 12:23 ` [PATCH 3/3] ASoC: SOF: Intel: mtl: " Peter Ujfalusi
  2022-07-12 18:22 ` [PATCH 0/3] ASoC: SOF: Intel: " Mark Brown
  3 siblings, 0 replies; 5+ messages in thread
From: Peter Ujfalusi @ 2022-07-12 12:23 UTC (permalink / raw)
  To: lgirdwood, broonie, pierre-louis.bossart
  Cc: alsa-devel, ranjani.sridharan, kai.vehmanen

It is not yet clear, but it is possible to create a firmware so broken
that it will send a reply message before a FW_READY message (it is not
yet clear if FW_READY will arrive later).
Since the reply_data is allocated only after the FW_READY message, this
will lead to a NULL pointer dereference if not filtered out.

The issue was reported with IPC4 firmware but the same condition is present
for IPC3.

Reported-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
---
 sound/soc/sof/intel/hda-ipc.c | 39 ++++++++++++++++++++++-------------
 1 file changed, 25 insertions(+), 14 deletions(-)

diff --git a/sound/soc/sof/intel/hda-ipc.c b/sound/soc/sof/intel/hda-ipc.c
index f08011249955..65e688f749ea 100644
--- a/sound/soc/sof/intel/hda-ipc.c
+++ b/sound/soc/sof/intel/hda-ipc.c
@@ -148,17 +148,23 @@ irqreturn_t hda_dsp_ipc4_irq_thread(int irq, void *context)
 
 		if (primary & SOF_IPC4_MSG_DIR_MASK) {
 			/* Reply received */
-			struct sof_ipc4_msg *data = sdev->ipc->msg.reply_data;
+			if (likely(sdev->fw_state == SOF_FW_BOOT_COMPLETE)) {
+				struct sof_ipc4_msg *data = sdev->ipc->msg.reply_data;
 
-			data->primary = primary;
-			data->extension = extension;
+				data->primary = primary;
+				data->extension = extension;
 
-			spin_lock_irq(&sdev->ipc_lock);
+				spin_lock_irq(&sdev->ipc_lock);
 
-			snd_sof_ipc_get_reply(sdev);
-			snd_sof_ipc_reply(sdev, data->primary);
+				snd_sof_ipc_get_reply(sdev);
+				snd_sof_ipc_reply(sdev, data->primary);
 
-			spin_unlock_irq(&sdev->ipc_lock);
+				spin_unlock_irq(&sdev->ipc_lock);
+			} else {
+				dev_dbg_ratelimited(sdev->dev,
+						    "IPC reply before FW_READY: %#x|%#x\n",
+						    primary, extension);
+			}
 		} else {
 			/* Notification received */
 
@@ -225,16 +231,21 @@ irqreturn_t hda_dsp_ipc_irq_thread(int irq, void *context)
 		 * place, the message might not yet be marked as expecting a
 		 * reply.
 		 */
-		spin_lock_irq(&sdev->ipc_lock);
+		if (likely(sdev->fw_state == SOF_FW_BOOT_COMPLETE)) {
+			spin_lock_irq(&sdev->ipc_lock);
 
-		/* handle immediate reply from DSP core */
-		hda_dsp_ipc_get_reply(sdev);
-		snd_sof_ipc_reply(sdev, msg);
+			/* handle immediate reply from DSP core */
+			hda_dsp_ipc_get_reply(sdev);
+			snd_sof_ipc_reply(sdev, msg);
 
-		/* set the done bit */
-		hda_dsp_ipc_dsp_done(sdev);
+			/* set the done bit */
+			hda_dsp_ipc_dsp_done(sdev);
 
-		spin_unlock_irq(&sdev->ipc_lock);
+			spin_unlock_irq(&sdev->ipc_lock);
+		} else {
+			dev_dbg_ratelimited(sdev->dev, "IPC reply before FW_READY: %#x\n",
+					    msg);
+		}
 
 		ipc_irq = true;
 	}
-- 
2.37.0


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 3/3] ASoC: SOF: Intel: mtl: Do not process IPC reply before firmware boot
  2022-07-12 12:23 [PATCH 0/3] ASoC: SOF: Intel: Do not process IPC reply before firmware boot Peter Ujfalusi
  2022-07-12 12:23 ` [PATCH 1/3] ASoC: SOF: Intel: cnl: " Peter Ujfalusi
  2022-07-12 12:23 ` [PATCH 2/3] ASoC: SOF: Intel: hda-ipc: " Peter Ujfalusi
@ 2022-07-12 12:23 ` Peter Ujfalusi
  2022-07-12 18:22 ` [PATCH 0/3] ASoC: SOF: Intel: " Mark Brown
  3 siblings, 0 replies; 5+ messages in thread
From: Peter Ujfalusi @ 2022-07-12 12:23 UTC (permalink / raw)
  To: lgirdwood, broonie, pierre-louis.bossart
  Cc: alsa-devel, ranjani.sridharan, kai.vehmanen

It is not yet clear, but it is possible to create a firmware so broken
that it will send a reply message before a FW_READY message (it is not
yet clear if FW_READY will arrive later).
Since the reply_data is allocated only after the FW_READY message, this
will lead to a NULL pointer dereference if not filtered out.

Reported-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
---
 sound/soc/sof/intel/mtl.c | 20 +++++++++++++-------
 1 file changed, 13 insertions(+), 7 deletions(-)

diff --git a/sound/soc/sof/intel/mtl.c b/sound/soc/sof/intel/mtl.c
index 3a043589c12b..a5e244ea0688 100644
--- a/sound/soc/sof/intel/mtl.c
+++ b/sound/soc/sof/intel/mtl.c
@@ -512,17 +512,23 @@ static irqreturn_t mtl_ipc_irq_thread(int irq, void *context)
 		 */
 		if (primary & SOF_IPC4_MSG_DIR_MASK) {
 			/* Reply received */
-			struct sof_ipc4_msg *data = sdev->ipc->msg.reply_data;
+			if (likely(sdev->fw_state == SOF_FW_BOOT_COMPLETE)) {
+				struct sof_ipc4_msg *data = sdev->ipc->msg.reply_data;
 
-			data->primary = primary;
-			data->extension = extension;
+				data->primary = primary;
+				data->extension = extension;
 
-			spin_lock_irq(&sdev->ipc_lock);
+				spin_lock_irq(&sdev->ipc_lock);
 
-			snd_sof_ipc_get_reply(sdev);
-			snd_sof_ipc_reply(sdev, data->primary);
+				snd_sof_ipc_get_reply(sdev);
+				snd_sof_ipc_reply(sdev, data->primary);
 
-			spin_unlock_irq(&sdev->ipc_lock);
+				spin_unlock_irq(&sdev->ipc_lock);
+			} else {
+				dev_dbg_ratelimited(sdev->dev,
+						    "IPC reply before FW_READY: %#x|%#x\n",
+						    primary, extension);
+			}
 		} else {
 			/* Notification received */
 			notification_data.primary = primary;
-- 
2.37.0


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH 0/3] ASoC: SOF: Intel: Do not process IPC reply before firmware boot
  2022-07-12 12:23 [PATCH 0/3] ASoC: SOF: Intel: Do not process IPC reply before firmware boot Peter Ujfalusi
                   ` (2 preceding siblings ...)
  2022-07-12 12:23 ` [PATCH 3/3] ASoC: SOF: Intel: mtl: " Peter Ujfalusi
@ 2022-07-12 18:22 ` Mark Brown
  3 siblings, 0 replies; 5+ messages in thread
From: Mark Brown @ 2022-07-12 18:22 UTC (permalink / raw)
  To: peter.ujfalusi, pierre-louis.bossart, lgirdwood
  Cc: alsa-devel, ranjani.sridharan, kai.vehmanen

On Tue, 12 Jul 2022 15:23:54 +0300, Peter Ujfalusi wrote:
> By mistake a developer managed to create a 'corrupted' IPC4 firmware image which
> loaded fine to the DSP and after boot it sent an IPC reply before we would have
> received the FW_READY message.
> It turned out that the image was an IPC3 firmware and the IPC reply was the IPC3
> FW_READY notification message which got understood as an IPC4 reply message due
> to the difference between the two IPC mechanism.
> 
> [...]

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next

Thanks!

[1/3] ASoC: SOF: Intel: cnl: Do not process IPC reply before firmware boot
      commit: acacd9eefd0def5a83244d88e5483b5f38ee7287
[2/3] ASoC: SOF: Intel: hda-ipc: Do not process IPC reply before firmware boot
      commit: 499cc881b09c8283ab5e75b0d6d21cb427722161
[3/3] ASoC: SOF: Intel: mtl: Do not process IPC reply before firmware boot
      commit: 1549a69b89b7e5b1b830da897529344766728a4b

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2022-07-12 18:23 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-07-12 12:23 [PATCH 0/3] ASoC: SOF: Intel: Do not process IPC reply before firmware boot Peter Ujfalusi
2022-07-12 12:23 ` [PATCH 1/3] ASoC: SOF: Intel: cnl: " Peter Ujfalusi
2022-07-12 12:23 ` [PATCH 2/3] ASoC: SOF: Intel: hda-ipc: " Peter Ujfalusi
2022-07-12 12:23 ` [PATCH 3/3] ASoC: SOF: Intel: mtl: " Peter Ujfalusi
2022-07-12 18:22 ` [PATCH 0/3] ASoC: SOF: Intel: " Mark Brown

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox