From: Takashi Iwai <tiwai@suse.de>
To: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Cc: alsa-devel@alsa-project.org, Zheyu Ma <zheyuma97@gmail.com>
Subject: Re: [PATCH 1/2] ALSA: core: Add snd_card_free_on_error() helper
Date: Tue, 12 Apr 2022 14:23:55 +0200 [thread overview]
Message-ID: <s5hilrea3s4.wl-tiwai@suse.de> (raw)
In-Reply-To: <YlVY08C4/maO5s93@workstation>
On Tue, 12 Apr 2022 12:47:47 +0200,
Takashi Sakamoto wrote:
>
> Hi,
>
> On Tue, Apr 12, 2022 at 11:31:40AM +0200, Takashi Iwai wrote:
> > This is a small helper function to handle the error path more easily
> > when an error happens during the probe for the device with the
> > device-managed card. Since devres releases in the reverser order of
> > the creations, usually snd_card_free() gets called at the last in the
> > probe error path unless it already reached snd_card_register() calls.
> > Due to this nature, when a driver expects the resource releases in
> > card->private_free, this might be called too lately.
> >
> > As a workaround, one should call the probe like:
> >
> > static int __some_probe(...) { // do real probe.... }
> >
> > static int some_probe(...)
> > {
> > return snd_card_free_on_error(dev, __some_probe(dev, ...));
> > }
> >
> > so that the snd_card_free() is called explicitly at the beginning of
> > the error path from the probe.
> >
> > This function will be used in the upcoming fixes to address the
> > regressions by devres usages.
> >
> > Fixes: e8ad415b7a55 ("ALSA: core: Add managed card creation")
> > Cc: <stable@vger.kernel.org>
> > Signed-off-by: Takashi Iwai <tiwai@suse.de>
> > ---
> > include/sound/core.h | 1 +
> > sound/core/init.c | 28 ++++++++++++++++++++++++++++
> > 2 files changed, 29 insertions(+)
> >
> > diff --git a/include/sound/core.h b/include/sound/core.h
> > index b7e9b58d3c78..6d4cc49584c6 100644
> > --- a/include/sound/core.h
> > +++ b/include/sound/core.h
> > @@ -284,6 +284,7 @@ int snd_card_disconnect(struct snd_card *card);
> > void snd_card_disconnect_sync(struct snd_card *card);
> > int snd_card_free(struct snd_card *card);
> > int snd_card_free_when_closed(struct snd_card *card);
> > +int snd_card_free_on_error(struct device *dev, int ret);
> > void snd_card_set_id(struct snd_card *card, const char *id);
> > int snd_card_register(struct snd_card *card);
> > int snd_card_info_init(void);
> > diff --git a/sound/core/init.c b/sound/core/init.c
> > index 31ba7024e3ad..726a8353201f 100644
> > --- a/sound/core/init.c
> > +++ b/sound/core/init.c
> > @@ -209,6 +209,12 @@ static void __snd_card_release(struct device *dev, void *data)
> > * snd_card_register(), the very first devres action to call snd_card_free()
> > * is added automatically. In that way, the resource disconnection is assured
> > * at first, then released in the expected order.
> > + *
> > + * If an error happens at the probe before snd_card_register() is called and
> > + * there have been other devres resources, you'd need to free the card manually
> > + * via snd_card_free() call in the error; otherwise it may lead to UAF due to
> > + * devres call orders. You can use snd_card_free_on_error() helper for
> > + * handling it more easily.
> > */
> > int snd_devm_card_new(struct device *parent, int idx, const char *xid,
> > struct module *module, size_t extra_size,
> > @@ -235,6 +241,28 @@ int snd_devm_card_new(struct device *parent, int idx, const char *xid,
> > }
> > EXPORT_SYMBOL_GPL(snd_devm_card_new);
> >
> > +/**
> > + * snd_card_free_on_error - a small helper for handling devm probe errors
> > + * @dev: the managed device object
> > + * @ret: the return code from the probe callback
> > + *
> > + * This function handles the explicit snd_card_free() call at the error from
> > + * the probe callback. It's just a small helper for simplifying the error
> > + * handling with the managed devices.
> > + */
> > +int snd_card_free_on_error(struct device *dev, int ret)
> > +{
> > + struct snd_card *card;
> > +
> > + if (!ret)
> > + return 0;
> > + card = devres_find(dev, __snd_card_release, NULL, NULL);
> > + if (card)
> > + snd_card_free(card);
> > + return ret;
> > +}
> > +EXPORT_SYMBOL_GPL(snd_card_free_on_error);
> > +
> > static int snd_card_init(struct snd_card *card, struct device *parent,
> > int idx, const char *xid, struct module *module,
> > size_t extra_size)
> > --
> > 2.31.1
>
> The idea looks good itself to me. On the other hand, the name
> 'snd_card_free_on_error()' is not so suitable since it assumes that
> 'snd_devm_card_new()' is called in advance, while we have another function,
> 'snd_card_new()'.
>
> I think it better to use 'snd_devm_card_free_on_error()' instead since
> the function doesn't work as expected in the case of 'snd_card_new()'
> (the snd_card_free() is not called because nothing found in devres).
Yeah, that came to my mind in the first implementations, too, but it
looked too long to me, so I took this term in the submitted version :)
In theory, we can extend it to retrieve the card from the device data,
too, but I don't think worth for it.
thanks,
Takashi
next prev parent reply other threads:[~2022-04-12 12:24 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-04-12 9:31 [PATCH 0/2] ALSA: echoaudio: Fix the probe error handling Takashi Iwai
2022-04-12 9:31 ` [PATCH 1/2] ALSA: core: Add snd_card_free_on_error() helper Takashi Iwai
2022-04-12 10:47 ` Takashi Sakamoto
2022-04-12 12:23 ` Takashi Iwai [this message]
2022-04-12 9:31 ` [PATCH 2/2] ALSA: echoaudio: Fix the missing snd_card_free() call at probe error Takashi Iwai
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=s5hilrea3s4.wl-tiwai@suse.de \
--to=tiwai@suse.de \
--cc=alsa-devel@alsa-project.org \
--cc=o-takashi@sakamocchi.jp \
--cc=zheyuma97@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox