| From 9dbec61fa20e9201d030ba5117662203e7e7c137 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Mon, 28 Oct 2019 04:59:17 -0400 |
| Subject: zram: fix race between backing_dev_show and backing_dev_store |
| |
| [ Upstream commit f7daefe4231e57381d92c2e2ad905a899c28e402 ] |
| |
| 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> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| drivers/block/zram/zram_drv.c | 5 +++-- |
| 1 file changed, 3 insertions(+), 2 deletions(-) |
| |
| diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c |
| index 133178c9b2cf3..1b4e195c0d3c9 100644 |
| --- a/drivers/block/zram/zram_drv.c |
| +++ b/drivers/block/zram/zram_drv.c |
| @@ -291,13 +291,14 @@ static void reset_bdev(struct zram *zram) |
| static ssize_t backing_dev_show(struct device *dev, |
| struct device_attribute *attr, char *buf) |
| { |
| + struct file *file; |
| struct zram *zram = dev_to_zram(dev); |
| - struct file *file = zram->backing_dev; |
| char *p; |
| ssize_t ret; |
| |
| down_read(&zram->init_lock); |
| - if (!zram_wb_enabled(zram)) { |
| + file = zram->backing_dev; |
| + if (!file) { |
| memcpy(buf, "none\n", 5); |
| up_read(&zram->init_lock); |
| return 5; |
| -- |
| 2.20.1 |
| |