lkml.org 
[lkml]   [2022]   [Sep]   [26]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.15 024/148] ALSA: core: Fix double-free at snd_card_new()
    Date
    From: Takashi Iwai <tiwai@suse.de>

    commit c3afa2a402d1ecefa59f88d55d9e765f52f75bd9 upstream.

    During the code change to add the support for devres-managed card
    instance, we put an explicit kfree(card) call at the error path in
    snd_card_new(). This is needed for the early error path before the
    card is initialized with the device, but is rather superfluous and
    causes a double-free at the error path after the card instance is
    initialized, as the destructor of the card object already contains a
    kfree() call.

    This patch fixes the double-free situation by removing the superfluous
    kfree(). Meanwhile we need to call kfree() explicitly for the early
    error path, so it's added there instead.

    Fixes: e8ad415b7a55 ("ALSA: core: Add managed card creation")
    Reported-by: Rondreis <linhaoguo86@gmail.com>
    Cc: <stable@vger.kernel.org>
    Link: https://lore.kernel.org/r/CAB7eexL1zBnB636hwS27d-LdPYZ_R1-5fJS_h=ZbCWYU=UPWJg@mail.gmail.com
    Link: https://lore.kernel.org/r/20220919123516.28222-1-tiwai@suse.de
    Signed-off-by: Takashi Iwai <tiwai@suse.de>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    ---
    sound/core/init.c | 10 +++++-----
    1 file changed, 5 insertions(+), 5 deletions(-)

    --- a/sound/core/init.c
    +++ b/sound/core/init.c
    @@ -178,10 +178,8 @@ int snd_card_new(struct device *parent,
    return -ENOMEM;

    err = snd_card_init(card, parent, idx, xid, module, extra_size);
    - if (err < 0) {
    - kfree(card);
    - return err;
    - }
    + if (err < 0)
    + return err; /* card is freed by error handler */

    *card_ret = card;
    return 0;
    @@ -231,7 +229,7 @@ int snd_devm_card_new(struct device *par
    card->managed = true;
    err = snd_card_init(card, parent, idx, xid, module, extra_size);
    if (err < 0) {
    - devres_free(card);
    + devres_free(card); /* in managed mode, we need to free manually */
    return err;
    }

    @@ -293,6 +291,8 @@ static int snd_card_init(struct snd_card
    mutex_unlock(&snd_card_mutex);
    dev_err(parent, "cannot find the slot for index %d (range 0-%i), error: %d\n",
    idx, snd_ecards_limit - 1, err);
    + if (!card->managed)
    + kfree(card); /* manually free here, as no destructor called */
    return err;
    }
    set_bit(idx, snd_cards_lock); /* lock it */

    \
     
     \ /
      Last update: 2022-09-26 13:15    [W:4.473 / U:0.944 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site