All of lore.kernel.org
 help / color / mirror / Atom feed
From: Takashi Iwai <tiwai@suse.de>
To: Cen Zhang <zzzccc427@gmail.com>
Cc: Takashi Iwai <tiwai@suse.de>,
	perex@perex.cz, tiwai@suse.com, linux-sound@vger.kernel.org,
	linux-kernel@vger.kernel.org, baijiaju1990@gmail.com,
	jjzuming@gmail.com
Subject: Re: [PATCH] ALSA: info: Serialize freeing with recursive registration
Date: Sat, 17 Oct 2026 12:31:54 +0200	[thread overview]
Message-ID: <87ecdo1uud.wl-tiwai@suse.de> (raw)
In-Reply-To: <CAFRLqsVs8BGNHb8qG6nnrCc=fafMYAmCSDuXDb8uBRBrgJhnEA@mail.gmail.com>

On Sat, 17 Oct 2026 11:27:54 +0200,
Cen Zhang wrote:
> 
> Hi Takashi,
> 
> >
> > Does the above crash really happen with unmodified code?
> > The PCM oss proc unregister is per card, hence there can't be race
> > between register and unregister for the same card.
> >
> > The hardening itself in the proc code is good, per se (although it's
> > doubtful whether we really need a global mutex from the performance
> > POV), though.
> >
> >
> > thanks,
> >
> > Takashi
> 
> 
> Thank you for the review. The quoted KASAN report used scheduling
> instrumentation
> and a small test module that called snd_card_register() on an already registered
> dummy card.
> 
> But reviewing the source, I found a concrete scenario involving
> existing in-tree callers that appears to allow this race.
> 
> Consider a registered card with PCM A and its published OSS proc
> entry. A later bind of another codec B on the same card can reach
> hda_codec_driver_probe(), which calls snd_card_register() when
> !bus_probing && card->registered.
> 
> At the same time, snd-pcm-oss can be unloaded while the card remains
> registered, provided no active OSS references prevent the unload.
> alsa_pcm_oss_exit() calls snd_pcm_notify(..., 1), which invokes
> n_unregister() for the registered PCM devices and frees their OSS
> proc entries.
> 
> The interleaving I believe the source permits is:
> 
>   HDA codec B probe                  snd-pcm-oss module exit
>   -----------------                  -----------------------
>   snd_card_register(card)
>     snd_device_register_all(card)
>     /* PCM register_mutex released */
> 
>                                      lock(register_mutex)
>                                      n_unregister(PCM A)
>                                        snd_info_free_entry(entry)
>                                          proc_remove(entry->p)
>                                          lock(info_mutex)
>                                          entry->p = NULL
>                                          unlock(info_mutex)
>                                          /* entry still linked */
> 
>     lock(snd_card_mutex)
>     snd_info_card_register(card)
>       snd_info_register(card->proc_root)
>         find PCM A's linked entry
>         lock(info_mutex)
>         recreate proc node with
>           entry as private data
>         unlock(info_mutex)
>     unlock(snd_card_mutex)
> 
>                                      unlink entry
>                                      kfree(entry)
>                                      unlock(register_mutex)
> 
> The card-info traversal does not hold the PCM register_mutex, and
> OSS notifier removal does not take snd_card_mutex. The parent proc
> directories also remain present because the card and PCM A have
> not been removed.
> 
> This appears to allow the new proc node to retain a pointer to the
> freed entry. A subsequent open could then reach alloc_info_private()
> with that stale pointer. Please let me know if I have overlooked
> another serialization point in this path.

OK, the arbitrary OSS removal is the problem child.

IMO, instead of hardening piece-by-piece in ad hoc ways, we can pin
the OSS PCM and mixer module when any card is added and unpin at the
card removal, so that we can't unload OSS modules while there are any
actually used cards.

The cases with the partial HDA codec probe/remove is a different
problem, though.  This has to be addressed somehow better.


thanks,

Takashi

  reply	other threads:[~2026-10-17 10:31 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-17  6:58 [PATCH] ALSA: info: Serialize freeing with recursive registration Cen Zhang
2026-10-17  8:25 ` Takashi Iwai
2026-10-17  9:27   ` Cen Zhang
2026-10-17 10:31     ` Takashi Iwai [this message]
2026-10-17 10:47       ` Takashi Iwai
2026-10-17 15:14         ` Cen Zhang

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=87ecdo1uud.wl-tiwai@suse.de \
    --to=tiwai@suse.de \
    --cc=baijiaju1990@gmail.com \
    --cc=jjzuming@gmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-sound@vger.kernel.org \
    --cc=perex@perex.cz \
    --cc=tiwai@suse.com \
    --cc=zzzccc427@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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.