summaryrefslogtreecommitdiff
path: root/include/linux/workqueue.h
diff options
context:
space:
mode:
authorZhangGuoDong <zhangguodong@kylinos.cn>2026-07-03 14:54:48 +0800
committerTrond Myklebust <trond.myklebust@hammerspace.com>2026-08-17 09:02:07 -0700
commit3265f1998ae9a9282a8a6ca95467d9572d6ebb82 (patch)
treee51967c19342921746bf423397b407517992a5a1 /include/linux/workqueue.h
parent59075fb8b7887b4149e73e3d5aee2ceeeb87d287 (diff)
NFS: Verify symlink inode before caching target
nfs_symlink() copies the symlink target into a folio before issuing the SYMLINK RPC. After a successful reply, it caches that folio in the instantiated inode mapping and assumes that the dentry now names a symlink. If the dentry is instantiated with a non-symlink inode, the raw symlink target folio can be inserted into the wrong mapping. When that inode is a directory, reclaim or unmount later calls nfs_readdir_clear_array() through nfs_dir_aops and interprets the symlink target as a readdir cache array, which can lead to invalid kfree() calls. A vmcore from a 4.19-based kernel showed the crash when reclaiming a directory mapping on unmount: Stack trace: nfs_readdir_clear_array+0x4d/0x70 [nfs] page_cache_free_page.isra.35+0x1a/0x90 delete_from_page_cache_batch+0x1cf/0x2c0 truncate_inode_pages_range+0x24d/0x910 [...] nfs_evict_inode+0x15/0x30 [nfs] evict+0x115/0x2b0 dispose_list+0x48/0x60 evict_inodes+0x16c/0x1b0 generic_shutdown_super+0x3f/0x120 nfs_kill_super+0x1b/0x40 [nfs] deactivate_locked_super+0x3f/0x70 cleanup_mnt+0x3b/0x80 The current code still has the same unchecked cache insertion pattern, so it may be susceptible to the same failure mode. Verify that the instantiated inode is a symlink before caching the target folio. If the type is wrong, drop the suspect dentry and skip the cache insertion while preserving the successful SYMLINK result. Co-developed-by: Jackie Liu <liuyun01@kylinos.cn> Signed-off-by: Jackie Liu <liuyun01@kylinos.cn> Signed-off-by: ZhangGuoDong <zhangguodong@kylinos.cn> Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
Diffstat (limited to 'include/linux/workqueue.h')
0 files changed, 0 insertions, 0 deletions