From patchwork Fri Jan 19 09:20:24 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peng Zhang X-Patchwork-Id: 13523476 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id 56FB7C47DB7 for ; Fri, 19 Jan 2024 09:20:46 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 7C96E6B0072; Fri, 19 Jan 2024 04:20:45 -0500 (EST) Received: by kanga.kvack.org (Postfix, from userid 40) id 779446B0074; Fri, 19 Jan 2024 04:20:45 -0500 (EST) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 667A16B0075; Fri, 19 Jan 2024 04:20:45 -0500 (EST) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0017.hostedemail.com [216.40.44.17]) by kanga.kvack.org (Postfix) with ESMTP id 56EB16B0072 for ; Fri, 19 Jan 2024 04:20:45 -0500 (EST) Received: from smtpin06.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay08.hostedemail.com (Postfix) with ESMTP id F2B73140642 for ; Fri, 19 Jan 2024 09:20:44 +0000 (UTC) X-FDA: 81695515608.06.F414594 Received: from szxga02-in.huawei.com (szxga02-in.huawei.com [45.249.212.188]) by imf06.hostedemail.com (Postfix) with ESMTP id B09D0180007 for ; Fri, 19 Jan 2024 09:20:41 +0000 (UTC) Authentication-Results: imf06.hostedemail.com; dkim=none; spf=pass (imf06.hostedemail.com: domain of zhangpeng362@huawei.com designates 45.249.212.188 as permitted sender) smtp.mailfrom=zhangpeng362@huawei.com; dmarc=pass (policy=quarantine) header.from=huawei.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1705656043; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding:in-reply-to: references; bh=Tg2+iUvTb1BpS+NrOdGKFVsBK8MYuHZCixFZqGUJJ+g=; b=dCbVI4MsVTdhOWKfrtu7B7Tn093foTYITOwiHxR3+StM/ExoX7ElOhZ/0wiJPhJkv7bwwB XTcvESGkaR/6V+c9tbxkuyyLcB19A46IVnjNnEBIglBDnNiernWxnOlt26aMj++HOEu/tJ VOAE7YS1O3s6xhRQuC0LNDCMx+cG/zA= ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1705656043; a=rsa-sha256; cv=none; b=Zwi9sVdfJos4VoIpSeY7mJ9V3Vv7gmK9vnOFhOxQngIjd1XKQLbyuwhCRobq5NQarnB476 gfixML6kIAomwGOUyTwaFPXba9uZFnYhLooylDl26qVjLMDSQf6OcBQx0B+SKj1tRWJb0T YZrKKenqQ67I1CuaWIWPbgzrttbx6Lc= ARC-Authentication-Results: i=1; imf06.hostedemail.com; dkim=none; spf=pass (imf06.hostedemail.com: domain of zhangpeng362@huawei.com designates 45.249.212.188 as permitted sender) smtp.mailfrom=zhangpeng362@huawei.com; dmarc=pass (policy=quarantine) header.from=huawei.com Received: from mail.maildlp.com (unknown [172.19.163.48]) by szxga02-in.huawei.com (SkyGuard) with ESMTP id 4TGYwM6SnmzWjww; Fri, 19 Jan 2024 17:19:31 +0800 (CST) Received: from kwepemm600020.china.huawei.com (unknown [7.193.23.147]) by mail.maildlp.com (Postfix) with ESMTPS id 0E2BE180073; Fri, 19 Jan 2024 17:20:31 +0800 (CST) Received: from localhost.localdomain (10.175.112.125) by kwepemm600020.china.huawei.com (7.193.23.147) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.35; Fri, 19 Jan 2024 17:20:29 +0800 From: Peng Zhang To: , , CC: , , , , , , , , Subject: [RFC PATCH] filemap: add mapping_mapped check in filemap_unaccount_folio() Date: Fri, 19 Jan 2024 17:20:24 +0800 Message-ID: <20240119092024.193066-1-zhangpeng362@huawei.com> X-Mailer: git-send-email 2.25.1 MIME-Version: 1.0 X-Originating-IP: [10.175.112.125] X-ClientProxiedBy: dggems703-chm.china.huawei.com (10.3.19.180) To kwepemm600020.china.huawei.com (7.193.23.147) X-Rspamd-Queue-Id: B09D0180007 X-Rspam-User: X-Stat-Signature: qq7nce3iq98muu9gc8e68rhy4zd7aubh X-Rspamd-Server: rspam03 X-HE-Tag: 1705656041-119907 X-HE-Meta: U2FsdGVkX1/ClP86gUnGRhRFINiv+UVyM73noXFuDGwLbegs+GWFQayg+j5dmo0nrIBnv1/+yLHzloHfxlRy0W8FqcsrLuN/EMgUalNXNQZ4OgzGrMeucxlEIRF4DX5cfbiu6u6nC2sLtOZQCbhor3cOFPHFuspczjrt4HlRqTyg09saODz9EIZLsN3q3jhiVKyl3H99EpAY+sbiu1tCOxQHW+6NT+z5wvPsHrTq2md6slbuLEpraqcCFl4E+epLcdVwPg8HHyMDlIildR7iTlelVsoJskQquz93mM2x0HHbdPLO8r6qVzBXRTifMe/08fxNF9Vk8/OCF0fK+VIA0kYgSsm4zVSB6TWtCuo0bu7yATOUNTzVFyHixP6o+VgWM+UruTrP/TecbY/RaljSMetLrEaGt0CkKK2ysBbv7P5LiLOo386MOgeSxFYoUF1FyM/r8YrzL0L9DHHXt/LmRSvKQTqIG3U6X6l0GlqVP0jJnRydD5zGlt291qnudJvWoEQfrS4nQ9AmKe7dAEFJwfmBWByRM5qC84iM2YbGREqiSW6Ay7CxQFCvxFDojLb8sBWIt3V0TN62OfqKeVhA7PG831Eq0BOuIdUsnSFWP8XP7qaCCPaIk6fxdOVhuoJSOhAu3fnSnyZnvnohe0GGCceR9dqDe3pVdwU9gEl3E4250SokN6mG6RM9+E61GO/oDlQy6fL1QrgO7Ol785kGB3EPyfBs7gANbT9X5gBPars/oiHNvB/EiceA/yKUmam7uKUnenSIMvuEQwJO/QH+stAccj75D+9xky2sn5AVEPKzyPdJiKkc2yigxm+ZkeqCPU5WDKMjTqd8+n5XL/MT9GjOmNjnEJUOoav3FmHFuvYNSzQwhH6hm2FMVyZkkA56ZxxrmoBvKeWaq44akSz565j8JegX7O1iXHNdPt/5zHgxZj9fdHjCsNsOhUW9UjmWpv1wIbryKdCGbTIE4UZ 36YxsEw4 liatJzvBPJq/xG16HZK7udZn2h9v1rrHJ6RfP217qM0n1K3yKOomu5M+Yjlc5fFEKuzYTTT8YyFxcqkJvoS6SMgqAmFqWwN0XqqMSIo5qZuyT7rW+suUeVFmvEweorzx7K9V+lx1IWJ1mli/7NJn1yRB9kvwNZ1Xq7arhVMr1hNu/EoMY9mYOEPA92mIq1DdWmRwq X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: List-Subscribe: List-Unsubscribe: From: ZhangPeng Recently, we discovered a syzkaller issue that triggers VM_BUG_ON_FOLIO in filemap_unaccount_folio() with CONFIG_DEBUG_VM enabled, or bad page without CONFIG_DEBUG_VM. The specific scenarios are as follows: (1) mmap: Use socket fd to create a TCP VMA. (2) open(O_CREAT) + fallocate + sendfile: Read the ext4 file and create the page cache. The mapping of the page cache is ext4 inode->i_mapping. Send the ext4 page cache to the socket fd through sendfile. (3) getsockopt TCP_ZEROCOPY_RECEIVE: Receive the ext4 page cache and use vm_insert_pages() to insert the ext4 page cache to the TCP VMA. In this case, mapcount changes from - 1 to 0. The page cache mapping is ext4 inode->i_mapping, but the VMA of the page cache is the TCP VMA and folio->mapping->i_mmap is empty. (4) open(O_TRUNC): Deletes the ext4 page cache. In this case, the page cache is still in the xarray tree of mapping->i_pages and these page cache should also be deleted. However, folio->mapping->i_mmap is empty. Therefore, truncate_cleanup_folio()->unmap_mapping_folio() can't unmap i_mmap tree. In filemap_unaccount_folio(), the mapcount of the folio is 0, causing BUG ON. Syz log that can be used to reproduce the issue: r3 = socket$inet_tcp(0x2, 0x1, 0x0) mmap(&(0x7f0000ff9000/0x4000)=nil, 0x4000, 0x0, 0x12, r3, 0x0) r4 = socket$inet_tcp(0x2, 0x1, 0x0) bind$inet(r4, &(0x7f0000000000)={0x2, 0x4e24, @multicast1}, 0x10) connect$inet(r4, &(0x7f00000006c0)={0x2, 0x4e24, @empty}, 0x10) r5 = openat$dir(0xffffffffffffff9c, &(0x7f00000000c0)='./file0\x00', 0x181e42, 0x0) fallocate(r5, 0x0, 0x0, 0x85b8) sendfile(r4, r5, 0x0, 0x8ba0) getsockopt$inet_tcp_TCP_ZEROCOPY_RECEIVE(r4, 0x6, 0x23, &(0x7f00000001c0)={&(0x7f0000ffb000/0x3000)=nil, 0x3000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, &(0x7f0000000440)=0x40) r6 = openat$dir(0xffffffffffffff9c, &(0x7f00000000c0)='./file0\x00', 0x181e42, 0x0) In the current TCP zerocopy scenario, folio will be released normally . When the process exits, if the page cache is truncated before the process exits, BUG ON or Bad page occurs, which does not meet the expectation. To fix this issue, the mapping_mapped() check is added to filemap_unaccount_folio(). In addition, to reduce the impact on performance, no lock is added when mapping_mapped() is checked. Signed-off-by: ZhangPeng --- mm/filemap.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/mm/filemap.c b/mm/filemap.c index ea49677c6338..6a669eb24816 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -148,10 +148,11 @@ static void page_cache_delete(struct address_space *mapping, static void filemap_unaccount_folio(struct address_space *mapping, struct folio *folio) { + bool mapped = folio_mapped(folio) && mapping_mapped(mapping); long nr; - VM_BUG_ON_FOLIO(folio_mapped(folio), folio); - if (!IS_ENABLED(CONFIG_DEBUG_VM) && unlikely(folio_mapped(folio))) { + VM_BUG_ON_FOLIO(mapped, folio); + if (!IS_ENABLED(CONFIG_DEBUG_VM) && unlikely(mapped)) { pr_alert("BUG: Bad page cache in process %s pfn:%05lx\n", current->comm, folio_pfn(folio)); dump_page(&folio->page, "still mapped when deleted");