]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
ASoC: codecs: Fix atomicity violation in snd_soc_component_get_drvdata()
authorQiu-ji Chen <chenqiuji666@gmail.com>
Mon, 30 Sep 2024 10:12:16 +0000 (18:12 +0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 5 Dec 2024 09:59:38 +0000 (10:59 +0100)
commit 1157733344651ca505e259d6554591ff156922fa upstream.

An atomicity violation occurs when the validity of the variables
da7219->clk_src and da7219->mclk_rate is being assessed. Since the entire
assessment is not protected by a lock, the da7219 variable might still be
in flux during the assessment, rendering this check invalid.

To fix this issue, we recommend adding a lock before the block
if ((da7219->clk_src == clk_id) && (da7219->mclk_rate == freq)) so that
the legitimacy check for da7219->clk_src and da7219->mclk_rate is
protected by the lock, ensuring the validity of the check.

This possible bug is found by an experimental static analysis tool
developed by our team. This tool analyzes the locking APIs
to extract function pairs that can be concurrently executed, and then
analyzes the instructions in the paired functions to identify possible
concurrency bugs including data races and atomicity violations.

Fixes: 6d817c0e9fd7 ("ASoC: codecs: Add da7219 codec driver")
Cc: stable@vger.kernel.org
Signed-off-by: Qiu-ji Chen <chenqiuji666@gmail.com>
Link: https://patch.msgid.link/20240930101216.23723-1-chenqiuji666@gmail.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
sound/soc/codecs/da7219.c

index e46e9f4bc994681615b25066054d20867d3507cb..9a93f77ceb0f26a4a2e70fad381aaee441e87620 100644 (file)
@@ -1164,17 +1164,20 @@ static int da7219_set_dai_sysclk(struct snd_soc_dai *codec_dai,
        struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
        int ret = 0;
 
-       if ((da7219->clk_src == clk_id) && (da7219->mclk_rate == freq))
+       mutex_lock(&da7219->pll_lock);
+
+       if ((da7219->clk_src == clk_id) && (da7219->mclk_rate == freq)) {
+               mutex_unlock(&da7219->pll_lock);
                return 0;
+       }
 
        if ((freq < 2000000) || (freq > 54000000)) {
+               mutex_unlock(&da7219->pll_lock);
                dev_err(codec_dai->dev, "Unsupported MCLK value %d\n",
                        freq);
                return -EINVAL;
        }
 
-       mutex_lock(&da7219->pll_lock);
-
        switch (clk_id) {
        case DA7219_CLKSRC_MCLK_SQR:
                snd_soc_component_update_bits(component, DA7219_PLL_CTRL,