From patchwork Tue Oct 17 09:08:12 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeff Xu X-Patchwork-Id: 13424814 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 E13FECDB483 for ; Tue, 17 Oct 2023 09:08:31 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 6E48D8D0106; Tue, 17 Oct 2023 05:08:27 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id 693E58D0101; Tue, 17 Oct 2023 05:08:27 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 4E7348D0106; Tue, 17 Oct 2023 05:08:27 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0015.hostedemail.com [216.40.44.15]) by kanga.kvack.org (Postfix) with ESMTP id 3A9338D0101 for ; Tue, 17 Oct 2023 05:08:27 -0400 (EDT) Received: from smtpin21.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay02.hostedemail.com (Postfix) with ESMTP id 146E2120F98 for ; Tue, 17 Oct 2023 09:08:27 +0000 (UTC) X-FDA: 81354377454.21.9015444 Received: from mail-pl1-f169.google.com (mail-pl1-f169.google.com [209.85.214.169]) by imf27.hostedemail.com (Postfix) with ESMTP id 40F5840008 for ; Tue, 17 Oct 2023 09:08:25 +0000 (UTC) Authentication-Results: imf27.hostedemail.com; dkim=pass header.d=chromium.org header.s=google header.b=Z8LmKfHt; spf=pass (imf27.hostedemail.com: domain of jeffxu@chromium.org designates 209.85.214.169 as permitted sender) smtp.mailfrom=jeffxu@chromium.org; dmarc=pass (policy=none) header.from=chromium.org ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1697533705; 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-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=UgKgE+zT4qoDlXNN6kCnypBqiPQ8What3ncvSi+XOyU=; b=fuUD6RhLhTtpjL8gMD2EVond3KZxViCh7Ob/6KaWPgwWPw6Mwi9uNe051gTnXvxkTVt+62 wUXlMZtN2MeJKTZTRFWZJ8w7lHeD6V6pxVCFzBifoDvCQ4cHyr6k+Kw/V6WeuEAdu4+5pM SEqXzc2MkEqSnlsaBMs7W3FEmICAS2U= ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1697533705; a=rsa-sha256; cv=none; b=QBeWeZ/YSFkeg6YaecHwD0C6SsSYXvjhr6scdZPNgRPBUyWvLUL3Yi5F3jBsr9OOEUIMJn BEUQkChJSH8eCVYHVO37kpg+TXrtqZekpedBm8nSjtXZqrWnn+7lp0H0nbAF9NTIcEA1Xh sYwI5lhEeS9U954G4huvsJanOViPbco= ARC-Authentication-Results: i=1; imf27.hostedemail.com; dkim=pass header.d=chromium.org header.s=google header.b=Z8LmKfHt; spf=pass (imf27.hostedemail.com: domain of jeffxu@chromium.org designates 209.85.214.169 as permitted sender) smtp.mailfrom=jeffxu@chromium.org; dmarc=pass (policy=none) header.from=chromium.org Received: by mail-pl1-f169.google.com with SMTP id d9443c01a7336-1c0ecb9a075so35841345ad.2 for ; Tue, 17 Oct 2023 02:08:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1697533704; x=1698138504; darn=kvack.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=UgKgE+zT4qoDlXNN6kCnypBqiPQ8What3ncvSi+XOyU=; b=Z8LmKfHtjSvJLqyJVFpwEUs/QcvL5zm1gu7hRIFWfzcQkl3dZoME7P7i38o6UtCzUe ppZrcBSeJY+msxBBx/GOL6jGP18PvRjYg8de0vTscOxFJl3jfKl8FcogtzIje5NpoZQs ZGQUVYSida0priiQCR2nMN8n6UepuVmkPtljU= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1697533704; x=1698138504; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=UgKgE+zT4qoDlXNN6kCnypBqiPQ8What3ncvSi+XOyU=; b=blS8eKUzL8dN0NGNTcPtWLb9wzHPntyuZ8azfq+1/AD23K2ZyB8t0lJJ610VyhV9Gz YRbZST+CAn6ZOhpIWnrSg2Ip574EVuiO6SVLVpYvQSBaZjDjnZEqlDhWG8r+6jwL97+l yWizxLFSger4ibwPE9Zb4rRjsHdQuJ5UuLfQUdTGUQlbnmiBDnqpU+YyMixghAKMZMAR AC/LjRR2K3aWtK+PZ4RzQPdhchU+Pv79YhAW0l1m4Dhe5V9EugN0aqJEevTXRdIr3L/Y G09RQLER4MgenEyxloi7lQ6pgxU18Z46K6qhR924ey3mV8VxCK38RJcXHY81ylP8N0Hc ja7w== X-Gm-Message-State: AOJu0YwmqMEgItoRd2LDhjjzbprUfq5pWdZ4jK7ibJCEuNij+AtIw7/W 4oqBiLm2r7vrroutH+eKlAPowg== X-Google-Smtp-Source: AGHT+IHCYocrm1n4yld0Gd8Vj3vGZcQMpjkWq5rvV/TBCHu6MN2SKOy6Ffa2J/O1CuQzRvjFk/JD+Q== X-Received: by 2002:a17:903:4295:b0:1c6:2780:3adc with SMTP id ju21-20020a170903429500b001c627803adcmr1780065plb.24.1697533704140; Tue, 17 Oct 2023 02:08:24 -0700 (PDT) Received: from localhost (9.184.168.34.bc.googleusercontent.com. [34.168.184.9]) by smtp.gmail.com with UTF8SMTPSA id t7-20020a170902e84700b001bc21222e34sm995141plg.285.2023.10.17.02.08.23 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Tue, 17 Oct 2023 02:08:23 -0700 (PDT) From: jeffxu@chromium.org To: akpm@linux-foundation.org, keescook@chromium.org, jannh@google.com, sroettger@google.com, willy@infradead.org, gregkh@linuxfoundation.org, torvalds@linux-foundation.org Cc: jeffxu@google.com, jorgelo@chromium.org, groeck@chromium.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-mm@kvack.org, surenb@google.com, alex.sierra@amd.com, apopple@nvidia.com, aneesh.kumar@linux.ibm.com, axelrasmussen@google.com, ben@decadent.org.uk, catalin.marinas@arm.com, david@redhat.com, dwmw@amazon.co.uk, ying.huang@intel.com, hughd@google.com, joey.gouly@arm.com, corbet@lwn.net, wangkefeng.wang@huawei.com, Liam.Howlett@oracle.com, lstoakes@gmail.com, mawupeng1@huawei.com, linmiaohe@huawei.com, namit@vmware.com, peterx@redhat.com, peterz@infradead.org, ryan.roberts@arm.com, shr@devkernel.io, vbabka@suse.cz, xiujianfeng@huawei.com, yu.ma@intel.com, zhangpeng362@huawei.com, dave.hansen@intel.com, luto@kernel.org, linux-hardening@vger.kernel.org Subject: [RFC PATCH v2 5/8] mseal: Check seal flag for munmap(2) Date: Tue, 17 Oct 2023 09:08:12 +0000 Message-ID: <20231017090815.1067790-6-jeffxu@chromium.org> X-Mailer: git-send-email 2.42.0.655.g421f12c284-goog In-Reply-To: <20231017090815.1067790-1-jeffxu@chromium.org> References: <20231017090815.1067790-1-jeffxu@chromium.org> MIME-Version: 1.0 X-Rspamd-Queue-Id: 40F5840008 X-Rspam-User: X-Rspamd-Server: rspam11 X-Stat-Signature: b8uuhbfg1g8tc8aoh7wqm45ep8zajo4x X-HE-Tag: 1697533705-91675 X-HE-Meta: U2FsdGVkX19q7Xutd9xFYT336iYPDZL8oW+WtVZhNTKeqr6WUpDZQJ0BpPuAZ2oH5QThqt12rf+Wv4agsOM9Jv0ULpZyyWd//0ksGGTBPyQjZrIn5uNO9Uj4c8yDmPQQMJBhJqMh+Y7QsLDvTEU3LY8atTa92gicF9z2M+H2kZzKk0NEg7rU7oRnJ/M3c+pNtHpYrOHeLlu43zczFoelZZXrC3DB6LjHYzp3C5PWbly+hEFdTc9WEffNXIwYAUUGF8v87ZKXxqqR7HVhdMRWyZ/XIBPUlU/JjsKDf+VP6zxdJvFWNdsyRS1BpQ4lwzT15GriSdevzse8+3m5o8nYvMBRLSJu4LdeO3ZIIdhNUWCoTqh724R6Xxwyfw0qBC2pdEqDU7rl9qPQfpqWVMhaYHTNTQAYPpV71OFIbFzzo9gbw9PnDm0bJGB7lkaLaBkxl7YMGuhnrgqXGh1vVjWX5z7sAlbFjduBS0cYVfkZ0hEhItO79Lf4ZzkokygPhx46/9HTBq4UpnBMdcW32BLggk3/rmrzkwHmwZU7bfk0nh/g9d7QEgUWGHdiC7iMIgZkFUH7y4c9XVitL96ulH3foVwY64OLaaaKTNNkwGz3lB0RB2VpdFcLX57NHGW0yQl3okpz4nPfP91oIdIohnr5lZbJoElfKC/8LplmslazFnmS2/lLpo5eDr3W7HQcK4PCzskkU/yJYa8CkeSkzwCe7i+QblDGvKBUa8pHEGSyvanhReTCdyHPQRoYtbpxoNcoDENYC/6w6V0TsO0FvmLiYWBox198N8CK8+9ixZns2J/GIx+SEzXJrsZyZ0re9dspKFjbbL/Pl7ZgXDs5RLftSjxbx3hV5vxNgB2+gSKl5KUWyU7TfcLuFVndOHdbR8HmMPlIB3PS/CK15A/akVe8uCeb9dofXGOddTAyzBJ2kgcpq0Xzzh5SAOSe9qpqSxkb5pBhaZ5GUA/QX/4znuj qr21t2T5 2eLgEBLHG72jW2E9KDikfW8Jjn+ozGezLvS59bCjBFJimCKhWVWmHhptgm9lODoPdDDDVnXklHhMmbCncn7D7yRVXG6K3XZLUUlxigiaymzAd4+ccApLLjxTedK6M8HWlwMQqovVofT4sSvqFME3tnlxyF+hkNukYXekyU/N+op5imJLszig0hMI6OBnEGhTJ3/OGmnie3BLIfM4eqpAlH6oF4TdiGFxHPIHl4WC4yTnN9iG9D7EusG7DnsZuhUqFK6YQFuakg6ZjQkFVkwpkMfFTka8qx96zHm17Mfnfe0xXB+O1pXYUhRj7p3vaok8Wy7pO4eJ/3UVfQ/k= 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: From: Jeff Xu munmap(2) unmap VMAs in the given address range. Sealing will prevent unintended munmap(2) call. What this patch does: When a munmap(2) is invoked, if one of its VMAs has MM_SEAL_MUNMAP set from previous mseal(2) call, this munmap(2) will fail, without any VMA modified. This patch is based on following: 1. At syscall entry point: SYSCALL_DEFINE2(munmap, ...) Pass checkSeals = MM_SEAL_MUNMAP into __vm_munmap(), in turn, to do_vmi_munmap(). Of all the call paths that call into do_vmi_munmap(), this is the only place where checkSeals = MM_SEAL_MUNMAP. The rest has checkSeals = 0. 2. In do_vmi_munmap(), calls can_modify_mm() before any update is made to VMAs. Signed-off-by: Jeff Xu --- include/linux/mm.h | 2 +- mm/mmap.c | 21 +++++++++++++-------- mm/mremap.c | 5 +++-- 3 files changed, 17 insertions(+), 11 deletions(-) diff --git a/include/linux/mm.h b/include/linux/mm.h index b09df8501987..f2f316522f2a 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -3279,7 +3279,7 @@ extern unsigned long do_mmap(struct file *file, unsigned long addr, unsigned long pgoff, unsigned long *populate, struct list_head *uf); extern int do_vmi_munmap(struct vma_iterator *vmi, struct mm_struct *mm, unsigned long start, size_t len, struct list_head *uf, - bool unlock); + bool unlock, unsigned long checkSeals); extern int do_munmap(struct mm_struct *, unsigned long, size_t, struct list_head *uf); extern int do_madvise(struct mm_struct *mm, unsigned long start, size_t len_in, int behavior); diff --git a/mm/mmap.c b/mm/mmap.c index 414ac31aa9fa..62d592f16f45 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -2601,6 +2601,7 @@ do_vmi_align_munmap(struct vma_iterator *vmi, struct vm_area_struct *vma, * @len: The length of the range to munmap * @uf: The userfaultfd list_head * @unlock: set to true if the user wants to drop the mmap_lock on success + * @checkSeals: seal type to check. * * This function takes a @mas that is either pointing to the previous VMA or set * to MA_START and sets it up to remove the mapping(s). The @len will be @@ -2611,7 +2612,7 @@ do_vmi_align_munmap(struct vma_iterator *vmi, struct vm_area_struct *vma, */ int do_vmi_munmap(struct vma_iterator *vmi, struct mm_struct *mm, unsigned long start, size_t len, struct list_head *uf, - bool unlock) + bool unlock, unsigned long checkSeals) { unsigned long end; struct vm_area_struct *vma; @@ -2623,6 +2624,9 @@ int do_vmi_munmap(struct vma_iterator *vmi, struct mm_struct *mm, if (end == start) return -EINVAL; + if (!can_modify_mm(mm, start, end, checkSeals)) + return -EACCES; + /* arch_unmap() might do unmaps itself. */ arch_unmap(mm, start, end); @@ -2650,7 +2654,7 @@ int do_munmap(struct mm_struct *mm, unsigned long start, size_t len, { VMA_ITERATOR(vmi, mm, start); - return do_vmi_munmap(&vmi, mm, start, len, uf, false); + return do_vmi_munmap(&vmi, mm, start, len, uf, false, 0); } unsigned long mmap_region(struct file *file, unsigned long addr, @@ -2684,7 +2688,7 @@ unsigned long mmap_region(struct file *file, unsigned long addr, } /* Unmap any existing mapping in the area */ - if (do_vmi_munmap(&vmi, mm, addr, len, uf, false)) + if (do_vmi_munmap(&vmi, mm, addr, len, uf, false, 0)) return -ENOMEM; /* @@ -2909,7 +2913,8 @@ unsigned long mmap_region(struct file *file, unsigned long addr, return error; } -static int __vm_munmap(unsigned long start, size_t len, bool unlock) +static int __vm_munmap(unsigned long start, size_t len, bool unlock, + unsigned long checkSeals) { int ret; struct mm_struct *mm = current->mm; @@ -2919,7 +2924,7 @@ static int __vm_munmap(unsigned long start, size_t len, bool unlock) if (mmap_write_lock_killable(mm)) return -EINTR; - ret = do_vmi_munmap(&vmi, mm, start, len, &uf, unlock); + ret = do_vmi_munmap(&vmi, mm, start, len, &uf, unlock, checkSeals); if (ret || !unlock) mmap_write_unlock(mm); @@ -2929,14 +2934,14 @@ static int __vm_munmap(unsigned long start, size_t len, bool unlock) int vm_munmap(unsigned long start, size_t len) { - return __vm_munmap(start, len, false); + return __vm_munmap(start, len, false, 0); } EXPORT_SYMBOL(vm_munmap); SYSCALL_DEFINE2(munmap, unsigned long, addr, size_t, len) { addr = untagged_addr(addr); - return __vm_munmap(addr, len, true); + return __vm_munmap(addr, len, true, MM_SEAL_MUNMAP); } @@ -3168,7 +3173,7 @@ int vm_brk_flags(unsigned long addr, unsigned long request, unsigned long flags) if (ret) goto limits_failed; - ret = do_vmi_munmap(&vmi, mm, addr, len, &uf, 0); + ret = do_vmi_munmap(&vmi, mm, addr, len, &uf, 0, 0); if (ret) goto munmap_failed; diff --git a/mm/mremap.c b/mm/mremap.c index 056478c106ee..ac363937f8c4 100644 --- a/mm/mremap.c +++ b/mm/mremap.c @@ -715,7 +715,8 @@ static unsigned long move_vma(struct vm_area_struct *vma, } vma_iter_init(&vmi, mm, old_addr); - if (!do_vmi_munmap(&vmi, mm, old_addr, old_len, uf_unmap, false)) { + if (!do_vmi_munmap(&vmi, mm, old_addr, old_len, uf_unmap, false, + 0)) { /* OOM: unable to split vma, just get accounts right */ if (vm_flags & VM_ACCOUNT && !(flags & MREMAP_DONTUNMAP)) vm_acct_memory(old_len >> PAGE_SHIFT); @@ -1009,7 +1010,7 @@ SYSCALL_DEFINE5(mremap, unsigned long, addr, unsigned long, old_len, } ret = do_vmi_munmap(&vmi, mm, addr + new_len, old_len - new_len, - &uf_unmap, true); + &uf_unmap, true, 0); if (ret) goto out;