lkml.org 
[lkml]   [2022]   [Aug]   [23]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.19 328/365] ASoC: SOF: Intel: cnl: Do not process IPC reply before firmware boot
    Date
    From: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>

    [ Upstream commit acacd9eefd0def5a83244d88e5483b5f38ee7287 ]

    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>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    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 cd6e5f8a5eb4..6c98f65635fc 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.35.1


    \
     
     \ /
      Last update: 2022-08-23 11:24    [W:4.034 / U:0.316 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site