From patchwork Wed Aug 14 07:14:23 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeff Xu X-Patchwork-Id: 13762914 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 495D7C52D7F for ; Wed, 14 Aug 2024 07:14:38 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id B857B6B0089; Wed, 14 Aug 2024 03:14:37 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id B34BA6B0088; Wed, 14 Aug 2024 03:14:37 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 9877A6B0089; Wed, 14 Aug 2024 03:14:37 -0400 (EDT) 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 76BC16B0083 for ; Wed, 14 Aug 2024 03:14:37 -0400 (EDT) Received: from smtpin28.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay06.hostedemail.com (Postfix) with ESMTP id B974FA7C62 for ; Wed, 14 Aug 2024 07:14:36 +0000 (UTC) X-FDA: 82449988152.28.D1C327F Received: from mail-pl1-f177.google.com (mail-pl1-f177.google.com [209.85.214.177]) by imf08.hostedemail.com (Postfix) with ESMTP id C6BB2160035 for ; Wed, 14 Aug 2024 07:14:34 +0000 (UTC) Authentication-Results: imf08.hostedemail.com; dkim=pass header.d=chromium.org header.s=google header.b=BORiePDg; dmarc=pass (policy=none) header.from=chromium.org; spf=pass (imf08.hostedemail.com: domain of jeffxu@chromium.org designates 209.85.214.177 as permitted sender) smtp.mailfrom=jeffxu@chromium.org ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1723619662; a=rsa-sha256; cv=none; b=zHo3+wR5vEG4Bpa/u7V5i0J2Fe9jEty6nycKoj7Jk+fuMZxb9bVSWNoKLSCihdnX6tzd0M wALeWNTbvSHVerA/sqo5gh3E8eQNEXAEGFPgxo2g7VFPF8NOvolyAlXPxxen69MZuX7cDM FESstVN82oLLNLU1cFixF4L8Wg9qpRM= ARC-Authentication-Results: i=1; imf08.hostedemail.com; dkim=pass header.d=chromium.org header.s=google header.b=BORiePDg; dmarc=pass (policy=none) header.from=chromium.org; spf=pass (imf08.hostedemail.com: domain of jeffxu@chromium.org designates 209.85.214.177 as permitted sender) smtp.mailfrom=jeffxu@chromium.org ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1723619662; 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=PgVLZ9rJ8uTulNaVowlNQVAT4uj5xefq6Kph3t1/npI=; b=qRHGW5LQHJ4YrZ3xf6c7xq1tdPOY2eZ9oNsG/xe0JwLx41kcAPdSHpQoX3sbVAaPIqqbhW sDIrSNyDxZMLlY/rVlsrShGK9vE+mry5omU4qd8XXmN7Q7Eb+cqdvQeTSUu2yeCi7LGUi2 9bXOGlX2K9jOIzXyGs5XTr+3zQ7Mw+w= Received: by mail-pl1-f177.google.com with SMTP id d9443c01a7336-201d6ac1426so4814535ad.1 for ; Wed, 14 Aug 2024 00:14:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1723619673; x=1724224473; 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=PgVLZ9rJ8uTulNaVowlNQVAT4uj5xefq6Kph3t1/npI=; b=BORiePDg7eM0wxQSPKiVdVbjvT9W4aAIDtmPgKS6uYtOCteGRx+FUfXoNpUBpmfroP dRTU5NDbLnNDoO81OF/pO677XWDUVdZ5MNCleCn9+JaEjA7cXQzADWFjuCRQscsQtlVi ght7h4fHspjJ9lBo6dvrVBWivwVvzak9/pRY4= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1723619673; x=1724224473; 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=PgVLZ9rJ8uTulNaVowlNQVAT4uj5xefq6Kph3t1/npI=; b=wrYVRwrmE4mH2BpenSoz1KI7wkmdzrwnULdR9wNnOFkFzpnCQ+l7eB4F+GGWv5TNHf h7dY9lSjvejlqwSdUmzlXluHxYIDGGQ8xFr4RtuZ6gfIiSnuPy7RpyMrJSUziLgMWP3U ExoHb8WNnYNxW7nIkxmQMystbWxjsgXK9ZGue2Ci+wRu5EwAL/UWETzTfwBf7d1eJDh0 ZPvTm9DrmA0kutg3OGCoJnu138sJ4+c/oiFE2KU9OypQ2tg4hIDdInC8gpTLg1iocOMx 20pNg572UHzEU1YI8FWQVKFx5lU4RVqff8HcqMKZoIwN5gYkem2G9IfRAuJ/ZOsFwSqI i73w== X-Forwarded-Encrypted: i=1; AJvYcCUKz+yuLmua3VjODiOiFGWiP0JppGDmlOPQBAMjHbS8YPgzsfMYb3aHgGgkZU+7NoIZySxQB48QdYhcTcN4ITV9se0= X-Gm-Message-State: AOJu0YwFl6X4iJWz9Pu8LjJHzbWMk98geRCpLcLMfjxwZeogqRYk/IeG h5Qfv756zSwAj4Wa6YdYq7908YKGm5oTtwoS9KLTT8DgLWQAcIMJCHPluhZu+g== X-Google-Smtp-Source: AGHT+IHU57C7vsS+qNBq8gDAWLhmPJNqgKoeLlLOzmIi1g6FfwO3Vs3x6r998OZVdfqTnr2qHr+eJA== X-Received: by 2002:a17:902:d2c1:b0:1fd:6529:744c with SMTP id d9443c01a7336-201d638fe41mr23419445ad.1.1723619672938; Wed, 14 Aug 2024 00:14:32 -0700 (PDT) Received: from localhost (150.12.83.34.bc.googleusercontent.com. [34.83.12.150]) by smtp.gmail.com with UTF8SMTPSA id d9443c01a7336-201cd1314cesm23705465ad.8.2024.08.14.00.14.32 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Wed, 14 Aug 2024 00:14:32 -0700 (PDT) From: jeffxu@chromium.org To: akpm@linux-foundation.org, willy@infradead.org, torvalds@linux-foundation.org, Liam.Howlett@oracle.com, pedro.falcato@gmail.com Cc: linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-mm@kvack.org, linux-hardening@vger.kernel.org, jeffxu@google.com, lorenzo.stoakes@oracle.com, mpe@ellerman.id.au, oliver.sang@intel.com, vbabka@suse.cz, keescook@chromium.org, Jeff Xu Subject: [PATCH v1 1/2] mseal:selftest mremap across VMA boundaries. Date: Wed, 14 Aug 2024 07:14:23 +0000 Message-ID: <20240814071424.2655666-2-jeffxu@chromium.org> X-Mailer: git-send-email 2.46.0.76.ge559c4bf1a-goog In-Reply-To: <20240814071424.2655666-1-jeffxu@chromium.org> References: <20240814071424.2655666-1-jeffxu@chromium.org> MIME-Version: 1.0 X-Rspam-User: X-Rspamd-Queue-Id: C6BB2160035 X-Rspamd-Server: rspam01 X-Stat-Signature: ggr4he6att5eh93fxmohikioxt1uqrkq X-HE-Tag: 1723619674-252953 X-HE-Meta: U2FsdGVkX18cO9oKlvGo0uFvuov8V15GzArT0WtL7HOeqQVPnnOVkAKVpVDOSzvTO2hiYHry/evVZnbIriMpdiBpp/1OwHFVZhXghajobLTse2/gPAPAY9xBKl4zTqxPFP0+bnLFspJ9VcfRatLbrl48Wnp+e7D7Z65xMUZOA3XEnWb/UIjfVvHN3MEgZudAFeu40PX5tcqpRCCa+7EozaIon3p1FDhuWmw0za5fCZkioQRrhmbKR0wXSviH38cYz9XaPIaxuGYvpDxZO7PBSMuGu+QKQoPZ97Zf1Obgy6D8vzCIbg44ZU9VvdDffML0+wLGiEP1EDATVMbntVA0vdBBiZ5DrjJPwMoF2rYdIRP4R0xmRFoM95ChL5nDdCPSRvN2MPpjpiy1CNSf2lEjU9ZlDRx+LgjKTz9Du4/v+mUAjO3PUmI1bclOdfw3GNh/vWBhfOO8x0Qx+MWOJCdGQfhs5LVNNk8x9pmzJPey3c1OY6YvMG8XtvbDByJ9BPms1nH0J437UlJNrTdR0ZX11VvjNLWaA+naB20pOebul6ZSxBt37Xk9utOcSHwJEr3j8BP178QEXIFSV5EOA5KK0Swh7OTweVYmZMdEACCn46ndNyqW94sUjvX9Lj3MvkE6OljdX06IgXmIMzILZs2h42yt2EEo3euGD1526EiYEmly+4Ghzc9HAy+posG0xm2oCgB8XMU8gPOq7TWTZWST8YNhcnztXatfZsrWyU58d/sB3gAp2QNQS4VyqHuUwKVGOLbEqDxu5Br2ezjVSaMRJipBPfYlNwpdVSfEOrx1nEy0tSzpGwM3Red7zHAgf1ZhdGndkAe+ykM4A/TvUActlIas4mYEoAPIi/pCXvxITLACPw5eJbQt6HFSNUHcVKdWbHydOOb30jSZJz5L0VRg68sQI+kStQImPjfkK1V2V0B5tRmkXJOL6a1Kam3IzEoOicBo8QLc3/vETZSibE9 g+kOS7J5 roBhGOInUWJwGPanGuogM6jdnG6gOyf6gnZMktKBLE6z99yyhu1HQjqQz6ceiCqxwsg4KWZVma+BIPKqEsX+pW9WZ14QL5BLyIR0ecZuw+mJjz78jD4f+VmCBpwhfMKpegOKvW5d1Ryry15jCJBMMGWztdDU3COPi+hfxXve8QiqmE0Rg1UMbkGgqMHOSU0clHMlHIf/Vl08wVN9zCiB8BNp1FOf6wSZDo9kSg04tB7f2V5OaEDC5APdeQu/T/cNd9UTQ66Xq0fRqy0U7f0B88MjedrCklnRqJViZ4KG5ieBnM1JANJHOjLh4XDHtp27LqSGZ0Hb3RBRg4H9BSMXj0VSLVw== 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: Jeff Xu Add selftest to mremap across VMA boundaries, i.e. mremap will fail. Signed-off-by: Jeff Xu --- tools/testing/selftests/mm/mseal_test.c | 293 +++++++++++++++++++++++- 1 file changed, 292 insertions(+), 1 deletion(-) diff --git a/tools/testing/selftests/mm/mseal_test.c b/tools/testing/selftests/mm/mseal_test.c index 5bce2fe102ab..422cf90fb56c 100644 --- a/tools/testing/selftests/mm/mseal_test.c +++ b/tools/testing/selftests/mm/mseal_test.c @@ -1482,6 +1482,47 @@ static void test_seal_mremap_move_dontunmap_anyaddr(bool seal) REPORT_TEST_PASS(); } +static void test_seal_mremap_move_dontunmap_allocated(bool seal) +{ + void *ptr, *ptr2; + unsigned long page_size = getpagesize(); + unsigned long size = 4 * page_size; + int ret; + void *ret2; + + setup_single_address(size, &ptr); + FAIL_TEST_IF_FALSE(ptr != (void *)-1); + + if (seal) { + ret = sys_mseal(ptr, size); + FAIL_TEST_IF_FALSE(!ret); + } + + /* + * The new address is allocated. + */ + setup_single_address(size, &ptr2); + FAIL_TEST_IF_FALSE(ptr2 != (void *)-1); + + /* + * remap to allocated address. + */ + ret2 = sys_mremap(ptr, size, size, MREMAP_MAYMOVE | MREMAP_DONTUNMAP, + (void *) ptr2); + if (seal) { + FAIL_TEST_IF_FALSE(ret2 == MAP_FAILED); + FAIL_TEST_IF_FALSE(errno == EPERM); + } else { + /* remap success and but it won't be ptr2 */ + FAIL_TEST_IF_FALSE(!(ret2 == MAP_FAILED)); + FAIL_TEST_IF_FALSE(ret2 != ptr2); + } + + REPORT_TEST_PASS(); +} + + + static void test_seal_merge_and_split(void) { void *ptr; @@ -1746,6 +1787,239 @@ static void test_seal_discard_ro_anon(bool seal) REPORT_TEST_PASS(); } +static void test_seal_mremap_shrink_multiple_vmas(bool seal) +{ + void *ptr; + unsigned long page_size = getpagesize(); + unsigned long size = 12 * page_size; + int ret; + void *ret2; + int prot; + + setup_single_address(size, &ptr); + FAIL_TEST_IF_FALSE(ptr != (void *)-1); + + ret = sys_mprotect(ptr + 4 * page_size, 4 * page_size, PROT_NONE); + FAIL_TEST_IF_FALSE(!ret); + + size = get_vma_size(ptr, &prot); + FAIL_TEST_IF_FALSE(size == 4 * page_size); + + size = get_vma_size(ptr + 4 * page_size, &prot); + FAIL_TEST_IF_FALSE(size == 4 * page_size); + + if (seal) { + ret = sys_mseal(ptr + 4 * page_size, 4 * page_size); + FAIL_TEST_IF_FALSE(!ret); + } + + ret2 = sys_mremap(ptr, 12 * page_size, 6 * page_size, 0, 0); + if (seal) { + FAIL_TEST_IF_FALSE(ret2 == (void *) MAP_FAILED); + FAIL_TEST_IF_FALSE(errno == EPERM); + + size = get_vma_size(ptr, &prot); + FAIL_TEST_IF_FALSE(size == 4 * page_size); + FAIL_TEST_IF_FALSE(prot == 0x4); + + size = get_vma_size(ptr + 4 * page_size, &prot); + FAIL_TEST_IF_FALSE(size == 4 * page_size); + FAIL_TEST_IF_FALSE(prot == 0x0); + } else { + FAIL_TEST_IF_FALSE(ret2 == ptr); + + size = get_vma_size(ptr, &prot); + FAIL_TEST_IF_FALSE(size == 4 * page_size); + + size = get_vma_size(ptr + 4 * page_size, &prot); + FAIL_TEST_IF_FALSE(size == 2 * page_size); + } + + REPORT_TEST_PASS(); +} + +static void test_seal_mremap_expand_multiple_vmas(bool seal) +{ + void *ptr; + unsigned long page_size = getpagesize(); + unsigned long size = 12 * page_size; + int ret; + void *ret2; + int prot; + + setup_single_address(size, &ptr); + FAIL_TEST_IF_FALSE(ptr != (void *)-1); + + ret = sys_mprotect(ptr + 4 * page_size, 4 * page_size, PROT_NONE); + FAIL_TEST_IF_FALSE(!ret); + + /* ummap last 4 pages. */ + ret = sys_munmap(ptr + 8 * page_size, 4 * page_size); + FAIL_TEST_IF_FALSE(!ret); + + size = get_vma_size(ptr, &prot); + FAIL_TEST_IF_FALSE(size == 4 * page_size); + + size = get_vma_size(ptr + 4 * page_size, &prot); + FAIL_TEST_IF_FALSE(size == 4 * page_size); + + if (seal) { + ret = sys_mseal(ptr + 4 * page_size, 4 * page_size); + FAIL_TEST_IF_FALSE(!ret); + } + + ret2 = sys_mremap(ptr, 8 * page_size, 12 * page_size, 0, 0); + if (seal) { + FAIL_TEST_IF_FALSE(ret2 == (void *) MAP_FAILED); + + size = get_vma_size(ptr, &prot); + FAIL_TEST_IF_FALSE(size == 4 * page_size); + FAIL_TEST_IF_FALSE(prot == 0x4); + + size = get_vma_size(ptr + 4 * page_size, &prot); + FAIL_TEST_IF_FALSE(size == 4 * page_size); + FAIL_TEST_IF_FALSE(prot == 0x0); + } else { + FAIL_TEST_IF_FALSE(ret2 == (void *) MAP_FAILED); + + size = get_vma_size(ptr, &prot); + FAIL_TEST_IF_FALSE(size == 4 * page_size); + + size = get_vma_size(ptr + 4 * page_size, &prot); + FAIL_TEST_IF_FALSE(size == 4 * page_size); + + } + + REPORT_TEST_PASS(); +} + +static void test_seal_mremap_move_expand_multiple_vmas(bool seal) +{ + void *ptr; + unsigned long page_size = getpagesize(); + unsigned long size = 12 * page_size; + int ret; + void *ret2; + int prot; + void *ptr2; + + setup_single_address(size, &ptr); + FAIL_TEST_IF_FALSE(ptr != (void *)-1); + + setup_single_address(size, &ptr2); + FAIL_TEST_IF_FALSE(ptr2 != (void *)-1); + + ret = sys_munmap(ptr2, 12 * page_size); + FAIL_TEST_IF_FALSE(!ret); + + ret = sys_mprotect(ptr + 4 * page_size, 4 * page_size, PROT_NONE); + FAIL_TEST_IF_FALSE(!ret); + + /* ummap last 4 pages. */ + ret = sys_munmap(ptr + 8 * page_size, 4 * page_size); + FAIL_TEST_IF_FALSE(!ret); + + size = get_vma_size(ptr, &prot); + FAIL_TEST_IF_FALSE(size == 4 * page_size); + + size = get_vma_size(ptr + 4 * page_size, &prot); + FAIL_TEST_IF_FALSE(size == 4 * page_size); + + if (seal) { + ret = sys_mseal(ptr + 4 * page_size, 4 * page_size); + FAIL_TEST_IF_FALSE(!ret); + } + + /* move and expand cross VMA boundary will fail */ + ret2 = sys_mremap(ptr, 8 * page_size, 10 * page_size, MREMAP_FIXED | MREMAP_MAYMOVE, ptr2); + if (seal) { + FAIL_TEST_IF_FALSE(ret2 == (void *) MAP_FAILED); + + size = get_vma_size(ptr, &prot); + FAIL_TEST_IF_FALSE(size == 4 * page_size); + FAIL_TEST_IF_FALSE(prot == 0x4); + + size = get_vma_size(ptr + 4 * page_size, &prot); + FAIL_TEST_IF_FALSE(size == 4 * page_size); + FAIL_TEST_IF_FALSE(prot == 0x0); + } else { + FAIL_TEST_IF_FALSE(ret2 == (void *) MAP_FAILED); + + size = get_vma_size(ptr, &prot); + FAIL_TEST_IF_FALSE(size == 4 * page_size); + FAIL_TEST_IF_FALSE(prot == 0x4); + + size = get_vma_size(ptr + 4 * page_size, &prot); + FAIL_TEST_IF_FALSE(size == 4 * page_size); + FAIL_TEST_IF_FALSE(prot == 0x0); + } + + REPORT_TEST_PASS(); +} + +static void test_seal_mremap_move_shrink_multiple_vmas(bool seal) +{ + void *ptr; + unsigned long page_size = getpagesize(); + unsigned long size = 12 * page_size; + int ret; + void *ret2; + int prot; + void *ptr2; + + setup_single_address(size, &ptr); + FAIL_TEST_IF_FALSE(ptr != (void *)-1); + + setup_single_address(size, &ptr2); + FAIL_TEST_IF_FALSE(ptr2 != (void *)-1); + + ret = sys_munmap(ptr2, 12 * page_size); + FAIL_TEST_IF_FALSE(!ret); + + ret = sys_mprotect(ptr + 4 * page_size, 4 * page_size, PROT_NONE); + FAIL_TEST_IF_FALSE(!ret); + + size = get_vma_size(ptr, &prot); + FAIL_TEST_IF_FALSE(size == 4 * page_size); + FAIL_TEST_IF_FALSE(prot == 4); + + size = get_vma_size(ptr + 4 * page_size, &prot); + FAIL_TEST_IF_FALSE(size == 4 * page_size); + FAIL_TEST_IF_FALSE(prot == 0); + + if (seal) { + ret = sys_mseal(ptr + 4 * page_size, 4 * page_size); + FAIL_TEST_IF_FALSE(!ret); + } + + /* move and shrink cross VMA boundary is NOK */ + ret2 = sys_mremap(ptr, 12 * page_size, 8 * page_size, MREMAP_FIXED | MREMAP_MAYMOVE, ptr2); + if (seal) { + FAIL_TEST_IF_FALSE(ret2 == (void *) MAP_FAILED); + //FAIL_TEST_IF_FALSE(errno == EPERM); + + size = get_vma_size(ptr, &prot); + FAIL_TEST_IF_FALSE(size == 4 * page_size); + FAIL_TEST_IF_FALSE(prot == 4); + + size = get_vma_size(ptr + 4 * page_size, &prot); + FAIL_TEST_IF_FALSE(size == 4 * page_size); + FAIL_TEST_IF_FALSE(prot == 0); + } else { + FAIL_TEST_IF_FALSE(ret2 == (void *) MAP_FAILED); + + size = get_vma_size(ptr, &prot); + FAIL_TEST_IF_FALSE(size == 4 * page_size); + FAIL_TEST_IF_FALSE(prot == 4); + + size = get_vma_size(ptr + 4 * page_size, &prot); + FAIL_TEST_IF_FALSE(size == 4 * page_size); + FAIL_TEST_IF_FALSE(prot == 0); + } + + REPORT_TEST_PASS(); +} + int main(int argc, char **argv) { bool test_seal = seal_support(); @@ -1758,7 +2032,7 @@ int main(int argc, char **argv) if (!pkey_supported()) ksft_print_msg("PKEY not supported\n"); - ksft_set_plan(80); + ksft_set_plan(91); test_seal_addseal(); test_seal_unmapped_start(); @@ -1835,8 +2109,12 @@ int main(int argc, char **argv) test_seal_mremap_move_dontunmap(true); test_seal_mremap_move_fixed_zero(false); test_seal_mremap_move_fixed_zero(true); + test_seal_mremap_move_dontunmap_anyaddr(false); test_seal_mremap_move_dontunmap_anyaddr(true); + test_seal_mremap_move_dontunmap_allocated(false); + test_seal_mremap_move_dontunmap_allocated(true); + test_seal_discard_ro_anon(false); test_seal_discard_ro_anon(true); test_seal_discard_ro_anon_on_rw(false); @@ -1858,5 +2136,18 @@ int main(int argc, char **argv) test_seal_discard_ro_anon_on_pkey(false); test_seal_discard_ro_anon_on_pkey(true); + test_seal_mremap_shrink_multiple_vmas(false); + test_seal_mremap_shrink_multiple_vmas(true); + + test_seal_mremap_expand_multiple_vmas(false); + test_seal_mremap_expand_multiple_vmas(true); + + test_seal_mremap_move_expand_multiple_vmas(false); + + test_seal_mremap_move_expand_multiple_vmas(false); + test_seal_mremap_move_expand_multiple_vmas(true); + test_seal_mremap_move_shrink_multiple_vmas(false); + test_seal_mremap_move_shrink_multiple_vmas(true); + ksft_finished(); } From patchwork Wed Aug 14 07:14:24 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeff Xu X-Patchwork-Id: 13762915 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 179AFC3DA4A for ; Wed, 14 Aug 2024 07:14:39 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id C95CA6B0083; Wed, 14 Aug 2024 03:14:38 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id C200F6B0088; Wed, 14 Aug 2024 03:14:38 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 9FBFE6B008A; Wed, 14 Aug 2024 03:14:38 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0013.hostedemail.com [216.40.44.13]) by kanga.kvack.org (Postfix) with ESMTP id 7AB4B6B0083 for ; Wed, 14 Aug 2024 03:14:38 -0400 (EDT) Received: from smtpin17.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay03.hostedemail.com (Postfix) with ESMTP id 21096A0CD2 for ; Wed, 14 Aug 2024 07:14:38 +0000 (UTC) X-FDA: 82449988236.17.3ED19CA Received: from mail-oa1-f46.google.com (mail-oa1-f46.google.com [209.85.160.46]) by imf07.hostedemail.com (Postfix) with ESMTP id 48D6C4000E for ; Wed, 14 Aug 2024 07:14:36 +0000 (UTC) Authentication-Results: imf07.hostedemail.com; dkim=pass header.d=chromium.org header.s=google header.b="ogdg/s42"; spf=pass (imf07.hostedemail.com: domain of jeffxu@chromium.org designates 209.85.160.46 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=1723619605; 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=PPWWQwyyMYzOiADy+Um6ftzlEsZpYIENXIqV4xwjKPk=; b=3tRkMJXXYziMWZJd+ryD2IpcDZU16mK10/4UIoRxoUrRx0z/WE2NtDgl57sDpLUgdiWiAS 13Cl9NzLwMu+15zXpyKMKX3E8W0fq9r/vRFFNe7d6Svmh82yq4FEjuJ4paOrHJbTpw+umW 4x9GN2V2ct9Iz3CmHsPDu0RNU4HmTOk= ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1723619605; a=rsa-sha256; cv=none; b=Ab4WGcA4UZpM8H37EOl3A+3PZr4hVIq04p4VottOatdwOKjxu2hqJCHWCx42i4nLJyzZIm Bxhz1N0ANJWoM9h01L/kUCCHDDO2FQX3RGuCyabPGKihmEwMSayW4foU5EN3DxaIRwamEJ Ztg284UbNn54jeee08nVvi4Fszo21lg= ARC-Authentication-Results: i=1; imf07.hostedemail.com; dkim=pass header.d=chromium.org header.s=google header.b="ogdg/s42"; spf=pass (imf07.hostedemail.com: domain of jeffxu@chromium.org designates 209.85.160.46 as permitted sender) smtp.mailfrom=jeffxu@chromium.org; dmarc=pass (policy=none) header.from=chromium.org Received: by mail-oa1-f46.google.com with SMTP id 586e51a60fabf-26ff21d8382so101361fac.1 for ; Wed, 14 Aug 2024 00:14:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1723619675; x=1724224475; 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=PPWWQwyyMYzOiADy+Um6ftzlEsZpYIENXIqV4xwjKPk=; b=ogdg/s42DF7SEt1txpXCjgI6sHSccyZbbufdMAM0LGsDU4VqjXHCvDCJruHweyjruW EWLymFB0Tbyas0kYrZeYzvLwFcXzbOuP4HjwrYESZ8buWW0IJRQTwfsbZ+gxlLCbBo8k 98aGC7reCJ1mos5ahjKG/KZhBPSUMTDTcAfT0= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1723619675; x=1724224475; 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=PPWWQwyyMYzOiADy+Um6ftzlEsZpYIENXIqV4xwjKPk=; b=MQiUVjELzASLHl6YpUBjj170Lsmgw/FLdRxg8n5BTmFpETLewTlVJz3ovG3Qd7+0bE jDrLndtLrDtfa29ZZfurJY36+vC4AfYsMKBX7ea5QD1JlGLXE6RGhtUkDhPT3qEci5gZ O7goKd8o3a6Aj3qTfy/pnkbB9WQRlhSoUXjWllGa197HH2SkQLT1mQIOzm29FBwf0NVZ B8geQthQW6XAnmSnOlI79gXuiKH/fQdfc+gjvZVsx4F0wwl0mIH7KOdGBCJo0Khg88HT 5VPIK/HgV+Ak3rDrhQ2RtUoBmCfSDpTImBEeRjr8hoibQo1k62Or13rSQO7w4Din1t8u 278w== X-Forwarded-Encrypted: i=1; AJvYcCVB1p/eDqjMmaDKKLrprvZf0mXBv52P/jjSkE0jXIKlV1+6079/IhmyoSjDmgR3NRs39yMtfRMeAQ==@kvack.org X-Gm-Message-State: AOJu0Yz2KllEg8CkAwacg8ksSBOe80YQj4vWO5ksJ5YK3Kz60M9jf/if yPSQsEwvu7zGMqolksYeMffSM9CHaD5BSk0iqoZ2BLYM/YayM6R0gcG1uQHtQ3MRRDUzmgnaRVw = X-Google-Smtp-Source: AGHT+IE6JfJPxPtoC8Uw6welRiHqjOl4qLH95nS8kNG0C9/2C8BlFRDSZOxp1j99zGbCvMk19tkN6A== X-Received: by 2002:a05:6871:520d:b0:261:7b0:9d66 with SMTP id 586e51a60fabf-26fe5c8313fmr1892557fac.50.1723619674941; Wed, 14 Aug 2024 00:14:34 -0700 (PDT) Received: from localhost (150.12.83.34.bc.googleusercontent.com. [34.83.12.150]) by smtp.gmail.com with UTF8SMTPSA id d2e1a72fcca58-710e5873086sm6727529b3a.20.2024.08.14.00.14.34 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Wed, 14 Aug 2024 00:14:34 -0700 (PDT) From: jeffxu@chromium.org To: akpm@linux-foundation.org, willy@infradead.org, torvalds@linux-foundation.org, Liam.Howlett@oracle.com, pedro.falcato@gmail.com Cc: linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-mm@kvack.org, linux-hardening@vger.kernel.org, jeffxu@google.com, lorenzo.stoakes@oracle.com, mpe@ellerman.id.au, oliver.sang@intel.com, vbabka@suse.cz, keescook@chromium.org, Jeff Xu Subject: [PATCH v1 2/2] mseal: refactor mremap to remove can_modify_mm Date: Wed, 14 Aug 2024 07:14:24 +0000 Message-ID: <20240814071424.2655666-3-jeffxu@chromium.org> X-Mailer: git-send-email 2.46.0.76.ge559c4bf1a-goog In-Reply-To: <20240814071424.2655666-1-jeffxu@chromium.org> References: <20240814071424.2655666-1-jeffxu@chromium.org> MIME-Version: 1.0 X-Rspamd-Queue-Id: 48D6C4000E X-Stat-Signature: pek6g1yjwetkjftxib8ggbpxe46rkdcn X-Rspamd-Server: rspam09 X-Rspam-User: X-HE-Tag: 1723619676-33720 X-HE-Meta: U2FsdGVkX18T5iTSrVFi7YwDkNgaipqnjbhiHZ5tcaLp6v6XPxohXafG4tBqloeM6iHJYqyOxXvgxyi7vJduU6vCaxCL4yqmLfkbxH7D0m8aNe28lTnq75KPyGegLbtLpcIwA6y5CHMg55LmiFMd8TH8ZgywlKiuWd8TOutbMaNvdL2JSxCLvB4x8qetL6/TtHQEjqQxxGwUUl39ezbfmaNpi39RjnoO/VRRSJvnPtBXbppW0gV4kA3cinxKcyK2lQAZo1QTbtFdKciRv92fg/+vS2bAVtnNmoGswAFJJwdFtwGyzVpS7+ydfkKLLyZrU7Q15ttvjiSAnQkAmRx6c1vtdQ6bttK8Ec37xP5va5h8whIykPS8A1bI3nQuRh49wkXDSrCKS36CFCmk05FsSgF7GVIMGvJnt6utPuImgo1zJ+dsTGIjNxMq+lv8sZvh8egDdq1tLq13MD5XEwLtxvX7vH8/uh7AWqkqJk2VJ4C/CRxhzPF4W6qR3BXXn3QcKOiuhk1iEZPJGgxhCEE8vMI3XI40TYRVxn6eupIV8m3d1hOu9j5eSx3KY7bvIqko++mMBExSfVpLVmtT6e5rzpdJRir1SwWTuR1e4hT/FVXaAMwZslRH0f3HhnELA6hK9a3Ae55E2t1NwH4aO9OXfnOowl5BwkhIXvPFhxDAlXvdbLzdhsaa9Srn12/kjxnTVEDNCuLUZ4UeVZ1+qJ1Nf+JuxIvydI5Tq9FDGFkI+2XnGzyIdPjYrTzBoNN2WUm8l0N7MN41VyHyj6si8QVyuk0DTCBdWfst1euJM/wKBBQ80K5DkAuO4KkVRutYV9b1LMBupDcqw8M8CYZHCsLNlJKd61wqlfeNx4GO/biM3idMZkem3FX/svRGkkzREGa6P1Hai4ihh7vjfqOfnc5b/BeSknMuFhWaRCSEm9xBzxaCiThmiYXXF1aOGQkAoX/eQLcJr4RcfOqJMn7iXLO PNG4keCC S3YYcnjhbQpYsssl147R5aj5mGZvyjVvBZ8jdu71B6KlR6lBQg/NzH1Q2X1DXILXAzLclHIOJfk1+jeGEsrrDfUZi+lNbXyqmfPsBknzDLa64jO1cRbIm5cIwL9wxYt+kGeRmzNUyMgVW/YKHRXPuQdh38G2kYJv5ra6sNGtVFeZT9Gaey/Kb8MSDXFth3+pVkQ1mRWzj8xRsgtnospewzX3wrA6LaMMatR8vWc+8XVNFRlmPjjeka9GT3YP0Ma7/n5TsfIsvmUsAMYHixmYsIUIQZ7rRia5PISWF8rLoE0CZplBf5OEqE34is7nBG/vC4w5L9Ha907wozNXxkTdi0aG2u0jfw9iXrJ6fOXuh7ZNuW8/PRGCvdLgwHhaFyAxnaqMwgaXGu6fo+p8= 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: Jeff Xu mremap doesn't allow relocate, expand, shrink across VMA boundaries, refactor the code to check src address range before doing anything on the destination. This also allow we remove can_modify_mm from mremap, since the src address must be single VMA, use can_modify_vma instead. Signed-off-by: Jeff Xu --- mm/internal.h | 24 ++++++++++++++++ mm/mremap.c | 77 +++++++++++++++++++++++++-------------------------- mm/mseal.c | 17 ------------ 3 files changed, 61 insertions(+), 57 deletions(-) diff --git a/mm/internal.h b/mm/internal.h index b4d86436565b..53f0bbbc6449 100644 --- a/mm/internal.h +++ b/mm/internal.h @@ -1501,6 +1501,24 @@ bool can_modify_mm(struct mm_struct *mm, unsigned long start, unsigned long end); bool can_modify_mm_madv(struct mm_struct *mm, unsigned long start, unsigned long end, int behavior); + +static inline bool vma_is_sealed(struct vm_area_struct *vma) +{ + return (vma->vm_flags & VM_SEALED); +} + +/* + * check if a vma is sealed for modification. + * return true, if modification is allowed. + */ +static inline bool can_modify_vma(struct vm_area_struct *vma) +{ + if (unlikely(vma_is_sealed(vma))) + return false; + + return true; +} + #else static inline int can_do_mseal(unsigned long flags) { @@ -1518,6 +1536,12 @@ static inline bool can_modify_mm_madv(struct mm_struct *mm, unsigned long start, { return true; } + +static inline bool can_modify_vma(struct vm_area_struct *vma) +{ + return true; +} + #endif #ifdef CONFIG_SHRINKER_DEBUG diff --git a/mm/mremap.c b/mm/mremap.c index e7ae140fc640..3c5bb671a280 100644 --- a/mm/mremap.c +++ b/mm/mremap.c @@ -904,28 +904,7 @@ static unsigned long mremap_to(unsigned long addr, unsigned long old_len, /* * In mremap_to(). - * Move a VMA to another location, check if src addr is sealed. - * - * Place can_modify_mm here because mremap_to() - * does its own checking for address range, and we only - * check the sealing after passing those checks. - * - * can_modify_mm assumes we have acquired the lock on MM. */ - if (unlikely(!can_modify_mm(mm, addr, addr + old_len))) - return -EPERM; - - if (flags & MREMAP_FIXED) { - /* - * In mremap_to(). - * VMA is moved to dst address, and munmap dst first. - * do_munmap will check if dst is sealed. - */ - ret = do_munmap(mm, new_addr, new_len, uf_unmap_early); - if (ret) - goto out; - } - if (old_len > new_len) { ret = do_munmap(mm, addr+new_len, old_len - new_len, uf_unmap); if (ret) @@ -939,6 +918,26 @@ static unsigned long mremap_to(unsigned long addr, unsigned long old_len, goto out; } + /* + * Since we can't remap across vma boundaries, + * check single vma instead of src address range. + */ + if (unlikely(!can_modify_vma(vma))) { + ret = -EPERM; + goto out; + } + + if (flags & MREMAP_FIXED) { + /* + * In mremap_to(). + * VMA is moved to dst address, and munmap dst first. + * do_munmap will check if dst is sealed. + */ + ret = do_munmap(mm, new_addr, new_len, uf_unmap_early); + if (ret) + goto out; + } + /* MREMAP_DONTUNMAP expands by old_len since old_len == new_len */ if (flags & MREMAP_DONTUNMAP && !may_expand_vm(mm, vma->vm_flags, old_len >> PAGE_SHIFT)) { @@ -1079,19 +1078,6 @@ SYSCALL_DEFINE5(mremap, unsigned long, addr, unsigned long, old_len, goto out; } - /* - * Below is shrink/expand case (not mremap_to()) - * Check if src address is sealed, if so, reject. - * In other words, prevent shrinking or expanding a sealed VMA. - * - * Place can_modify_mm here so we can keep the logic related to - * shrink/expand together. - */ - if (unlikely(!can_modify_mm(mm, addr, addr + old_len))) { - ret = -EPERM; - goto out; - } - /* * Always allow a shrinking remap: that just unmaps * the unnecessary pages.. @@ -1107,7 +1093,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); if (ret) goto out; @@ -1124,6 +1110,15 @@ SYSCALL_DEFINE5(mremap, unsigned long, addr, unsigned long, old_len, goto out; } + /* + * Since we can't remap across vma boundaries, + * check single vma instead of src address range. + */ + if (unlikely(!can_modify_vma(vma))) { + ret = -EPERM; + goto out; + } + /* old_len exactly to the end of the area.. */ if (old_len == vma->vm_end - addr) { @@ -1132,9 +1127,10 @@ SYSCALL_DEFINE5(mremap, unsigned long, addr, unsigned long, old_len, /* can we just expand the current mapping? */ if (vma_expandable(vma, delta)) { long pages = delta >> PAGE_SHIFT; - VMA_ITERATOR(vmi, mm, vma->vm_end); long charged = 0; + VMA_ITERATOR(vmi, mm, vma->vm_end); + if (vma->vm_flags & VM_ACCOUNT) { if (security_vm_enough_memory_mm(mm, pages)) { ret = -ENOMEM; @@ -1177,20 +1173,21 @@ SYSCALL_DEFINE5(mremap, unsigned long, addr, unsigned long, old_len, ret = -ENOMEM; if (flags & MREMAP_MAYMOVE) { unsigned long map_flags = 0; + if (vma->vm_flags & VM_MAYSHARE) map_flags |= MAP_SHARED; new_addr = get_unmapped_area(vma->vm_file, 0, new_len, - vma->vm_pgoff + - ((addr - vma->vm_start) >> PAGE_SHIFT), - map_flags); + vma->vm_pgoff + + ((addr - vma->vm_start) >> PAGE_SHIFT), + map_flags); if (IS_ERR_VALUE(new_addr)) { ret = new_addr; goto out; } ret = move_vma(vma, addr, old_len, new_len, new_addr, - &locked, flags, &uf, &uf_unmap); + &locked, flags, &uf, &uf_unmap); } out: if (offset_in_page(ret)) diff --git a/mm/mseal.c b/mm/mseal.c index bf783bba8ed0..4591ae8d29c2 100644 --- a/mm/mseal.c +++ b/mm/mseal.c @@ -16,28 +16,11 @@ #include #include "internal.h" -static inline bool vma_is_sealed(struct vm_area_struct *vma) -{ - return (vma->vm_flags & VM_SEALED); -} - static inline void set_vma_sealed(struct vm_area_struct *vma) { vm_flags_set(vma, VM_SEALED); } -/* - * check if a vma is sealed for modification. - * return true, if modification is allowed. - */ -static bool can_modify_vma(struct vm_area_struct *vma) -{ - if (unlikely(vma_is_sealed(vma))) - return false; - - return true; -} - static bool is_madv_discard(int behavior) { return behavior &