From: Yibo Tan <lhfff@tju.edu.cn>
To: Richard Cochran <richardcochran@gmail.com>
Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [PATCH v1] ptp: idt82p33: Stop PTP work producers before teardown
Date: Tue, 22 Sep 2026 19:36:01 +0800 [thread overview]
Message-ID: <20260922113601.855416-1-lhfff@tju.edu.cn> (raw)
idt82p33_ptp_clock_unregister_all() cancels each channel's adjtime work
before unregistering its PTP clock. An adjustment callback already in
progress can schedule that work after cancellation returns. Device
removal then frees the channel while its delayed work remains queued,
causing a use-after-free.
Mark the device as stopping under its lock before draining work. Reject
new adjustment and EXTS requests, clear the EXTS polling mask, and
synchronously drain the EXTS and channel adjustment work before the
device storage is released.
With an i2c-stub device and kprobe-controlled callback timing, three
runs of the unmodified driver reported KASAN use-after-free after
unbind. Three runs with this change completed without a kernel
diagnostic. No physical IDT82P33 device was tested.
Signed-off-by: Yibo Tan <lhfff@tju.edu.cn>
---
drivers/ptp/ptp_idt82p33.c | 25 +++++++++++++++++++++----
drivers/ptp/ptp_idt82p33.h | 1 +
2 files changed, 22 insertions(+), 4 deletions(-)
diff --git a/drivers/ptp/ptp_idt82p33.c b/drivers/ptp/ptp_idt82p33.c
index f01c50dfa44e8..ffc2ec1fc4bed 100644
--- a/drivers/ptp/ptp_idt82p33.c
+++ b/drivers/ptp/ptp_idt82p33.c
@@ -918,6 +918,13 @@ static void idt82p33_ptp_clock_unregister_all(struct idt82p33 *idt82p33)
struct idt82p33_channel *channel;
u8 i;
+ mutex_lock(idt82p33->lock);
+ idt82p33->stopping = true;
+ idt82p33->extts_mask = 0;
+ mutex_unlock(idt82p33->lock);
+
+ cancel_delayed_work_sync(&idt82p33->extts_work);
+
for (i = 0; i < MAX_PHC_PLL; i++) {
channel = &idt82p33->channel[i];
cancel_delayed_work_sync(&channel->adjtime_work);
@@ -937,6 +944,10 @@ static int idt82p33_enable(struct ptp_clock_info *ptp,
int err = -EOPNOTSUPP;
mutex_lock(idt82p33->lock);
+ if (idt82p33->stopping) {
+ err = -ENODEV;
+ goto out;
+ }
switch (rq->type) {
case PTP_CLK_REQ_PEROUT:
@@ -958,6 +969,7 @@ static int idt82p33_enable(struct ptp_clock_info *ptp,
break;
}
+out:
mutex_unlock(idt82p33->lock);
if (err)
@@ -1044,11 +1056,14 @@ static int idt82p33_adjtime(struct ptp_clock_info *ptp, s64 delta_ns)
return -EBUSY;
mutex_lock(idt82p33->lock);
+ if (idt82p33->stopping) {
+ err = -ENODEV;
+ goto out;
+ }
if (abs(delta_ns) < phase_snap_threshold) {
err = idt82p33_start_ddco(channel, delta_ns);
- mutex_unlock(idt82p33->lock);
- return err;
+ goto out;
}
/* Use more accurate internal 1pps triggered write first */
@@ -1056,6 +1071,7 @@ static int idt82p33_adjtime(struct ptp_clock_info *ptp, s64 delta_ns)
if (err && delta_ns > IMMEDIATE_SNAP_THRESHOLD_NS)
err = _idt82p33_adjtime_immediate(channel, delta_ns);
+out:
mutex_unlock(idt82p33->lock);
if (err)
@@ -1342,6 +1358,8 @@ static void idt82p33_extts_check(struct work_struct *work)
return;
mutex_lock(idt82p33->lock);
+ if (idt82p33->stopping)
+ goto out;
for (i = 0; i < MAX_PHC_PLL; i++) {
mask = 1 << i;
@@ -1367,6 +1385,7 @@ static void idt82p33_extts_check(struct work_struct *work)
schedule_delayed_work(&idt82p33->extts_work,
msecs_to_jiffies(EXTTS_PERIOD_MS));
+out:
mutex_unlock(idt82p33->lock);
}
@@ -1442,8 +1461,6 @@ static void idt82p33_remove(struct platform_device *pdev)
{
struct idt82p33 *idt82p33 = platform_get_drvdata(pdev);
- cancel_delayed_work_sync(&idt82p33->extts_work);
-
idt82p33_ptp_clock_unregister_all(idt82p33);
}
diff --git a/drivers/ptp/ptp_idt82p33.h b/drivers/ptp/ptp_idt82p33.h
index 6a63c14b6966b..b88c921adaa91 100644
--- a/drivers/ptp/ptp_idt82p33.h
+++ b/drivers/ptp/ptp_idt82p33.h
@@ -91,6 +91,7 @@ struct idt82p33 {
u8 extts_mask;
bool extts_single_shot;
struct delayed_work extts_work;
+ bool stopping;
/* Remember the ptp channel to report extts */
struct idt82p33_channel *event_channel[MAX_PHC_PLL];
/* Mutex to protect operations from being interrupted */
--
2.39.5
next reply other threads:[~2026-09-22 11:36 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-22 11:36 Yibo Tan [this message]
2026-09-25 5:37 ` [PATCH v1] ptp: idt82p33: Stop PTP work producers before teardown netdev-bot+sashiko
2026-09-26 0:00 ` patchwork-bot+netdevbpf
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=20260922113601.855416-1-lhfff@tju.edu.cn \
--to=lhfff@tju.edu.cn \
--cc=linux-kernel@vger.kernel.org \
--cc=netdev@vger.kernel.org \
--cc=richardcochran@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox