summaryrefslogtreecommitdiffstats
path: root/drivers/block/zram
diff options
context:
space:
mode:
authorChenwandun <chenwandun@huawei.com>2019-10-18 23:20:14 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2019-10-19 06:32:32 -0400
commitf7daefe4231e57381d92c2e2ad905a899c28e402 (patch)
tree067767d5a6b2b6cd00064326605c423ad7edcb54 /drivers/block/zram
parentae8af4388db002bbd1df78ecee7ca31cee78e964 (diff)
zram: fix race between backing_dev_show and backing_dev_store
CPU0: CPU1: backing_dev_show backing_dev_store ...... ...... file = zram->backing_dev; down_read(&zram->init_lock); down_read(&zram->init_init_lock) file_path(file, ...); zram->backing_dev = backing_dev; up_read(&zram->init_lock); up_read(&zram->init_lock); gets the value of zram->backing_dev too early in backing_dev_show, which resultin the value being NULL at the beginning, and not NULL later. backtrace: d_path+0xcc/0x174 file_path+0x10/0x18 backing_dev_show+0x40/0xb4 dev_attr_show+0x20/0x54 sysfs_kf_seq_show+0x9c/0x10c kernfs_seq_show+0x28/0x30 seq_read+0x184/0x488 kernfs_fop_read+0x5c/0x1a4 __vfs_read+0x44/0x128 vfs_read+0xa0/0x138 SyS_read+0x54/0xb4 Link: http://lkml.kernel.org/r/1571046839-16814-1-git-send-email-chenwandun@huawei.com Signed-off-by: Chenwandun <chenwandun@huawei.com> Acked-by: Minchan Kim <minchan@kernel.org> Cc: Sergey Senozhatsky <sergey.senozhatsky.work@gmail.com> Cc: Jens Axboe <axboe@kernel.dk> Cc: <stable@vger.kernel.org> [4.14+] Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/block/zram')
-rw-r--r--drivers/block/zram/zram_drv.c5
1 files changed, 3 insertions, 2 deletions
diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c
index d58a359a6622..4285e75e52c3 100644
--- a/drivers/block/zram/zram_drv.c
+++ b/drivers/block/zram/zram_drv.c
@@ -413,13 +413,14 @@ static void reset_bdev(struct zram *zram)
413static ssize_t backing_dev_show(struct device *dev, 413static ssize_t backing_dev_show(struct device *dev,
414 struct device_attribute *attr, char *buf) 414 struct device_attribute *attr, char *buf)
415{ 415{
416 struct file *file;
416 struct zram *zram = dev_to_zram(dev); 417 struct zram *zram = dev_to_zram(dev);
417 struct file *file = zram->backing_dev;
418 char *p; 418 char *p;
419 ssize_t ret; 419 ssize_t ret;
420 420
421 down_read(&zram->init_lock); 421 down_read(&zram->init_lock);
422 if (!zram->backing_dev) { 422 file = zram->backing_dev;
423 if (!file) {
423 memcpy(buf, "none\n", 5); 424 memcpy(buf, "none\n", 5);
424 up_read(&zram->init_lock); 425 up_read(&zram->init_lock);
425 return 5; 426 return 5;