]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
ASoC: sma1307: Fix error handling in sma1307_setting_loaded()
authorDan Carpenter <dan.carpenter@linaro.org>
Fri, 21 Mar 2025 14:35:25 +0000 (17:35 +0300)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 29 May 2025 09:13:47 +0000 (11:13 +0200)
[ Upstream commit 012a6efcc805308b1d90a1056ba963eb08858645 ]

There are a couple bugs in this code:

1) The cleanup code calls kfree(sma1307->set.header) and
   kfree(sma1307->set.def) but those functions were allocated using
   devm_kzalloc().  It results in a double free.  Delete all these
   kfree() calls.

2) A missing call to kfree(data) if the checksum was wrong on this error
   path:
if ((sma1307->set.checksum >> 8) != SMA1307_SETTING_CHECKSUM) {
   Since the "data" pointer is supposed to be freed on every return, I
   changed that to use the __free(kfree) cleanup attribute.

Fixes: 0ec6bd16705f ("ASoC: sma1307: Add NULL check in sma1307_setting_loaded()")
Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
Link: https://patch.msgid.link/8d32dd96-1404-4373-9b6c-c612a9c18c4c@stanley.mountain
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
sound/soc/codecs/sma1307.c

index b9d8136fe3dc1aa11780df90b27d735fa522b5fa..793abec56dd27d0b7ddab009e65b2ae11c183e5f 100644 (file)
@@ -1710,7 +1710,7 @@ static void sma1307_check_fault_worker(struct work_struct *work)
 static void sma1307_setting_loaded(struct sma1307_priv *sma1307, const char *file)
 {
        const struct firmware *fw;
-       int *data, size, offset, num_mode;
+       int size, offset, num_mode;
        int ret;
 
        ret = request_firmware(&fw, file, sma1307->dev);
@@ -1727,7 +1727,7 @@ static void sma1307_setting_loaded(struct sma1307_priv *sma1307, const char *fil
                return;
        }
 
-       data = kzalloc(fw->size, GFP_KERNEL);
+       int *data __free(kfree) = kzalloc(fw->size, GFP_KERNEL);
        if (!data) {
                release_firmware(fw);
                sma1307->set.status = false;
@@ -1747,7 +1747,6 @@ static void sma1307_setting_loaded(struct sma1307_priv *sma1307, const char *fil
                                           sma1307->set.header_size,
                                           GFP_KERNEL);
        if (!sma1307->set.header) {
-               kfree(data);
                sma1307->set.status = false;
                return;
        }
@@ -1768,8 +1767,6 @@ static void sma1307_setting_loaded(struct sma1307_priv *sma1307, const char *fil
            = devm_kzalloc(sma1307->dev,
                           sma1307->set.def_size * sizeof(int), GFP_KERNEL);
        if (!sma1307->set.def) {
-               kfree(data);
-               kfree(sma1307->set.header);
                sma1307->set.status = false;
                return;
        }
@@ -1787,9 +1784,6 @@ static void sma1307_setting_loaded(struct sma1307_priv *sma1307, const char *fil
                                   sma1307->set.mode_size * 2 * sizeof(int),
                                   GFP_KERNEL);
                if (!sma1307->set.mode_set[i]) {
-                       kfree(data);
-                       kfree(sma1307->set.header);
-                       kfree(sma1307->set.def);
                        for (int j = 0; j < i; j++)
                                kfree(sma1307->set.mode_set[j]);
                        sma1307->set.status = false;
@@ -1804,7 +1798,6 @@ static void sma1307_setting_loaded(struct sma1307_priv *sma1307, const char *fil
                }
        }
 
-       kfree(data);
        sma1307->set.status = true;
 
 }