lkml.org 
[lkml]   [2015]   [Oct]   [19]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 3.4 02/65] mtd: fix: avoid race condition when accessing mtd->usecount
    Date
    From: Brian Norris <computersforpeace@gmail.com>

    3.4.110-rc1 review patch. If anyone has any objections, please let me know.

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


    commit 073db4a51ee43ccb827f54a4261c0583b028d5ab upstream.

    On A MIPS 32-cores machine a BUG_ON was triggered because some acesses to
    mtd->usecount were done without taking mtd_table_mutex.
    kernel: Call Trace:
    kernel: [<ffffffff80401818>] __put_mtd_device+0x20/0x50
    kernel: [<ffffffff804086f4>] blktrans_release+0x8c/0xd8
    kernel: [<ffffffff802577e0>] __blkdev_put+0x1a8/0x200
    kernel: [<ffffffff802579a4>] blkdev_close+0x1c/0x30
    kernel: [<ffffffff8022006c>] __fput+0xac/0x250
    kernel: [<ffffffff80171208>] task_work_run+0xd8/0x120
    kernel: [<ffffffff8012c23c>] work_notifysig+0x10/0x18
    kernel:
    kernel:
    Code: 2442ffff ac8202d8 000217fe <00020336> dc820128 10400003
    00000000 0040f809 00000000
    kernel: ---[ end trace 080fbb4579b47a73 ]---

    Fixed by taking the mutex in blktrans_open and blktrans_release.

    Note that this locking is already suggested in
    include/linux/mtd/blktrans.h:

    struct mtd_blktrans_ops {
    ...
    /* Called with mtd_table_mutex held; no race with add/remove */
    int (*open)(struct mtd_blktrans_dev *dev);
    void (*release)(struct mtd_blktrans_dev *dev);
    ...
    };

    But we weren't following it.

    Originally reported by (and patched by) Zhang and Giuseppe,
    independently. Improved and rewritten.

    Reported-by: Zhang Xingcai <zhangxingcai@huawei.com>
    Reported-by: Giuseppe Cantavenera <giuseppe.cantavenera.ext@nokia.com>
    Tested-by: Giuseppe Cantavenera <giuseppe.cantavenera.ext@nokia.com>
    Acked-by: Alexander Sverdlin <alexander.sverdlin@nokia.com>
    Signed-off-by: Brian Norris <computersforpeace@gmail.com>
    Signed-off-by: Zefan Li <lizefan@huawei.com>
    ---
    drivers/mtd/mtd_blkdevs.c | 5 +++++
    1 file changed, 5 insertions(+)

    diff --git a/drivers/mtd/mtd_blkdevs.c b/drivers/mtd/mtd_blkdevs.c
    index f1f0671..1917f7d 100644
    --- a/drivers/mtd/mtd_blkdevs.c
    +++ b/drivers/mtd/mtd_blkdevs.c
    @@ -214,6 +214,7 @@ static int blktrans_open(struct block_device *bdev, fmode_t mode)
    return -ERESTARTSYS; /* FIXME: busy loop! -arnd*/

    mutex_lock(&dev->lock);
    + mutex_lock(&mtd_table_mutex);

    if (dev->open)
    goto unlock;
    @@ -237,6 +238,7 @@ static int blktrans_open(struct block_device *bdev, fmode_t mode)

    unlock:
    dev->open++;
    + mutex_unlock(&mtd_table_mutex);
    mutex_unlock(&dev->lock);
    blktrans_dev_put(dev);
    return ret;
    @@ -247,6 +249,7 @@ error_release:
    error_put:
    module_put(dev->tr->owner);
    kref_put(&dev->ref, blktrans_dev_release);
    + mutex_unlock(&mtd_table_mutex);
    mutex_unlock(&dev->lock);
    blktrans_dev_put(dev);
    return ret;
    @@ -261,6 +264,7 @@ static int blktrans_release(struct gendisk *disk, fmode_t mode)
    return ret;

    mutex_lock(&dev->lock);
    + mutex_lock(&mtd_table_mutex);

    if (--dev->open)
    goto unlock;
    @@ -273,6 +277,7 @@ static int blktrans_release(struct gendisk *disk, fmode_t mode)
    __put_mtd_device(dev->mtd);
    }
    unlock:
    + mutex_unlock(&mtd_table_mutex);
    mutex_unlock(&dev->lock);
    blktrans_dev_put(dev);
    return ret;
    --
    1.9.1


    \
     
     \ /
      Last update: 2015-10-20 03:21    [W:7.717 / U:0.192 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site