From patchwork Mon Mar 17 03:16:29 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Ren, Jianqi (Jacky) (CN)" X-Patchwork-Id: 14018610 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 E0E67C28B2F for ; Mon, 17 Mar 2025 03:17:21 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 11925280002; Sun, 16 Mar 2025 23:17:19 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id 0C890280001; Sun, 16 Mar 2025 23:17:19 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id ED254280002; Sun, 16 Mar 2025 23:17:18 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0010.hostedemail.com [216.40.44.10]) by kanga.kvack.org (Postfix) with ESMTP id CA03E280001 for ; Sun, 16 Mar 2025 23:17:18 -0400 (EDT) Received: from smtpin26.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay04.hostedemail.com (Postfix) with ESMTP id 61E2D1A1494 for ; Mon, 17 Mar 2025 03:17:20 +0000 (UTC) X-FDA: 83229582240.26.5F7F052 Received: from mx0a-0064b401.pphosted.com (mx0a-0064b401.pphosted.com [205.220.166.238]) by imf25.hostedemail.com (Postfix) with ESMTP id 10D07A0006 for ; Mon, 17 Mar 2025 03:17:17 +0000 (UTC) Authentication-Results: imf25.hostedemail.com; dkim=none; dmarc=pass (policy=reject) header.from=windriver.com; spf=pass (imf25.hostedemail.com: domain of "prvs=517140f2e9=jianqi.ren.cn@windriver.com" designates 205.220.166.238 as permitted sender) smtp.mailfrom="prvs=517140f2e9=jianqi.ren.cn@windriver.com" ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1742181438; 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=2m9P+UFG6SnjxvJZcIUkPEIqpAZL0Qsg6iK7F/GDjAk=; b=0NaDftdtzTu8TrAiiXYLGPwro0EwBLlHfnvvc0R0MbSyRwY46ZFLbLkkq9TqCobYn2Ixku 06KZUvWU5aGG1MpUjdbGGDWvGZU9QcrdE/9aN0B9IQVbwZMguzVfAKyMWkAn4F1MgXcGe6 VOV0J+x9ZJs4aTWErlv6pgyZDRuJw+0= ARC-Authentication-Results: i=1; imf25.hostedemail.com; dkim=none; dmarc=pass (policy=reject) header.from=windriver.com; spf=pass (imf25.hostedemail.com: domain of "prvs=517140f2e9=jianqi.ren.cn@windriver.com" designates 205.220.166.238 as permitted sender) smtp.mailfrom="prvs=517140f2e9=jianqi.ren.cn@windriver.com" ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1742181438; a=rsa-sha256; cv=none; b=O0Y+E0UCIz7pLFSMNVZGIIdUKEsJM42JVjV/WXeoojTSQZAxsm9ljSQiOmzq4+Jiu2t69i 0XcQiqEbxGNbddrWwCmh/vEdKttQsER0bAOAzQSZokZJltguR1kpxN52vCPG557W3s+778 ImfIiKzt23ckEkswd71RIqNJO/mrGK0= Received: from pps.filterd (m0250810.ppops.net [127.0.0.1]) by mx0a-0064b401.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 52H3Ggvr019255; Sun, 16 Mar 2025 20:16:42 -0700 Received: from ala-exchng02.corp.ad.wrs.com (ala-exchng02.wrs.com [147.11.82.254]) by mx0a-0064b401.pphosted.com (PPS) with ESMTPS id 45d4u41e50-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Sun, 16 Mar 2025 20:16:42 -0700 (PDT) Received: from ALA-EXCHNG02.corp.ad.wrs.com (147.11.82.254) by ALA-EXCHNG02.corp.ad.wrs.com (147.11.82.254) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.43; Sun, 16 Mar 2025 20:16:34 -0700 Received: from pek-lpg-core1.wrs.com (147.11.136.210) by ALA-EXCHNG02.corp.ad.wrs.com (147.11.82.254) with Microsoft SMTP Server id 15.1.2507.43 via Frontend Transport; Sun, 16 Mar 2025 20:16:30 -0700 From: To: CC: , , , , , , , , , , , , , , , , , , , Subject: [PATCH 6.6.y] mm: split critical region in remap_file_pages() and invoke LSMs in between Date: Mon, 17 Mar 2025 11:16:29 +0800 Message-ID: <20250317031629.2244-1-jianqi.ren.cn@windriver.com> X-Mailer: git-send-email 2.25.1 MIME-Version: 1.0 X-Proofpoint-ORIG-GUID: bVmTRPOsgWVbYo47AjBXgKpokUDYsrBY X-Proofpoint-GUID: bVmTRPOsgWVbYo47AjBXgKpokUDYsrBY X-Authority-Analysis: v=2.4 cv=UIfdHDfy c=1 sm=1 tr=0 ts=67d7941a cx=c_pps a=K4BcnWQioVPsTJd46EJO2w==:117 a=K4BcnWQioVPsTJd46EJO2w==:17 a=Vs1iUdzkB0EA:10 a=VwQbUJbxAAAA:8 a=AiHppB-aAAAA:8 a=1XWaLZrsAAAA:8 a=QyXUC8HyAAAA:8 a=i0EeH86SAAAA:8 a=hSkVLCK3AAAA:8 a=yPCof4ZbAAAA:8 a=xVhDTqbCAAAA:8 a=pGLkceISAAAA:8 a=K6HrmWtEAAAA:8 a=VnNF1IyMAAAA:8 a=hBqU3vQJAAAA:8 a=Z4Rwk6OoAAAA:8 a=t7CeM3EgAAAA:8 a=EeNX1Q8U76Y4bKcPbGMA:9 a=cQPPKAXgyycSBL8etih5:22 a=GrmWmAYt4dzCMttCBZOh:22 a=yV38gEssg_2GhkhKF82i:22 a=WLjMIN4s_96MqnBbPenP:22 a=HkZW87K1Qel5hWWM3VKY:22 a=FdTzh2GWekK77mhwV6Dw:22 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1093,Hydra:6.0.680,FMLib:17.12.68.34 definitions=2025-03-17_01,2025-03-14_01,2024-11-22_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 impostorscore=0 mlxscore=0 phishscore=0 priorityscore=1501 malwarescore=0 mlxlogscore=999 bulkscore=0 clxscore=1011 lowpriorityscore=0 adultscore=0 suspectscore=0 spamscore=0 classifier=spam authscore=0 authtc=n/a authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.21.0-2502280000 definitions=main-2503170023 X-Rspam-User: X-Rspamd-Queue-Id: 10D07A0006 X-Rspamd-Server: rspam08 X-Stat-Signature: 44et88qjoh9g59s1uxxba3ncswu5xzs5 X-HE-Tag: 1742181437-168577 X-HE-Meta: U2FsdGVkX1+k2pRcvUTFkzCQJnXsURDkS5zGOOj4o6LXZJOy5eNZqzKi41DLuje1OwW1UIf5IVVnTgVii4An7gofMIw7MR7QPupb2V9ejZnGqNFIAwojr8XqcwhGSKZ5RgPYWVayfqx6ggMmkvCume3H/+/6KxJPkOQ/62ytIEd0PSrpiGWkxYkJYtkOH1rTrM7mwu9mnWrBPgnpT5XtwaaF5Co1BIgwpgSD9jicGQm2PXoxKiHLMIdGB6rRqWDghHGzXyMcwdQ0vFv6ef1XGPLeZuyhbcVPTQNs1QlFnitFF9UVAyvSEnzaMt6g4kSU6OEx1b/KF3WCvxKQpz7ymLQfLDEsNagP+PoKfZ47Gl+8RWxKWAgA44g78M+mQ+D4fSe/T9AopEG99i0EgbWLLV42YDkccz1qCi7w4I4P9dYPjZgWJ5+Y9eDWwN8Wv1OX2RW5A1KPI6P9bWqxDJDniQBXor3nNHsDoWnnHz6H6W8I4yyiZYKRObK5yPPpYhshzLDup+oSFdtpV84+vJbywi4Zjq65uS3pn625XN21uHw7Q+CxFPnrxe2AYIEFbcmWSQ/wwUzJjeycTWvpmAH4Gypa8PUV91JUm0zhLTwzunnkPzbCpVh7a6rNpimSFBrotN04IqvNy34A4vyalVn299TEYRYH8xqHqqos61SSnmPa+OARgiDM7QNtD1m+f2s84CvLPPbSbLqqw9LVc5WE9OulpSL+bECQJygTMqPw+e3bZFjgl5xKr3/cEz/N9Vi8G0yVUWM/MF/QTrPukNHh4qKX7xP/bsHsLPugxSMqqMZr9ycK+7LCkiCD52q33VgGZKGr+ppfTFOdR9RTEbP4fixXv81bC26lChATQJaIzDuS9oSNUwRa8cJ5onCM0VTe2um8qTiGkCFo0QCWOzdrJBJOEmGLM+lyyCJrZTij79STgJXydX/GLVSN9KZ42L183NxC2WJ44UIz3VZP2qv bEny96CA zsSsHnnhHaRouXKKpLandA3HDxJeFMo2oEdseTZ1/qD2TX/K902XCNOQ6IPKaKcDwmiSb6oEoWuGsotaRQHUe4k8OFxkKrzFnyyrFHs8xvmJJUrwSmdHXerCnj9B/ctKAOuUtPRzqMXVM3tE5kQiXtlAPFz4NuP7RXBmUcOroIMb1f2cNQDxKZH5vH2QroIuuS4mmH1OiTuQen9IMGYg2Sw/zPrEqbsZLS2Gzmqa+Fzk9lPJaNp2lQkZcPJVcBF4k39Rn0dDASkg8s2MqI7lsHGrznuXrltxElAh25zhQELzmyRc/cL3Db9JgzlIPiBZYFuGXaOmcqcuNJsA1ahYESQRWL/GtUsOnuwwKS1g06zzShrX3KjTgxHtt2zUfjuOc0tsA298vz8fKXyYxY8lmekKskrZ+giIg2nFCEPHlGfa6Dz9j+OViSP6CnNBhyhJ6uyW7hEfAN+iAbz7SPUH/lZr8zD1ZGIC1yLW/dBdcsN+TQxR3VSkBcfm3wvqjBlZJziqO+XTHvbgOH41YhekH7SnFS22xXyuTVofXucbKX63cEw2o5555dVxV/XPvkzKjKQYkJckywC6QtJqiIWUbR3VLZCFX88V84BVDM+lK4CfUF8uLj02VxThzkA3s/EhA02Na1zQT2OOYIu2bnHRS6Nue1ZosR9rKP3AJIxl4vSqD6A9DZI4yBhvaFQJGa0mi37MgpMb65K2HOUzNAXZDTd7l8kgsv9PaeqUkH6y3RoqJF1qFIzyZ0tuTEAyweJsVU338d8vx/lA0KH9mOIB2UKBx/dPtdUmfErRv2TO0ymwxvWLSwIu3CfvjqNJ6vvBV+XDUI2WX4pW1PxJiaHhAHLrklpAINfYLoRzQtwg8r2lsaa3dB/ImgodBd4JMgNqiA4ESjKGB2dJyJxQikuM3/+WWLg== 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: "Kirill A. Shutemov" [ Upstream commit 58a039e679fe72bd0efa8b2abe669a7914bb4429 ] Commit ea7e2d5e49c0 ("mm: call the security_mmap_file() LSM hook in remap_file_pages()") fixed a security issue, it added an LSM check when trying to remap file pages, so that LSMs have the opportunity to evaluate such action like for other memory operations such as mmap() and mprotect(). However, that commit called security_mmap_file() inside the mmap_lock lock, while the other calls do it before taking the lock, after commit 8b3ec6814c83 ("take security_mmap_file() outside of ->mmap_sem"). This caused lock inversion issue with IMA which was taking the mmap_lock and i_mutex lock in the opposite way when the remap_file_pages() system call was called. Solve the issue by splitting the critical region in remap_file_pages() in two regions: the first takes a read lock of mmap_lock, retrieves the VMA and the file descriptor associated, and calculates the 'prot' and 'flags' variables; the second takes a write lock on mmap_lock, checks that the VMA flags and the VMA file descriptor are the same as the ones obtained in the first critical region (otherwise the system call fails), and calls do_mmap(). In between, after releasing the read lock and before taking the write lock, call security_mmap_file(), and solve the lock inversion issue. Link: https://lkml.kernel.org/r/20241018161415.3845146-1-roberto.sassu@huaweicloud.com Fixes: ea7e2d5e49c0 ("mm: call the security_mmap_file() LSM hook in remap_file_pages()") Signed-off-by: Kirill A. Shutemov Signed-off-by: Roberto Sassu Reported-by: syzbot+1cd571a672400ef3a930@syzkaller.appspotmail.com Closes: https://lore.kernel.org/linux-security-module/66f7b10e.050a0220.46d20.0036.GAE@google.com/ Tested-by: Roberto Sassu Reviewed-by: Roberto Sassu Reviewed-by: Jann Horn Reviewed-by: Lorenzo Stoakes Reviewed-by: Liam R. Howlett Reviewed-by: Paul Moore Tested-by: syzbot+1cd571a672400ef3a930@syzkaller.appspotmail.com Cc: Jarkko Sakkinen Cc: Dmitry Kasatkin Cc: Eric Snowberg Cc: James Morris Cc: Mimi Zohar Cc: "Serge E. Hallyn" Cc: Shu Han Cc: Vlastimil Babka Signed-off-by: Andrew Morton Signed-off-by: Jianqi Ren Signed-off-by: He Zhe --- Verified the build test --- mm/mmap.c | 69 +++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 52 insertions(+), 17 deletions(-) diff --git a/mm/mmap.c b/mm/mmap.c index e4dfeaef668a..03a24cb3951d 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -2981,6 +2981,7 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size, unsigned long populate = 0; unsigned long ret = -EINVAL; struct file *file; + vm_flags_t vm_flags; pr_warn_once("%s (%d) uses deprecated remap_file_pages() syscall. See Documentation/mm/remap_file_pages.rst.\n", current->comm, current->pid); @@ -2997,12 +2998,60 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size, if (pgoff + (size >> PAGE_SHIFT) < pgoff) return ret; - if (mmap_write_lock_killable(mm)) + if (mmap_read_lock_killable(mm)) + return -EINTR; + + /* + * Look up VMA under read lock first so we can perform the security + * without holding locks (which can be problematic). We reacquire a + * write lock later and check nothing changed underneath us. + */ + vma = vma_lookup(mm, start); + + if (!vma || !(vma->vm_flags & VM_SHARED)) { + mmap_read_unlock(mm); + return -EINVAL; + } + + prot |= vma->vm_flags & VM_READ ? PROT_READ : 0; + prot |= vma->vm_flags & VM_WRITE ? PROT_WRITE : 0; + prot |= vma->vm_flags & VM_EXEC ? PROT_EXEC : 0; + + flags &= MAP_NONBLOCK; + flags |= MAP_SHARED | MAP_FIXED | MAP_POPULATE; + if (vma->vm_flags & VM_LOCKED) + flags |= MAP_LOCKED; + + /* Save vm_flags used to calculate prot and flags, and recheck later. */ + vm_flags = vma->vm_flags; + file = get_file(vma->vm_file); + + mmap_read_unlock(mm); + + /* Call outside mmap_lock to be consistent with other callers. */ + ret = security_mmap_file(file, prot, flags); + if (ret) { + fput(file); + return ret; + } + + ret = -EINVAL; + + /* OK security check passed, take write lock + let it rip. */ + if (mmap_write_lock_killable(mm)) { + fput(file); return -EINTR; + } vma = vma_lookup(mm, start); - if (!vma || !(vma->vm_flags & VM_SHARED)) + if (!vma) + goto out; + + /* Make sure things didn't change under us. */ + if (vma->vm_flags != vm_flags) + goto out; + if (vma->vm_file != file) goto out; if (start + size > vma->vm_end) { @@ -3030,25 +3079,11 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size, goto out; } - prot |= vma->vm_flags & VM_READ ? PROT_READ : 0; - prot |= vma->vm_flags & VM_WRITE ? PROT_WRITE : 0; - prot |= vma->vm_flags & VM_EXEC ? PROT_EXEC : 0; - - flags &= MAP_NONBLOCK; - flags |= MAP_SHARED | MAP_FIXED | MAP_POPULATE; - if (vma->vm_flags & VM_LOCKED) - flags |= MAP_LOCKED; - - file = get_file(vma->vm_file); - ret = security_mmap_file(vma->vm_file, prot, flags); - if (ret) - goto out_fput; ret = do_mmap(vma->vm_file, start, size, prot, flags, 0, pgoff, &populate, NULL); -out_fput: - fput(file); out: mmap_write_unlock(mm); + fput(file); if (populate) mm_populate(ret, populate); if (!IS_ERR_VALUE(ret))