From: Jakub Kicinski <kuba@kernel.org>
To: poros@redhat.com
Cc: Jakub Kicinski <kuba@kernel.org>,
netdev@vger.kernel.org, ivecera@redhat.com,
vadim.fedorenko@linux.dev, arkadiusz.kubalewski@intel.com,
jiri@resnulli.us, milena.olech@intel.com, davem@davemloft.net,
michal.michalik@intel.com, linux-kernel@vger.kernel.org
Subject: Re: [PATCH net 1/2] dpll: fix NULL deref in dpll_device_ops() during teardown race
Date: Wed, 20 May 2026 19:19:30 -0700 [thread overview]
Message-ID: <20260521021930.687910-1-kuba@kernel.org> (raw)
In-Reply-To: <20260516191317.1005612-2-poros@redhat.com>
This is an AI-generated review of your patch. The human sending this
email has considered the AI review valid, or at least plausible.
---
dpll: fix NULL deref in dpll_device_ops() during teardown race
This commit modifies dpll_device_ops() and dpll_priv() to return NULL during
a teardown race when the registration list is empty. It also adds a check in
dpll_cmd_pin_get_one() to drop the notification if the first referenced dpll
is unregistered.
> In-tree doit/dumpit callers of dpll_priv() / dpll_device_ops() obtain
> their dpll via dpll_pre_doit() -> dpll_device_get_by_id(), which only
> returns DPLL_REGISTERED devices; dpll_device_unregister() clears that
> mark only after observing list_empty(&dpll->registration_list), so
> those callers cannot see the new NULL return. The only path that can
> is dpll_cmd_pin_get_one() reached from dpll_pin_event_send(), gated
> here.
Is this description accurate for pin operations?
Looking at doit and dumpit paths for pins, they appear to use
dpll_pin_pre_doit() which relies on dpll_pin_available(). That function
allows the operation if at least one dpll referencing the pin is registered.
If a pin references multiple dpll devices, and one is registered while
another is half-dead (being unregistered), couldn't a user trigger a panic by
executing a pin dump or configuration command during a driver unload?
> diff --git a/drivers/dpll/dpll_netlink.c b/drivers/dpll/dpll_netlink.c
> index ea63602637866..b73d718e8a56d 100644
> --- a/drivers/dpll/dpll_netlink.c
> +++ b/drivers/dpll/dpll_netlink.c
> @@ -709,6 +709,12 @@ dpll_cmd_pin_get_one(struct sk_buff *msg, struct dpll_pin *pin,
> ref = dpll_xa_ref_dpll_first(&pin->dpll_refs);
> ASSERT_NOT_NULL(ref);
>
> + /* The first dpll the pin references may be torn down while still
> + * pinned by foreign-driver refs; drop the notification cleanly.
> + */
> + if (!dpll_device_ops(ref->dpll))
> + return -ENODEV;
> +
Will returning -ENODEV here break the netlink pin dump globally?
Since dpll_cmd_pin_get_one() is called inside the dumpit loop of
dpll_nl_pin_get_dumpit(), returning an error aborts the entire dump process.
A single pin in this transient state seems to break the pin dump operation
for all pins.
Also, for notifications sent via dpll_pin_event_send(), this return value
silently cancels and frees the netlink message. If the pin is shared with
other active dplls (which might be later in the xarray), won't their valid
state change notifications be permanently lost? Should the code skip
unregistered dplls instead of unconditionally aborting the operation?
Furthermore, does this check fully prevent the NULL pointer dereference?
This only validates the first dpll reference returned by
dpll_xa_ref_dpll_first(). If the first dpll is registered but a subsequent
dpll is half-dead (its registration list is empty), this check passes.
Execution would then proceed to functions like dpll_msg_add_pin_dplls() or
netlink set operations like dpll_pin_phase_adj_set() which iterate over
all dpll references in pin->dpll_refs. For the half-dead dpll, dpll_priv(dpll)
now evaluates to NULL, which is passed to driver callbacks
like ops->state_on_dpll_get that might unconditionally dereference it
(for example, ice_dpll_pin_state_get() uses struct ice_pf *pf = d->pf),
causing a kernel panic.
--
pw-bot: cr
next prev parent reply other threads:[~2026-05-21 2:19 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-16 19:13 [PATCH net 0/2] dpll: fix two teardown races on E825-C Petr Oros
2026-05-16 19:13 ` [PATCH net 1/2] dpll: fix NULL deref in dpll_device_ops() during teardown race Petr Oros
2026-05-21 2:19 ` Jakub Kicinski [this message]
2026-05-21 2:19 ` Jakub Kicinski
2026-05-16 19:13 ` [PATCH net 2/2] dpll: filter pin->dpll_refs by cookie in dpll_pin_on_pin_unregister Petr Oros
2026-05-21 2:19 ` Jakub Kicinski
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=20260521021930.687910-1-kuba@kernel.org \
--to=kuba@kernel.org \
--cc=arkadiusz.kubalewski@intel.com \
--cc=davem@davemloft.net \
--cc=ivecera@redhat.com \
--cc=jiri@resnulli.us \
--cc=linux-kernel@vger.kernel.org \
--cc=michal.michalik@intel.com \
--cc=milena.olech@intel.com \
--cc=netdev@vger.kernel.org \
--cc=poros@redhat.com \
--cc=vadim.fedorenko@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox