* [PATCH] phy: apple: atc: Fix typec switch/mux leak and UAF on unbind
@ 2026-04-20 23:10 David Carlier
0 siblings, 0 replies; only message in thread
From: David Carlier @ 2026-04-20 23:10 UTC (permalink / raw)
To: Sven Peter, Janne Grunau, Neal Gompa, Vinod Koul, Neil Armstrong,
Hector Martin, Philipp Zabel
Cc: David Carlier, asahi, linux-arm-kernel, linux-phy, linux-kernel
atcphy_probe_switch() and atcphy_probe_mux() discard the pointers
returned by typec_switch_register() and typec_mux_register(). The
platform driver has no .remove callback, so the registered switch
and mux devices outlive the apple_atcphy struct, which is released
by devm cleanup on driver unbind.
A subsequent typec event (cable orientation change, alt-mode
transition) then invokes the registered atcphy_sw_set() or
atcphy_mux_set() callback, which retrieves the freed apple_atcphy
and dereferences it. Unbind followed by a cable replug or alt-mode
change is enough to trigger the use-after-free.
Save the registered switch and mux and unregister them through
devm_add_action_or_reset() so the framework references disappear in
step with the driver's devm-allocated state. Drop the unused struct
apple_atcphy::sw and ::mux fields, which were declared with the
wrong consumer-side types and never assigned.
Fixes: 8e98ca1e74db ("phy: apple: Add Apple Type-C PHY")
Signed-off-by: David Carlier <devnexen@gmail.com>
---
drivers/phy/apple/atc.c | 27 ++++++++++++++++++++++-----
1 file changed, 22 insertions(+), 5 deletions(-)
diff --git a/drivers/phy/apple/atc.c b/drivers/phy/apple/atc.c
index e9d106f135c5..4156fabad742 100644
--- a/drivers/phy/apple/atc.c
+++ b/drivers/phy/apple/atc.c
@@ -628,9 +628,6 @@ struct apple_atcphy {
struct reset_controller_dev rcdev;
- struct typec_switch *sw;
- struct typec_mux *mux;
-
struct mutex lock;
};
@@ -2066,15 +2063,25 @@ static int atcphy_sw_set(struct typec_switch_dev *sw, enum typec_orientation ori
return 0;
}
+static void atcphy_typec_switch_unregister(void *data)
+{
+ typec_switch_unregister(data);
+}
+
static int atcphy_probe_switch(struct apple_atcphy *atcphy)
{
+ struct typec_switch_dev *sw;
struct typec_switch_desc sw_desc = {
.drvdata = atcphy,
.fwnode = atcphy->dev->fwnode,
.set = atcphy_sw_set,
};
- return PTR_ERR_OR_ZERO(typec_switch_register(atcphy->dev, &sw_desc));
+ sw = typec_switch_register(atcphy->dev, &sw_desc);
+ if (IS_ERR(sw))
+ return PTR_ERR(sw);
+
+ return devm_add_action_or_reset(atcphy->dev, atcphy_typec_switch_unregister, sw);
}
static int atcphy_mux_set(struct typec_mux_dev *mux, struct typec_mux_state *state)
@@ -2146,15 +2153,25 @@ static int atcphy_mux_set(struct typec_mux_dev *mux, struct typec_mux_state *sta
return atcphy_configure(atcphy, target_mode);
}
+static void atcphy_typec_mux_unregister(void *data)
+{
+ typec_mux_unregister(data);
+}
+
static int atcphy_probe_mux(struct apple_atcphy *atcphy)
{
+ struct typec_mux_dev *mux;
struct typec_mux_desc mux_desc = {
.drvdata = atcphy,
.fwnode = atcphy->dev->fwnode,
.set = atcphy_mux_set,
};
- return PTR_ERR_OR_ZERO(typec_mux_register(atcphy->dev, &mux_desc));
+ mux = typec_mux_register(atcphy->dev, &mux_desc);
+ if (IS_ERR(mux))
+ return PTR_ERR(mux);
+
+ return devm_add_action_or_reset(atcphy->dev, atcphy_typec_mux_unregister, mux);
}
static int atcphy_load_tunables(struct apple_atcphy *atcphy)
--
2.53.0
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2026-04-20 23:10 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-20 23:10 [PATCH] phy: apple: atc: Fix typec switch/mux leak and UAF on unbind David Carlier
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox