| From 49da1fa16b88837067ca42176504c296de3769a2 Mon Sep 17 00:00:00 2001 |
| From: Chao Yu <yuchao0@huawei.com> |
| Date: Thu, 19 Mar 2020 19:58:00 +0800 |
| Subject: [PATCH] f2fs: fix NULL pointer dereference in f2fs_write_begin() |
| |
| commit 62f63eea291b50a5677ae7503ac128803174698a upstream. |
| |
| BUG: kernel NULL pointer dereference, address: 0000000000000000 |
| RIP: 0010:f2fs_write_begin+0x823/0xb90 [f2fs] |
| Call Trace: |
| f2fs_quota_write+0x139/0x1d0 [f2fs] |
| write_blk+0x36/0x80 [quota_tree] |
| get_free_dqblk+0x42/0xa0 [quota_tree] |
| do_insert_tree+0x235/0x4a0 [quota_tree] |
| do_insert_tree+0x26e/0x4a0 [quota_tree] |
| do_insert_tree+0x26e/0x4a0 [quota_tree] |
| do_insert_tree+0x26e/0x4a0 [quota_tree] |
| qtree_write_dquot+0x70/0x190 [quota_tree] |
| v2_write_dquot+0x43/0x90 [quota_v2] |
| dquot_acquire+0x77/0x100 |
| f2fs_dquot_acquire+0x2f/0x60 [f2fs] |
| dqget+0x310/0x450 |
| dquot_transfer+0x7e/0x120 |
| f2fs_setattr+0x11a/0x4a0 [f2fs] |
| notify_change+0x349/0x480 |
| chown_common+0x168/0x1c0 |
| do_fchownat+0xbc/0xf0 |
| __x64_sys_fchownat+0x20/0x30 |
| do_syscall_64+0x5f/0x220 |
| entry_SYSCALL_64_after_hwframe+0x44/0xa9 |
| |
| Passing fsdata parameter to .write_{begin,end} in f2fs_quota_write(), |
| so that if quota file is compressed one, we can avoid above NULL |
| pointer dereference when updating quota content. |
| |
| Signed-off-by: Chao Yu <yuchao0@huawei.com> |
| Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c |
| index d3c0e4ece4cf..4b4ac8535f74 100644 |
| --- a/fs/f2fs/super.c |
| +++ b/fs/f2fs/super.c |
| @@ -1797,6 +1797,7 @@ static ssize_t f2fs_quota_write(struct super_block *sb, int type, |
| int offset = off & (sb->s_blocksize - 1); |
| size_t towrite = len; |
| struct page *page; |
| + void *fsdata = NULL; |
| char *kaddr; |
| int err = 0; |
| int tocopy; |
| @@ -1806,7 +1807,7 @@ static ssize_t f2fs_quota_write(struct super_block *sb, int type, |
| towrite); |
| retry: |
| err = a_ops->write_begin(NULL, mapping, off, tocopy, 0, |
| - &page, NULL); |
| + &page, &fsdata); |
| if (unlikely(err)) { |
| if (err == -ENOMEM) { |
| congestion_wait(BLK_RW_ASYNC, HZ/50); |
| @@ -1822,7 +1823,7 @@ static ssize_t f2fs_quota_write(struct super_block *sb, int type, |
| flush_dcache_page(page); |
| |
| a_ops->write_end(NULL, mapping, off, tocopy, tocopy, |
| - page, NULL); |
| + page, fsdata); |
| offset = 0; |
| towrite -= tocopy; |
| off += tocopy; |
| -- |
| 2.7.4 |
| |