From 498eb6780a30d5cbb9bdb0e80bcdef206d305a42 Mon Sep 17 00:00:00 2001 From: Biao Li Date: Wed, 4 Aug 2021 17:29:31 +0800 Subject: [PATCH] ANDROID: fuse: Allocate zeroed memory for canonical path MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The page used to contain the fuse_dentry_canonical_path to be handled in fuse_dev_do_write is allocated using __get_free_pages(GFP_KERNEL). The returned page may contain undefined data, that by chance may be considered as a valid path name that is not in the cache. In that case, if the FUSE daemon mistakenly doesn't fill the canonical path buffer, the FUSE driver may fall into two blocking request_wait_answer(fuse_dev_write->kern_path->fuse_lookup_name) causing a deadlock condition. The stack is as follows: find S 0 20511 20117 0x00000000 Call trace: [] __switch_to+0xb8/0xd4 [] __schedule+0x458/0x714 [] schedule+0x8c/0xa8 [] request_wait_answer+0x74/0x220 [] __fuse_request_send+0x8c/0xa0 [] fuse_request_send+0x60/0x6c [] fuse_dentry_canonical_path+0xb8/0x104 [] do_sys_open+0x1b4/0x260 [] SyS_openat+0x3c/0x4c [] el0_svc_naked+0x34/0x38 mount.ntfs-3g S 0 5845 1 0x00000000 Call trace: [] __switch_to+0xb8/0xd4 [] __schedule+0x458/0x714 [] schedule+0x8c/0xa8 [] request_wait_answer+0x74/0x220 [] __fuse_request_send+0x8c/0xa0 [] fuse_request_send+0x60/0x6c [] fuse_simple_request+0x128/0x16c [] fuse_lookup_name+0x104/0x1b0 [] fuse_lookup+0x5c/0x11c [] lookup_slow+0xfc/0x174 [] walk_component+0xf0/0x290 [] path_lookupat+0xa0/0x128 [] filename_lookup+0x84/0x124 [] kern_path+0x44/0x54 [] fuse_dev_do_write+0x828/0xa0c [] fuse_dev_write+0x90/0xb4 [] do_iter_readv_writev+0xf4/0x13c [] do_readv_writev+0xec/0x220 [] vfs_writev+0x60/0x74 [] do_writev+0x7c/0x100 [] SyS_writev+0x38/0x48 [] el0_svc_naked+0x34/0x38 Fix by ensuring that the page allocated for the canonical path is zeroed. Bug: 194856119 Fixes: 24ab59f6bb42 ("ANDROID: fuse: Add support for d_canonical_path") Signed-off-by: Biao Li Signed-off-by: Shuosheng Huang Signed-off-by: Alessio Balsini Change-Id: I400815dc1049d90c308f5cf87ce60de97ff82131 --- fs/fuse/dir.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index ebd1927b2f61..be2e7c359490 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c @@ -311,7 +311,7 @@ static void fuse_dentry_canonical_path(const struct path *path, struct path *can char *path_name; int err; - path_name = (char*)__get_free_page(GFP_KERNEL); + path_name = (char *)get_zeroed_page(GFP_KERNEL); if (!path_name) goto default_path;