lkml.org 
[lkml]   [2008]   [Apr]   [20]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 07/36] UIO: hold a reference to the device's owner while the device is open
    Date
    From: Uwe Kleine-König <Uwe.Kleine-Koenig@digi.com>

    Otherwise the device might just disappear while /dev/uioX is being used
    which results in an Oops.

    Signed-off-by: Uwe Kleine-König <Uwe.Kleine-Koenig@digi.com>
    Signed-off-by: Hans J Koch <hjk@linutronix.de>
    Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
    ---
    drivers/uio/uio.c | 36 +++++++++++++++++++++---------------
    1 files changed, 21 insertions(+), 15 deletions(-)

    diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c
    index 1175908..55cc7b8 100644
    --- a/drivers/uio/uio.c
    +++ b/drivers/uio/uio.c
    @@ -301,23 +301,33 @@ static int uio_open(struct inode *inode, struct file *filep)
    if (!idev)
    return -ENODEV;

    + if (!try_module_get(idev->owner))
    + return -ENODEV;
    +
    listener = kmalloc(sizeof(*listener), GFP_KERNEL);
    - if (!listener)
    - return -ENOMEM;
    + if (!listener) {
    + ret = -ENOMEM;
    + goto err_alloc_listener;
    + }

    listener->dev = idev;
    listener->event_count = atomic_read(&idev->event);
    filep->private_data = listener;

    if (idev->info->open) {
    - if (!try_module_get(idev->owner))
    - return -ENODEV;
    ret = idev->info->open(idev->info, inode);
    - module_put(idev->owner);
    + if (ret)
    + goto err_infoopen;
    }

    - if (ret)
    - kfree(listener);
    + return 0;
    +
    +err_infoopen:
    +
    + kfree(listener);
    +err_alloc_listener:
    +
    + module_put(idev->owner);

    return ret;
    }
    @@ -336,12 +346,11 @@ static int uio_release(struct inode *inode, struct file *filep)
    struct uio_listener *listener = filep->private_data;
    struct uio_device *idev = listener->dev;

    - if (idev->info->release) {
    - if (!try_module_get(idev->owner))
    - return -ENODEV;
    + if (idev->info->release)
    ret = idev->info->release(idev->info, inode);
    - module_put(idev->owner);
    - }
    +
    + module_put(idev->owner);
    +
    if (filep->f_flags & FASYNC)
    ret = uio_fasync(-1, filep, 0);
    kfree(listener);
    @@ -510,10 +519,7 @@ static int uio_mmap(struct file *filep, struct vm_area_struct *vma)
    return -EINVAL;

    if (idev->info->mmap) {
    - if (!try_module_get(idev->owner))
    - return -ENODEV;
    ret = idev->info->mmap(idev->info, vma);
    - module_put(idev->owner);
    return ret;
    }

    --
    1.5.4.5
    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

    \
     
     \ /
      Last update: 2008-04-20 12:45    [W:0.024 / U:1.300 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site