mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2025-01-10 23:20:05 +00:00
ASoC: SOF: Intel: cnl: Do not process IPC reply before firmware boot
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> Link: https://lore.kernel.org/r/20220712122357.31282-2-peter.ujfalusi@linux.intel.com Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
parent
388fe2b8a3
commit
acacd9eefd
@ -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;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user