]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
xen/xenbus: reference count registered modules
authorPaul Durrant <pdurrant@amazon.com>
Mon, 2 Dec 2019 11:41:16 +0000 (11:41 +0000)
committerJuergen Gross <jgross@suse.com>
Wed, 4 Dec 2019 10:35:32 +0000 (11:35 +0100)
To prevent a PV driver module being removed whilst attached to its other
end, and hence xenbus calling into potentially invalid text, take a
reference on the module before calling the probe() method (dropping it if
unsuccessful) and drop the reference after returning from the remove()
method.

Suggested-by: Jan Beulich <jbeulich@suse.com>
Signed-off-by: Paul Durrant <pdurrant@amazon.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Juergen Gross <jgross@suse.com>
Signed-off-by: Juergen Gross <jgross@suse.com>
drivers/xen/xenbus/xenbus_probe.c

index 5b471889d7237c926682392b123db99e7ab6656f..c21be6e9d38a6c91ae75fb4e08a28588c1164df6 100644 (file)
@@ -232,9 +232,16 @@ int xenbus_dev_probe(struct device *_dev)
                return err;
        }
 
+       if (!try_module_get(drv->driver.owner)) {
+               dev_warn(&dev->dev, "failed to acquire module reference on '%s'\n",
+                        drv->driver.name);
+               err = -ESRCH;
+               goto fail;
+       }
+
        err = drv->probe(dev, id);
        if (err)
-               goto fail;
+               goto fail_put;
 
        err = watch_otherend(dev);
        if (err) {
@@ -244,6 +251,8 @@ int xenbus_dev_probe(struct device *_dev)
        }
 
        return 0;
+fail_put:
+       module_put(drv->driver.owner);
 fail:
        xenbus_dev_error(dev, err, "xenbus_dev_probe on %s", dev->nodename);
        xenbus_switch_state(dev, XenbusStateClosed);
@@ -263,6 +272,8 @@ int xenbus_dev_remove(struct device *_dev)
        if (drv->remove)
                drv->remove(dev);
 
+       module_put(drv->driver.owner);
+
        free_otherend_details(dev);
 
        xenbus_switch_state(dev, XenbusStateClosed);