RE: [PATCH v3 1/2] Drivers: hv: vmbus: prevent duplicate dynamic IDs
From: Michael Kelley
Date: Tue Oct 27 2026 - 13:09:15 EST
From: Jiale Yao <yaojiale02@xxxxxxx> Sent: Monday, October 26, 2026 11:57 PM
>
> new_id_store() checks for an existing dynamic ID before calling
> vmbus_add_dynid(), but the check and insertion use separate critical
> sections. Two concurrent writers can therefore both observe that a GUID is
> absent and add duplicate entries. Removing the GUID once then leaves the
> duplicate active.
>
> Move the duplicate check into vmbus_add_dynid() so it is performed under
> the same lock as the list insertion.
>
> Fixes: fc76936d3ea5 ("vmbus: add support for dynamic device id's")
> Cc: stable@xxxxxxxxxxxxxxx
> Tested-by: Kameron Carr <kameroncarr@xxxxxxxxxxxxxxxxxxx>
> Reviewed-by: Kameron Carr <kameroncarr@xxxxxxxxxxxxxxxxxxx>
> Signed-off-by: Jiale Yao <yaojiale02@xxxxxxx>
Reviewed-by: Michael Kelley <mhklinux@xxxxxxxxxxx>
> ---
> drivers/hv/vmbus_drv.c | 18 +++++++++++-------
> 1 file changed, 11 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
> index 4692687cdbf3..1037117e2d81 100644
> --- a/drivers/hv/vmbus_drv.c
> +++ b/drivers/hv/vmbus_drv.c
> @@ -737,7 +737,7 @@ static const struct hv_vmbus_device_id *hv_vmbus_get_id(const struct hv_driver *
> */
> static int vmbus_add_dynid(struct hv_driver *drv, guid_t *guid)
> {
> - struct vmbus_dynid *dynid;
> + struct vmbus_dynid *dynid, *existing;
>
> dynid = kzalloc_obj(*dynid);
> if (!dynid)
> @@ -745,9 +745,16 @@ static int vmbus_add_dynid(struct hv_driver *drv, guid_t *guid)
>
> dynid->id.guid = *guid;
>
> - spin_lock(&drv->dynids.lock);
> - list_add_tail(&dynid->node, &drv->dynids.list);
> - spin_unlock(&drv->dynids.lock);
> + scoped_guard(spinlock, &drv->dynids.lock) {
> + list_for_each_entry(existing, &drv->dynids.list, node) {
> + if (guid_equal(&existing->id.guid, guid)) {
> + kfree(dynid);
> + return -EEXIST;
> + }
> + }
> +
> + list_add_tail(&dynid->node, &drv->dynids.list);
> + }
>
> return driver_attach(&drv->driver);
> }
> @@ -780,9 +787,6 @@ static ssize_t new_id_store(struct device_driver *driver, const char *buf,
> if (retval)
> return retval;
>
> - if (hv_vmbus_dynid_match(drv, &guid))
> - return -EEXIST;
> -
> retval = vmbus_add_dynid(drv, &guid);
> if (retval)
> return retval;
> --
> 2.34.1
>