rapidio: utilize new cdev_device_add helper function
authorLogan Gunthorpe <logang@deltatee.com>
Fri, 17 Mar 2017 18:48:20 +0000 (12:48 -0600)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 21 Mar 2017 05:44:33 +0000 (06:44 +0100)
This driver did not originally set kobj.parent so it likely had
potential a use after free bug which this patch fixes.

We convert from device_register to device_initialize/cdev_device_add.
While we are at it we use put_device instead of kfree (as recommended
by the device_initialize documentation). We also remove an unnecessary
extra get_device from the code.

Signed-off-by: Logan Gunthorpe <logang@deltatee.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/rapidio/devices/rio_mport_cdev.c

index 50b617af81bd5a2d034798bfa27f2cfa8da97bde..5beb0c361076ba5869a259c8006c52367e41f748 100644 (file)
@@ -2444,31 +2444,25 @@ static struct mport_dev *mport_cdev_add(struct rio_mport *mport)
        mutex_init(&md->buf_mutex);
        mutex_init(&md->file_mutex);
        INIT_LIST_HEAD(&md->file_list);
-       cdev_init(&md->cdev, &mport_fops);
-       md->cdev.owner = THIS_MODULE;
-       ret = cdev_add(&md->cdev, MKDEV(MAJOR(dev_number), mport->id), 1);
-       if (ret < 0) {
-               kfree(md);
-               rmcd_error("Unable to register a device, err=%d", ret);
-               return NULL;
-       }
 
-       md->dev.devt = md->cdev.dev;
+       device_initialize(&md->dev);
+       md->dev.devt = MKDEV(MAJOR(dev_number), mport->id);
        md->dev.class = dev_class;
        md->dev.parent = &mport->dev;
        md->dev.release = mport_device_release;
        dev_set_name(&md->dev, DEV_NAME "%d", mport->id);
        atomic_set(&md->active, 1);
 
-       ret = device_register(&md->dev);
+       cdev_init(&md->cdev, &mport_fops);
+       md->cdev.owner = THIS_MODULE;
+
+       ret = cdev_device_add(&md->cdev, &md->dev);
        if (ret) {
                rmcd_error("Failed to register mport %d (err=%d)",
                       mport->id, ret);
                goto err_cdev;
        }
 
-       get_device(&md->dev);
-
        INIT_LIST_HEAD(&md->doorbells);
        spin_lock_init(&md->db_lock);
        INIT_LIST_HEAD(&md->portwrites);
@@ -2513,8 +2507,7 @@ static struct mport_dev *mport_cdev_add(struct rio_mport *mport)
        return md;
 
 err_cdev:
-       cdev_del(&md->cdev);
-       kfree(md);
+       put_device(&md->dev);
        return NULL;
 }
 
@@ -2578,7 +2571,7 @@ static void mport_cdev_remove(struct mport_dev *md)
        atomic_set(&md->active, 0);
        mport_cdev_terminate_dma(md);
        rio_del_mport_pw_handler(md->mport, md, rio_mport_pw_handler);
-       cdev_del(&(md->cdev));
+       cdev_device_del(&md->cdev, &md->dev);
        mport_cdev_kill_fasync(md);
 
        flush_workqueue(dma_wq);
@@ -2603,7 +2596,6 @@ static void mport_cdev_remove(struct mport_dev *md)
 
        rio_release_inb_dbell(md->mport, 0, 0x0fff);
 
-       device_unregister(&md->dev);
        put_device(&md->dev);
 }