From: Shih-Yuan Lee <fourdollars@debian.org>
To: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Cc: Mark Brown <broonie@kernel.org>,
linux-input@vger.kernel.org, linux-kernel@vger.kernel.org,
Shih-Yuan Lee <fourdollars@debian.org>
Subject: [PATCH v2 5/5] Input: applespi - fix use-after-free in applespi_remove()
Date: Mon, 20 Jul 2026 18:14:35 +0800 [thread overview]
Message-ID: <20260720101435.13612-6-fourdollars@debian.org> (raw)
In-Reply-To: <20260720101435.13612-1-fourdollars@debian.org>
applespi_remove() called applespi_drain_writes() to wait for in-flight
write transfers, then immediately called acpi_disable_gpe() and
acpi_remove_gpe_handler(). However it then called applespi_drain_reads()
*after* the GPE handler was removed, which races with any read SPI
completion callback that could still reference the applespi struct
already being torn down.
Moreover, the two drain helpers use separate wait paths that can miss
each other: a read completion arriving just after drain_writes() returns
but before drain_reads() is called will set read_active, and the
subsequent drain_reads() will then wait on a wait_queue that nobody will
ever wake because the GPE is already gone.
Fix by replacing the two separate drain calls with a single barrier
using the existing cancel_spi + wait_event_lock_irq mechanism:
- Set cancel_spi = true under the spinlock so that applespi_async()
immediately rejects new SPI submissions and wakes the wait queue
once all outstanding operations have drained.
- Wait for !applespi_async_outstanding() before proceeding with
teardown.
- Disable the GPE and remove its handler only after all in-flight SPI
transfers have completed, eliminating the use-after-free window.
Fixes: 0b7a8ac72fc1 ("Input: applespi - add driver for Apple SPI keyboard and touchpad")
Signed-off-by: Shih-Yuan Lee <fourdollars@debian.org>
---
drivers/input/keyboard/applespi.c | 13 ++++++++++---
1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/drivers/input/keyboard/applespi.c b/drivers/input/keyboard/applespi.c
index 95a8f790eaff..088337f060b2 100644
--- a/drivers/input/keyboard/applespi.c
+++ b/drivers/input/keyboard/applespi.c
@@ -1910,15 +1910,22 @@ static void applespi_drain_reads(struct applespi_data *applespi)
static void applespi_remove(struct spi_device *spi)
{
struct applespi_data *applespi = spi_get_drvdata(spi);
+ unsigned long flags;
- applespi_drain_writes(applespi);
+ /* Prevent any new SPI transfers and wait for outstanding ones */
+ spin_lock_irqsave(&applespi->cmd_msg_lock, flags);
+ applespi->cancel_spi = true;
+ wait_event_lock_irq_timeout(applespi->wait_queue,
+ !applespi_async_outstanding(applespi),
+ applespi->cmd_msg_lock,
+ msecs_to_jiffies(3000));
+ spin_unlock_irqrestore(&applespi->cmd_msg_lock, flags);
+ /* Disable GPE and remove handler */
acpi_disable_gpe(NULL, applespi->gpe);
acpi_remove_gpe_handler(NULL, applespi->gpe, applespi_notify);
device_wakeup_disable(&spi->dev);
- applespi_drain_reads(applespi);
-
debugfs_remove_recursive(applespi->debugfs_root);
}
--
2.39.5
next prev parent reply other threads:[~2026-07-20 10:14 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-20 10:14 [PATCH v2 0/5] Input: applespi - Fix probe timeout and use-after-free bugs Shih-Yuan Lee
2026-07-20 10:14 ` [PATCH v2 1/5] Input: applespi - use unified wait queue with timeouts for drain Shih-Yuan Lee
2026-07-20 10:25 ` sashiko-bot
2026-07-20 10:14 ` [PATCH v2 2/5] Input: applespi - track asynchronous SPI transfers in flight Shih-Yuan Lee
2026-07-20 10:31 ` sashiko-bot
2026-07-20 10:14 ` [PATCH v2 3/5] Input: applespi - register touchpad synchronously in probe Shih-Yuan Lee
2026-07-20 10:30 ` sashiko-bot
2026-07-20 10:14 ` [PATCH v2 4/5] Input: applespi - prefer asynchronous driver probing Shih-Yuan Lee
2026-07-20 10:32 ` sashiko-bot
2026-07-20 10:14 ` Shih-Yuan Lee [this message]
2026-07-20 10:30 ` [PATCH v2 5/5] Input: applespi - fix use-after-free in applespi_remove() sashiko-bot
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=20260720101435.13612-6-fourdollars@debian.org \
--to=fourdollars@debian.org \
--cc=broonie@kernel.org \
--cc=dmitry.torokhov@gmail.com \
--cc=linux-input@vger.kernel.org \
--cc=linux-kernel@vger.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.