From: hyunjungg <hj351016@gmail.com>
To: Srinivas Kandagatla <srini@kernel.org>
Cc: Mark Brown <broonie@kernel.org>,
Liam Girdwood <lgirdwood@gmail.com>,
linux-sound@vger.kernel.org, linux-kernel@vger.kernel.org,
Hyunjung Ko <hj351016@gmail.com>
Subject: [PATCH] ASoC: codecs: wcd-mbhc-v2: cancel button long-press work on deinit
Date: Fri, 6 Nov 2026 14:22:42 +0900 [thread overview]
Message-ID: <20261106052242.2000264-1-hj351016@gmail.com> (raw)
From: Hyunjung Ko <hj351016@gmail.com>
wcd_mbhc_deinit() drains two of the three works embedded in struct
wcd_mbhc before freeing it - correct_plug_swch (via
wcd_cancel_hs_detect_plug()) and mbhc_plug_detect_work - but not the
button long-press delayed work mbhc_btn_dwork:
mutex_lock(&mbhc->lock);
wcd_cancel_hs_detect_plug(mbhc, &mbhc->correct_plug_swch);
cancel_work_sync(&mbhc->mbhc_plug_detect_work);
mutex_unlock(&mbhc->lock);
kfree(mbhc);
mbhc_btn_dwork is armed from the button-press interrupt handler
wcd_mbhc_btn_press_handler() with a 400 ms delay:
schedule_delayed_work(&mbhc->mbhc_btn_dwork, msecs_to_jiffies(400));
and its handler wcd_btn_long_press_fn() dereferences @mbhc
(container_of(), mbhc->current_plug, mbhc->jack).
wcd_mbhc_deinit() frees the MBHC interrupts first, which stops new work
from being queued, but free_irq() does not cancel a delayed work that was
already scheduled. If a button was pressed within ~400 ms of component
removal, mbhc_btn_dwork is still pending when kfree(mbhc) runs, so
wcd_btn_long_press_fn() later executes against freed memory
(use-after-free).
The asymmetry dates from the teardown rework in commit (CVE-2023-53842),
which added the correct_plug_swch/mbhc_plug_detect_work cancellation but
left mbhc_btn_dwork undrained.
Cancel mbhc_btn_dwork alongside the other works. Its handler does not take
mbhc->lock, so cancel_delayed_work_sync() is safe to call under the lock.
Found by code review; not runtime-reproduced (requires WCD codec hardware
and a button-press event racing component removal).
Signed-off-by: Hyunjung Ko <hj351016@gmail.com>
---
sound/soc/codecs/wcd-mbhc-v2.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/sound/soc/codecs/wcd-mbhc-v2.c b/sound/soc/codecs/wcd-mbhc-v2.c
index 0000000..1111111 100644
--- a/sound/soc/codecs/wcd-mbhc-v2.c
+++ b/sound/soc/codecs/wcd-mbhc-v2.c
@@ -1624,6 +1624,7 @@ void wcd_mbhc_deinit(struct wcd_mbhc *mbhc)
mutex_lock(&mbhc->lock);
wcd_cancel_hs_detect_plug(mbhc, &mbhc->correct_plug_swch);
cancel_work_sync(&mbhc->mbhc_plug_detect_work);
+ cancel_delayed_work_sync(&mbhc->mbhc_btn_dwork);
mutex_unlock(&mbhc->lock);
kfree(mbhc);
next reply other threads:[~2026-11-06 5:23 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-06 5:22 hyunjungg [this message]
2026-11-06 5:38 ` [PATCH] ASoC: codecs: wcd-mbhc-v2: cancel button long-press work on deinit sashiko-bot
2026-11-06 5:44 ` [PATCH v2] " hyunjungg
2026-11-06 11:35 ` Mark Brown
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=20261106052242.2000264-1-hj351016@gmail.com \
--to=hj351016@gmail.com \
--cc=broonie@kernel.org \
--cc=lgirdwood@gmail.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-sound@vger.kernel.org \
--cc=srini@kernel.org \
/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.