lkml.org 
[lkml]   [2017]   [May]   [18]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.10 74/93] device-dax: fix cdev leak
    Date
    4.10-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Dan Williams <dan.j.williams@intel.com>

    commit ed01e50acdd3e4a640cf9ebd28a7e810c3ceca97 upstream.

    If device_add() fails, cleanup the cdev. Otherwise, we leak a kobj_map()
    with a stale device number.

    As Jason points out, there is a small possibility that userspace has
    opened and mapped the device in the time between cdev_add() and the
    device_add() failure. We need a new kill_dax_dev() helper to invalidate
    any established mappings.

    Fixes: ba09c01d2fa8 ("dax: convert to the cdev api")
    Reported-by: Jason Gunthorpe <jgunthorpe@obsidianresearch.com>
    Signed-off-by: Dan Williams <dan.j.williams@intel.com>
    Signed-off-by: Logan Gunthorpe <logang@deltatee.com>
    Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    drivers/dax/dax.c | 15 +++++++++++----
    1 file changed, 11 insertions(+), 4 deletions(-)

    --- a/drivers/dax/dax.c
    +++ b/drivers/dax/dax.c
    @@ -646,13 +646,10 @@ static void dax_dev_release(struct devic
    kfree(dax_dev);
    }

    -static void unregister_dax_dev(void *dev)
    +static void kill_dax_dev(struct dax_dev *dax_dev)
    {
    - struct dax_dev *dax_dev = to_dax_dev(dev);
    struct cdev *cdev = &dax_dev->cdev;

    - dev_dbg(dev, "%s\n", __func__);
    -
    /*
    * Note, rcu is not protecting the liveness of dax_dev, rcu is
    * ensuring that any fault handlers that might have seen
    @@ -664,6 +661,15 @@ static void unregister_dax_dev(void *dev
    synchronize_srcu(&dax_srcu);
    unmap_mapping_range(dax_dev->inode->i_mapping, 0, 0, 1);
    cdev_del(cdev);
    +}
    +
    +static void unregister_dax_dev(void *dev)
    +{
    + struct dax_dev *dax_dev = to_dax_dev(dev);
    +
    + dev_dbg(dev, "%s\n", __func__);
    +
    + kill_dax_dev(dax_dev);
    device_unregister(dev);
    }

    @@ -740,6 +746,7 @@ struct dax_dev *devm_create_dax_dev(stru
    dev_set_name(dev, "dax%d.%d", dax_region->id, dax_dev->id);
    rc = device_add(dev);
    if (rc) {
    + kill_dax_dev(dax_dev);
    put_device(dev);
    return ERR_PTR(rc);
    }

    \
     
     \ /
      Last update: 2017-05-18 12:58    [W:4.076 / U:0.024 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site