All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Mikhail Gavrilov" <mikhail.v.gavrilov@gmail.com>
Cc: dmitry.torokhov@gmail.com, linux-input@vger.kernel.org
Subject: Re: [RFC PATCH 1/2] HID: topping-m62: driver for the M62's vendor controls
Date: Fri, 04 Sep 2026 11:38:00 +0000	[thread overview]
Message-ID: <20260904113800.DC4281F00A3E@smtp.kernel.org> (raw)
In-Reply-To: <20260904112610.3286659-2-mikhail.v.gavrilov@gmail.com>

Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
- [High] Use-After-Free of `snd_kcontrol` and potentially `snd_card` in `topping_raw_event` due to dereferencing pointers after releasing the spinlock
- [High] Race condition in `topping_unbind` can strand delayed work `m62->keepalive`, leading to a Use-After-Free
- [Medium] API Contract Violation: Unconditional cleanup loop passes NULL pointers to `snd_ctl_remove()`, triggering kernel warnings
--

commit 172808f08cae9fcb08d59263a0babfa30be89c2c
Author: Mikhail Gavrilov <mikhail.v.gavrilov@gmail.com>

    HID: topping-m62: driver for the M62's vendor controls
    
    The Topping M62 is a USB audio interface whose analogue input gains,
    output volumes and output source selectors are not described by the USB
    Audio Class. They live behind a vendor protocol on a HID-class
    interface, spoken by Topping's M Control Center, which has no Linux
    build.

> diff --git a/drivers/hid/hid-topping-m62.c b/drivers/hid/hid-topping-m62.c
> index 0000000000000..0ef407ffb46b7
> --- /dev/null
> +++ b/drivers/hid/hid-topping-m62.c
[ ... ]
> +static int topping_raw_event(struct hid_device *hdev,
> +			     struct hid_report *report, u8 *data, int size)
> +{
[ ... ]
> +	scoped_guard(spinlock_irqsave, &m62->lock) {
> +		card = m62->card;
> +		if (m62->val[idx] != value) {
> +			m62->val[idx] = value;
> +			kctl = m62->kctl[idx];
> +		}
> +	}
> +
> +	/*
> +	 * A frame that arrived just as the audio side was unbinding can
> +	 * notify an id that has already gone.  snd_ctl_notify() takes a
> +	 * copy of the id and touches nothing that unbind frees, so such
> +	 * an event is merely wasted.
> +	 */
> +	if (card && kctl)
> +		snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, &kctl->id);
                                                                 ^^^^^^^^^

[Severity: High]
Does this code risk a use-after-free by passing a pointer to the kctl id
after releasing the lock?

If the audio component unbinds concurrently, topping_unbind() will execute,
clearing m62->card under the lock and freeing the kctl structures via
snd_ctl_remove(). 

When topping_raw_event() resumes and calls snd_ctl_notify(), the &kctl->id
pointer references freed memory. Because snd_ctl_notify() takes the ID by
reference rather than by copy, it will dereference this freed memory,
leading to memory corruption.

[ ... ]
> +static void topping_drop_kctls(struct topping_m62 *m62, struct snd_card *card)
> +{
> +	int i;
> +
> +	for (i = 0; i < TOPPING_NUM_KCTLS; i++) {
> +		snd_ctl_remove(card, m62->kctl[i]);
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

[Severity: Medium]
Will this unconditionally pass a NULL pointer to snd_ctl_remove() if a
control fails to allocate during probe?

If topping_add_kctl() fails, topping_bind() jumps to the err_drop label
and calls topping_drop_kctls(). The loop iterates over all indices in
the array and calls snd_ctl_remove() on them.

For any controls that were never allocated, m62->kctl[i] will be NULL.
Calling snd_ctl_remove() on a NULL pointer triggers ALSA's internal
snd_BUG_ON macro, which generates stack traces in dmesg.

> +		m62->kctl[i] = NULL;
> +	}
> +}
[ ... ]
> +static void topping_unbind(struct device *comp, struct device *master,
> +			   void *master_data)
> +{
> +	struct hid_device *hdev = to_hid_device(comp);
> +	struct topping_m62 *m62 = hid_get_drvdata(hdev);
> +	struct snd_card *card = master_data;
> +
> +	cancel_delayed_work_sync(&m62->keepalive);
> +
> +	/*
> +	 * Stop reporting before the controls go, so that a frame in
> +	 * flight cannot look up a control this function is removing.
> +	 */
> +	scoped_guard(spinlock_irqsave, &m62->lock)
> +		m62->card = NULL;
                ^^^^^^^^^^^^^^^^

[Severity: High]
Can a concurrent resume strand the delayed work and cause a use-after-free
if it is scheduled after cancel_delayed_work_sync() executes?

Because the work is cancelled before the m62->card synchronization flag is
cleared, a runtime resume occurring in this narrow window can observe that
m62->card is still valid. 

The topping_resume() function would then erroneously call
schedule_delayed_work(). Since the component is already unbound,
topping_remove() will eventually free the m62 structure without canceling
this newly scheduled work, allowing the timer to fire on freed memory.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260904112610.3286659-1-mikhail.v.gavrilov@gmail.com?part=1

  reply	other threads:[~2026-09-04 11:38 UTC|newest]

Thread overview: 74+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-12 17:10 snd-usb-audio: exposing a vendor HID control channel as mixer controls (Topping M62, 152a:875c) Mikhail Gavrilov
2026-08-13  7:24 ` Takashi Iwai
2026-08-20 15:13   ` [RFC 0/2] Two ways to reach the Topping M62's analogue gains Mikhail Gavrilov
2026-08-20 15:13     ` [RFC 1/2] ALSA: usb-audio: expose the Topping M62's analogue gains as mixer controls Mikhail Gavrilov
2026-08-20 15:13     ` [RFC 2/2] HID: topping: driver for the M62's vendor control channel Mikhail Gavrilov
2026-08-21 11:23     ` [RFC 0/2] Two ways to reach the Topping M62's analogue gains Mikhail Gavrilov
2026-08-23  8:50     ` Takashi Iwai
2026-08-23 14:22     ` [PATCH v2 0/2] ALSA: usb-audio: the Topping M62's vendor controls Mikhail Gavrilov
2026-08-23 14:22       ` [PATCH v2 1/2] ALSA: usb-audio: expose the Topping M62's analogue gains as mixer controls Mikhail Gavrilov
2026-08-23 14:38         ` sashiko-bot
2026-08-23 14:22       ` [PATCH v2 2/2] ALSA: usb-audio: let the M62's outputs say what they listen to Mikhail Gavrilov
2026-08-23 14:38         ` sashiko-bot
2026-08-23 19:48       ` [PATCH v3 0/2] ALSA: usb-audio: the Topping M62's vendor controls Mikhail Gavrilov
2026-08-23 19:48         ` [PATCH v3 1/2] ALSA: usb-audio: expose the Topping M62's analogue gains as mixer controls Mikhail Gavrilov
2026-08-23 20:07           ` sashiko-bot
2026-08-23 19:48         ` [PATCH v3 2/2] ALSA: usb-audio: let the M62's outputs say what they listen to Mikhail Gavrilov
2026-08-23 20:03           ` sashiko-bot
2026-08-23 22:29         ` [PATCH v4 0/2] ALSA: usb-audio: the Topping M62's vendor controls Mikhail Gavrilov
2026-08-23 22:29           ` [PATCH v4 1/2] ALSA: usb-audio: expose the Topping M62's analogue gains as mixer controls Mikhail Gavrilov
2026-08-23 22:46             ` sashiko-bot
2026-08-23 22:29           ` [PATCH v4 2/2] ALSA: usb-audio: let the M62's outputs say what they listen to Mikhail Gavrilov
2026-08-23 22:46             ` sashiko-bot
2026-08-24 20:13           ` [PATCH v5 0/2] ALSA: usb-audio: the Topping M62's vendor controls Mikhail Gavrilov
2026-08-24 20:13             ` [PATCH v5 1/2] ALSA: usb-audio: expose the Topping M62's analogue gains as mixer controls Mikhail Gavrilov
2026-08-24 20:40               ` sashiko-bot
2026-08-24 20:13             ` [PATCH v5 2/2] ALSA: usb-audio: let the M62's outputs say what they listen to Mikhail Gavrilov
2026-08-24 20:25               ` sashiko-bot
2026-08-24 22:31             ` [PATCH v6 0/2] ALSA: usb-audio: the Topping M62's vendor controls Mikhail Gavrilov
2026-08-24 22:31               ` [PATCH v6 1/2] ALSA: usb-audio: expose the Topping M62's analogue gains as mixer controls Mikhail Gavrilov
2026-08-24 22:47                 ` sashiko-bot
2026-08-24 22:31               ` [PATCH v6 2/2] ALSA: usb-audio: let the M62's outputs say what they listen to Mikhail Gavrilov
2026-08-24 22:58                 ` sashiko-bot
2026-08-25  8:56               ` [PATCH v7 0/2] ALSA: usb-audio: the Topping M62's vendor controls Mikhail Gavrilov
2026-08-25  8:56                 ` [PATCH v7 1/2] ALSA: usb-audio: expose the Topping M62's analogue gains as mixer controls Mikhail Gavrilov
2026-08-25  9:12                   ` sashiko-bot
2026-08-25  8:56                 ` [PATCH v7 2/2] ALSA: usb-audio: let the M62's outputs say what they listen to Mikhail Gavrilov
2026-08-25 11:12                 ` [PATCH v8 0/2] ALSA: usb-audio: the Topping M62's vendor controls Mikhail Gavrilov
2026-08-25 11:12                   ` [PATCH v8 1/2] ALSA: usb-audio: expose the Topping M62's analogue gains as mixer controls Mikhail Gavrilov
2026-08-25 11:12                   ` [PATCH v8 2/2] ALSA: usb-audio: let the M62's outputs say what they listen to Mikhail Gavrilov
2026-08-26 18:06                   ` [PATCH v8 0/2] ALSA: usb-audio: the Topping M62's vendor controls Mikhail Gavrilov
2026-09-03  8:30                     ` Takashi Iwai
2026-09-03  9:35                       ` Mikhail Gavrilov
2026-09-03 10:02                         ` Takashi Iwai
2026-09-03 10:19                           ` Mikhail Gavrilov
2026-09-04  0:18                           ` Mikhail Gavrilov
2026-09-04  7:05                             ` Mikhail Gavrilov
2026-09-04 11:26                               ` [RFC PATCH 0/2] the Topping M62's vendor controls, on the component framework Mikhail Gavrilov
2026-09-04 11:26                                 ` [RFC PATCH 1/2] HID: topping-m62: driver for the M62's vendor controls Mikhail Gavrilov
2026-09-04 11:38                                   ` sashiko-bot [this message]
2026-09-04 11:26                                 ` [RFC PATCH 2/2] ALSA: usb-audio: bind the Topping " Mikhail Gavrilov
2026-09-04 11:40                                   ` sashiko-bot
2026-09-04 14:11                                 ` [RFC PATCH v2 0/2] the Topping M62's vendor controls, on the component framework Mikhail Gavrilov
2026-09-04 14:11                                   ` [RFC PATCH v2 1/2] HID: topping-m62: driver for the M62's vendor controls Mikhail Gavrilov
2026-09-04 14:21                                     ` sashiko-bot
2026-09-04 14:11                                   ` [RFC PATCH v2 2/2] ALSA: usb-audio: bind the Topping " Mikhail Gavrilov
2026-09-04 14:24                                     ` sashiko-bot
2026-09-04 14:42                                   ` [RFC PATCH v3 0/2] the Topping M62's vendor controls, on the component framework Mikhail Gavrilov
2026-09-04 14:42                                     ` [RFC PATCH v3 1/2] HID: topping-m62: driver for the M62's vendor controls Mikhail Gavrilov
2026-09-04 14:57                                       ` sashiko-bot
2026-09-04 14:43                                     ` [RFC PATCH v3 2/2] ALSA: usb-audio: bind the Topping " Mikhail Gavrilov
2026-09-04 15:11                                       ` sashiko-bot
2026-09-04 15:30                                     ` [RFC PATCH v4 0/2] the Topping M62's vendor controls, on the component framework Mikhail Gavrilov
2026-09-04 15:30                                       ` [RFC PATCH v4 1/2] HID: topping-m62: driver for the M62's vendor controls Mikhail Gavrilov
2026-09-04 15:30                                       ` [RFC PATCH v4 2/2] ALSA: usb-audio: bind the Topping " Mikhail Gavrilov
2026-09-04 15:45                                         ` sashiko-bot
2026-09-04 16:22                                       ` [RFC PATCH v5 0/2] the Topping M62's vendor controls, on the component framework Mikhail Gavrilov
2026-09-04 16:22                                         ` [RFC PATCH v5 1/2] HID: topping-m62: driver for the M62's vendor controls Mikhail Gavrilov
2026-09-04 16:22                                         ` [RFC PATCH v5 2/2] ALSA: usb-audio: bind the Topping " Mikhail Gavrilov
2026-09-04 16:43                                           ` sashiko-bot
2026-09-04 16:58                                         ` [RFC PATCH v6 0/2] the Topping M62's vendor controls, on the component framework Mikhail Gavrilov
2026-09-04 16:58                                           ` [RFC PATCH v6 1/2] HID: topping-m62: driver for the M62's vendor controls Mikhail Gavrilov
2026-09-04 16:58                                           ` [RFC PATCH v6 2/2] ALSA: usb-audio: bind the Topping " Mikhail Gavrilov
2026-09-04 17:16                                             ` sashiko-bot
2026-09-04 17:45                                               ` Mikhail Gavrilov

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=20260904113800.DC4281F00A3E@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=dmitry.torokhov@gmail.com \
    --cc=linux-input@vger.kernel.org \
    --cc=mikhail.v.gavrilov@gmail.com \
    --cc=sashiko-reviews@lists.linux.dev \
    /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.