[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <20241209085410.601489-1-chenxiaosong@chenxiaosong.com>
Date: Mon, 9 Dec 2024 08:54:10 +0000
From: chenxiaosong@...nxiaosong.com
To: gregkh@...uxfoundation.org,
trondmy@...nel.org,
anna@...nel.org
Cc: linux-nfs@...r.kernel.org,
linux-kernel@...r.kernel.org,
huhai@...inos.cn,
chenxiaosong@...inos.cn
Subject: [PATCH 4.19] NFS: fix null-ptr-deref in nfs_inode_add_request()
From: ChenXiaoSong <chenxiaosong@...inos.cn>
There is panic as follows:
BUG: unable to handle kernel NULL pointer dereference at 0000000000000080
Call Trace:
nfs_inode_add_request+0x1cc/0x5b8
nfs_setup_write_request+0x1fa/0x1fc
nfs_writepage_setup+0x2d/0x7d
nfs_updatepage+0x8b8/0x936
nfs_write_end+0x61d/0xd45
generic_perform_write+0x19a/0x3f0
nfs_file_write+0x2cc/0x6e5
new_sync_write+0x442/0x560
__vfs_write+0xda/0xef
vfs_write+0x176/0x48b
ksys_write+0x10a/0x1e9
__se_sys_write+0x24/0x29
__x64_sys_write+0x79/0x93
do_syscall_64+0x16d/0x4bb
entry_SYSCALL_64_after_hwframe+0x5c/0xc1
The above panic may happen as follows:
nfs_updatepage
nfs_writepage_setup
nfs_setup_write_request
nfs_try_to_update_request will return NULL
nfs_wb_page will return 0
if (clear_page_dirty_for_io(page)) == true
nfs_writepage_locked will return 0
nfs_do_writepage will return 0
nfs_page_async_flush
if (nfs_error_is_fatal_on_server(ret)) == true
nfs_write_error_remove_page
generic_error_remove_page
truncate_inode_page
delete_from_page_cache
__delete_from_page_cache
page_cache_tree_delete
page->mapping = NULL
nfs_page_async_flush() return 0 <== this is point
nfs_do_writepage return 0
nfs_writepage_locked return 0
nfs_wb_page return 0
nfs_try_to_update_request return NULL
if (req != NULL) == false
nfs_create_request
req->wb_page = page // page->mapping == NULL
nfs_inode_add_request
mapping = page_file_mapping(req->wb_page) == NULL
return page->mapping // is NULL
spin_lock(&mapping->private_lock) // oops, mapping is NULL
Fix this by reporting fatal errors and stop writeback.
The patchset (29 patches) "Fix up soft mounts for NFSv4.x" [1] replaces
the custom error reporting mechanism. It seems that we can fix this bug
if we merge all the patchset into LTS 4.19. However, it is clear that
this is not the best option for LTS 4.19.
By the way, applying commit 22876f540bdf ("NFS: Don't call
generic_error_remove_page() while holding locks") into LTS 4.19 will
introduce other issues [2].
Link[1]: https://lore.kernel.org/all/20190407175912.23528-1-trond.myklebust@hammerspace.com/
Link[2]: https://lore.kernel.org/all/tencent_F89651CE8E1BFCEC42C4BFEDD0CA77F82609@qq.com/
Fixes: 89047634f5ce ("NFS: Don't interrupt file writeout due to fatal errors")
Signed-off-by: ChenXiaoSong <chenxiaosong@...inos.cn>
---
fs/nfs/write.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index 65aaa6eaad2c..c69a539eee2c 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -660,7 +660,7 @@ static int nfs_page_async_flush(struct nfs_pageio_descriptor *pgio,
return ret;
out_launder:
nfs_write_error_remove_page(req);
- return 0;
+ return ret;
}
static int nfs_do_writepage(struct page *page, struct writeback_control *wbc,
--
2.34.1
Powered by blists - more mailing lists