From nobody Sun Feb 8 13:13:19 2026 Received: from mail-pl1-f181.google.com (mail-pl1-f181.google.com [209.85.214.181]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id F312E13AD18 for ; Wed, 14 Aug 2024 07:14:33 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.181 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723619675; cv=none; b=KIQQmNAfTlDjQCzTUDHjaViQqu2LuAAjjLlZT2bPGteeFsSm1PnhO8B/r04q7zfitGZQwSf66I462fVLhJ0IUl2lJ871Fk3HpJjZXe8eRI6N1QyqthVdFikck0YNuZCMO00LrUI5zKW7o5daxZxKjCWVL7K69GPKy5wCPZfXv3k= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723619675; c=relaxed/simple; bh=FRw/jHn6ln5li8Cdyej4UuVStctKPxXfcZyK1aqevDk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=IENgMRV7vpP74OoGQt3NtoBXztWyPItbr2Hm5ooifTdSuS8+BkD3YgvrSDeCdBi3jaWF652hnjJS99rnT3A4YVF7Jf3A0RIQszqHdMd4eWa1H/ApOXN1LKYkAUMmn6n8u/Z8Gc1mlrI7vKeinf2VhO9SlVXgRJas7tNqCgpQ1hs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org; spf=pass smtp.mailfrom=chromium.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b=FtONhJ90; arc=none smtp.client-ip=209.85.214.181 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=chromium.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="FtONhJ90" Received: by mail-pl1-f181.google.com with SMTP id d9443c01a7336-1fc4fccdd78so46059245ad.2 for ; Wed, 14 Aug 2024 00:14:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1723619673; x=1724224473; darn=vger.kernel.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=FtONhJ90ux546tajtU0yzxkPIxbzPyhJqPCxp/XulcWDOyG+ZqZINtcrSaBRyurtKI gDNVktFTs0p5sKZX7sse+h4IDVCHOimqSToZSv7igZ7pZh7UwgdU24kcPZGeSjLUyo89 t6x2xbjBL5TcmA+jD7xO+sUxTdbi+ZHUJsinQ= 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=vZ0Uwk2UtMLocZze13fdfnq+VNVfPxKyTt8R9esU6KdtkDAbXZ9UG0QIWHnrL4DAyI 1tJcNaeQt3ppCujO/uuzaBvCEuszTPbyRVni+ttMWDWxppoD5BbW/oMtb/u+AWZpXcV9 VcLTPjImUaQB6arKTz9syh5izxUE/qj1iV3HmWgldFTOBvEgM8yqwHEFEM2zmC8Cclm4 Izu1q/ET/mrgMAzpM4y7VqwSpCExB2aDY1oP60nlEpNPlUK8CMkTfhDvXdAiBElsIULZ 7oTqKcBw/gbsAQQPfuhD5J7PU3NcCvaJgd3vv0rXOeyPZau6VLcUsRwOUHtg3uGM6RhS MGKw== X-Gm-Message-State: AOJu0Yyvb4bQw5jZM0CMgC93k1y/U2MFk/3uuuCuEMmJTZ6d1/PPOxW3 8Wk9G95XbxRkuhYVLysUWy5WNmGEhEqr5BRTRyvKDQ+0tkMdruJhU4tpSZh9Gg== 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> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 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/selfte= sts/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(); } =20 +static void test_seal_mremap_move_dontunmap_allocated(bool seal) +{ + void *ptr, *ptr2; + unsigned long page_size =3D getpagesize(); + unsigned long size =3D 4 * page_size; + int ret; + void *ret2; + + setup_single_address(size, &ptr); + FAIL_TEST_IF_FALSE(ptr !=3D (void *)-1); + + if (seal) { + ret =3D sys_mseal(ptr, size); + FAIL_TEST_IF_FALSE(!ret); + } + + /* + * The new address is allocated. + */ + setup_single_address(size, &ptr2); + FAIL_TEST_IF_FALSE(ptr2 !=3D (void *)-1); + + /* + * remap to allocated address. + */ + ret2 =3D sys_mremap(ptr, size, size, MREMAP_MAYMOVE | MREMAP_DONTUNMAP, + (void *) ptr2); + if (seal) { + FAIL_TEST_IF_FALSE(ret2 =3D=3D MAP_FAILED); + FAIL_TEST_IF_FALSE(errno =3D=3D EPERM); + } else { + /* remap success and but it won't be ptr2 */ + FAIL_TEST_IF_FALSE(!(ret2 =3D=3D MAP_FAILED)); + FAIL_TEST_IF_FALSE(ret2 !=3D 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(); } =20 +static void test_seal_mremap_shrink_multiple_vmas(bool seal) +{ + void *ptr; + unsigned long page_size =3D getpagesize(); + unsigned long size =3D 12 * page_size; + int ret; + void *ret2; + int prot; + + setup_single_address(size, &ptr); + FAIL_TEST_IF_FALSE(ptr !=3D (void *)-1); + + ret =3D sys_mprotect(ptr + 4 * page_size, 4 * page_size, PROT_NONE); + FAIL_TEST_IF_FALSE(!ret); + + size =3D get_vma_size(ptr, &prot); + FAIL_TEST_IF_FALSE(size =3D=3D 4 * page_size); + + size =3D get_vma_size(ptr + 4 * page_size, &prot); + FAIL_TEST_IF_FALSE(size =3D=3D 4 * page_size); + + if (seal) { + ret =3D sys_mseal(ptr + 4 * page_size, 4 * page_size); + FAIL_TEST_IF_FALSE(!ret); + } + + ret2 =3D sys_mremap(ptr, 12 * page_size, 6 * page_size, 0, 0); + if (seal) { + FAIL_TEST_IF_FALSE(ret2 =3D=3D (void *) MAP_FAILED); + FAIL_TEST_IF_FALSE(errno =3D=3D EPERM); + + size =3D get_vma_size(ptr, &prot); + FAIL_TEST_IF_FALSE(size =3D=3D 4 * page_size); + FAIL_TEST_IF_FALSE(prot =3D=3D 0x4); + + size =3D get_vma_size(ptr + 4 * page_size, &prot); + FAIL_TEST_IF_FALSE(size =3D=3D 4 * page_size); + FAIL_TEST_IF_FALSE(prot =3D=3D 0x0); + } else { + FAIL_TEST_IF_FALSE(ret2 =3D=3D ptr); + + size =3D get_vma_size(ptr, &prot); + FAIL_TEST_IF_FALSE(size =3D=3D 4 * page_size); + + size =3D get_vma_size(ptr + 4 * page_size, &prot); + FAIL_TEST_IF_FALSE(size =3D=3D 2 * page_size); + } + + REPORT_TEST_PASS(); +} + +static void test_seal_mremap_expand_multiple_vmas(bool seal) +{ + void *ptr; + unsigned long page_size =3D getpagesize(); + unsigned long size =3D 12 * page_size; + int ret; + void *ret2; + int prot; + + setup_single_address(size, &ptr); + FAIL_TEST_IF_FALSE(ptr !=3D (void *)-1); + + ret =3D sys_mprotect(ptr + 4 * page_size, 4 * page_size, PROT_NONE); + FAIL_TEST_IF_FALSE(!ret); + + /* ummap last 4 pages. */ + ret =3D sys_munmap(ptr + 8 * page_size, 4 * page_size); + FAIL_TEST_IF_FALSE(!ret); + + size =3D get_vma_size(ptr, &prot); + FAIL_TEST_IF_FALSE(size =3D=3D 4 * page_size); + + size =3D get_vma_size(ptr + 4 * page_size, &prot); + FAIL_TEST_IF_FALSE(size =3D=3D 4 * page_size); + + if (seal) { + ret =3D sys_mseal(ptr + 4 * page_size, 4 * page_size); + FAIL_TEST_IF_FALSE(!ret); + } + + ret2 =3D sys_mremap(ptr, 8 * page_size, 12 * page_size, 0, 0); + if (seal) { + FAIL_TEST_IF_FALSE(ret2 =3D=3D (void *) MAP_FAILED); + + size =3D get_vma_size(ptr, &prot); + FAIL_TEST_IF_FALSE(size =3D=3D 4 * page_size); + FAIL_TEST_IF_FALSE(prot =3D=3D 0x4); + + size =3D get_vma_size(ptr + 4 * page_size, &prot); + FAIL_TEST_IF_FALSE(size =3D=3D 4 * page_size); + FAIL_TEST_IF_FALSE(prot =3D=3D 0x0); + } else { + FAIL_TEST_IF_FALSE(ret2 =3D=3D (void *) MAP_FAILED); + + size =3D get_vma_size(ptr, &prot); + FAIL_TEST_IF_FALSE(size =3D=3D 4 * page_size); + + size =3D get_vma_size(ptr + 4 * page_size, &prot); + FAIL_TEST_IF_FALSE(size =3D=3D 4 * page_size); + + } + + REPORT_TEST_PASS(); +} + +static void test_seal_mremap_move_expand_multiple_vmas(bool seal) +{ + void *ptr; + unsigned long page_size =3D getpagesize(); + unsigned long size =3D 12 * page_size; + int ret; + void *ret2; + int prot; + void *ptr2; + + setup_single_address(size, &ptr); + FAIL_TEST_IF_FALSE(ptr !=3D (void *)-1); + + setup_single_address(size, &ptr2); + FAIL_TEST_IF_FALSE(ptr2 !=3D (void *)-1); + + ret =3D sys_munmap(ptr2, 12 * page_size); + FAIL_TEST_IF_FALSE(!ret); + + ret =3D sys_mprotect(ptr + 4 * page_size, 4 * page_size, PROT_NONE); + FAIL_TEST_IF_FALSE(!ret); + + /* ummap last 4 pages. */ + ret =3D sys_munmap(ptr + 8 * page_size, 4 * page_size); + FAIL_TEST_IF_FALSE(!ret); + + size =3D get_vma_size(ptr, &prot); + FAIL_TEST_IF_FALSE(size =3D=3D 4 * page_size); + + size =3D get_vma_size(ptr + 4 * page_size, &prot); + FAIL_TEST_IF_FALSE(size =3D=3D 4 * page_size); + + if (seal) { + ret =3D sys_mseal(ptr + 4 * page_size, 4 * page_size); + FAIL_TEST_IF_FALSE(!ret); + } + + /* move and expand cross VMA boundary will fail */ + ret2 =3D sys_mremap(ptr, 8 * page_size, 10 * page_size, MREMAP_FIXED | MR= EMAP_MAYMOVE, ptr2); + if (seal) { + FAIL_TEST_IF_FALSE(ret2 =3D=3D (void *) MAP_FAILED); + + size =3D get_vma_size(ptr, &prot); + FAIL_TEST_IF_FALSE(size =3D=3D 4 * page_size); + FAIL_TEST_IF_FALSE(prot =3D=3D 0x4); + + size =3D get_vma_size(ptr + 4 * page_size, &prot); + FAIL_TEST_IF_FALSE(size =3D=3D 4 * page_size); + FAIL_TEST_IF_FALSE(prot =3D=3D 0x0); + } else { + FAIL_TEST_IF_FALSE(ret2 =3D=3D (void *) MAP_FAILED); + + size =3D get_vma_size(ptr, &prot); + FAIL_TEST_IF_FALSE(size =3D=3D 4 * page_size); + FAIL_TEST_IF_FALSE(prot =3D=3D 0x4); + + size =3D get_vma_size(ptr + 4 * page_size, &prot); + FAIL_TEST_IF_FALSE(size =3D=3D 4 * page_size); + FAIL_TEST_IF_FALSE(prot =3D=3D 0x0); + } + + REPORT_TEST_PASS(); +} + +static void test_seal_mremap_move_shrink_multiple_vmas(bool seal) +{ + void *ptr; + unsigned long page_size =3D getpagesize(); + unsigned long size =3D 12 * page_size; + int ret; + void *ret2; + int prot; + void *ptr2; + + setup_single_address(size, &ptr); + FAIL_TEST_IF_FALSE(ptr !=3D (void *)-1); + + setup_single_address(size, &ptr2); + FAIL_TEST_IF_FALSE(ptr2 !=3D (void *)-1); + + ret =3D sys_munmap(ptr2, 12 * page_size); + FAIL_TEST_IF_FALSE(!ret); + + ret =3D sys_mprotect(ptr + 4 * page_size, 4 * page_size, PROT_NONE); + FAIL_TEST_IF_FALSE(!ret); + + size =3D get_vma_size(ptr, &prot); + FAIL_TEST_IF_FALSE(size =3D=3D 4 * page_size); + FAIL_TEST_IF_FALSE(prot =3D=3D 4); + + size =3D get_vma_size(ptr + 4 * page_size, &prot); + FAIL_TEST_IF_FALSE(size =3D=3D 4 * page_size); + FAIL_TEST_IF_FALSE(prot =3D=3D 0); + + if (seal) { + ret =3D sys_mseal(ptr + 4 * page_size, 4 * page_size); + FAIL_TEST_IF_FALSE(!ret); + } + + /* move and shrink cross VMA boundary is NOK */ + ret2 =3D sys_mremap(ptr, 12 * page_size, 8 * page_size, MREMAP_FIXED | MR= EMAP_MAYMOVE, ptr2); + if (seal) { + FAIL_TEST_IF_FALSE(ret2 =3D=3D (void *) MAP_FAILED); + //FAIL_TEST_IF_FALSE(errno =3D=3D EPERM); + + size =3D get_vma_size(ptr, &prot); + FAIL_TEST_IF_FALSE(size =3D=3D 4 * page_size); + FAIL_TEST_IF_FALSE(prot =3D=3D 4); + + size =3D get_vma_size(ptr + 4 * page_size, &prot); + FAIL_TEST_IF_FALSE(size =3D=3D 4 * page_size); + FAIL_TEST_IF_FALSE(prot =3D=3D 0); + } else { + FAIL_TEST_IF_FALSE(ret2 =3D=3D (void *) MAP_FAILED); + + size =3D get_vma_size(ptr, &prot); + FAIL_TEST_IF_FALSE(size =3D=3D 4 * page_size); + FAIL_TEST_IF_FALSE(prot =3D=3D 4); + + size =3D get_vma_size(ptr + 4 * page_size, &prot); + FAIL_TEST_IF_FALSE(size =3D=3D 4 * page_size); + FAIL_TEST_IF_FALSE(prot =3D=3D 0); + } + + REPORT_TEST_PASS(); +} + int main(int argc, char **argv) { bool test_seal =3D seal_support(); @@ -1758,7 +2032,7 @@ int main(int argc, char **argv) if (!pkey_supported()) ksft_print_msg("PKEY not supported\n"); =20 - ksft_set_plan(80); + ksft_set_plan(91); =20 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); =20 + 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(); } --=20 2.46.0.76.ge559c4bf1a-goog From nobody Sun Feb 8 13:13:19 2026 Received: from mail-oi1-f174.google.com (mail-oi1-f174.google.com [209.85.167.174]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0767713C9A3 for ; Wed, 14 Aug 2024 07:14:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.167.174 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723619677; cv=none; b=QmRmX9ElIYnVITHYIPjMK4vLOE74ASRPG23dvLbhv/1Onkv+56ALE8VMJbGox76VdTfzeiGQXPwYstQ73ogBhsoZAAZ27aNmMhqAvkQ7nYcyCToB3RTiK6tWUQlkuLV7/UuLvu4JAR7ttmgbY6mujeQNznU9eSy/CwpPDIKp8Ig= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723619677; c=relaxed/simple; bh=jH2VLByoCj65CKES9JuT0zu4kckdjVLERAHfZHiVcds=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=fJvUq86yvFVfGfyL+yMDdMvCBhF10/0MCRj2fUSTwi50a9eu+re+7+4CqaL+jtlI9tiJxhv1IVzwym/vUwYQeJv+iZ3XWiOn9551Lo1S9JbcnJB4YP5wClFMuuxR2RIajKQHPnFWNiwbpxV2FOxZOOynDHLLtoxan/5WV40Bu0I= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org; spf=pass smtp.mailfrom=chromium.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b=hYlcTzK9; arc=none smtp.client-ip=209.85.167.174 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=chromium.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="hYlcTzK9" Received: by mail-oi1-f174.google.com with SMTP id 5614622812f47-3db1e21b0e4so4341309b6e.2 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=vger.kernel.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=hYlcTzK9R2h12sw/AU7fpQD/UxgPjMBUzSbgt8OC0zHz5l2HQZ5U9QHtfHJ8e/5Oj0 6tujrpSGveXK6oY4Kg1akq2E6LPAmkNG3nruktKFhF/qizSAGxt2Dz3cl6VAODQfNhtz Qx2TXncCh6+tKbVQbdEw6V14LRXz9x+tSgS9U= 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=W5bWeHTuApxDEWJh385ycFfnC3Hl1bhJecjZMkvVeqVEI1p65D8uZs+2Mx0Gkh7Hw0 OIxzwpxqnGJ0LpFZlelqx/yLbPWRxYDYO5ISqsAY35z9yLC6GkZvQwrFYC/M5lM32pB5 nKK13FTDe/4pzGY4fgDCAiiNhpq+mrRe0SOTA/LUlQt5836NI3PvSHrZxwA3SUllGg6Y 3NCkx5QL/xqCHQ1CG4N5UGV00DIM6W6bNJS4dwnDRq0CT7ERiUTHT9cNG681hy68ZIbL d1lqI31O8xSEubNJYGeB8Xt5cG15spiBY7lY3GTqFxt+AxgFnAZXHMg5ocRNVx8P00rj qxXg== X-Gm-Message-State: AOJu0YzUbbkB4NrH9k5YGxnaFvS7QpC81ZR+rZ0s95HdczDgf7OhzGAH gWh8zPKXRiXycWuKL0Ayj73QK2zWSN5PwvC4wF+uDcnxf9CrOhnnniOWiHuImw== 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> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 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 lo= ng 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_stru= ct *mm, unsigned long start, { return true; } + +static inline bool can_modify_vma(struct vm_area_struct *vma) +{ + return true; +} + #endif =20 #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, uns= igned long old_len, =20 /* * 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 =3D do_munmap(mm, new_addr, new_len, uf_unmap_early); - if (ret) - goto out; - } - if (old_len > new_len) { ret =3D 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, uns= igned long old_len, goto out; } =20 + /* + * Since we can't remap across vma boundaries, + * check single vma instead of src address range. + */ + if (unlikely(!can_modify_vma(vma))) { + ret =3D -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 =3D do_munmap(mm, new_addr, new_len, uf_unmap_early); + if (ret) + goto out; + } + /* MREMAP_DONTUNMAP expands by old_len since old_len =3D=3D 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, unsigne= d long, old_len, goto out; } =20 - /* - * 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 =3D -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, } =20 ret =3D do_vmi_munmap(&vmi, mm, addr + new_len, old_len - new_len, - &uf_unmap, true); + &uf_unmap, true); if (ret) goto out; =20 @@ -1124,6 +1110,15 @@ SYSCALL_DEFINE5(mremap, unsigned long, addr, unsigne= d long, old_len, goto out; } =20 + /* + * Since we can't remap across vma boundaries, + * check single vma instead of src address range. + */ + if (unlikely(!can_modify_vma(vma))) { + ret =3D -EPERM; + goto out; + } + /* old_len exactly to the end of the area.. */ if (old_len =3D=3D vma->vm_end - addr) { @@ -1132,9 +1127,10 @@ SYSCALL_DEFINE5(mremap, unsigned long, addr, unsigne= d long, old_len, /* can we just expand the current mapping? */ if (vma_expandable(vma, delta)) { long pages =3D delta >> PAGE_SHIFT; - VMA_ITERATOR(vmi, mm, vma->vm_end); long charged =3D 0; =20 + VMA_ITERATOR(vmi, mm, vma->vm_end); + if (vma->vm_flags & VM_ACCOUNT) { if (security_vm_enough_memory_mm(mm, pages)) { ret =3D -ENOMEM; @@ -1177,20 +1173,21 @@ SYSCALL_DEFINE5(mremap, unsigned long, addr, unsign= ed long, old_len, ret =3D -ENOMEM; if (flags & MREMAP_MAYMOVE) { unsigned long map_flags =3D 0; + if (vma->vm_flags & VM_MAYSHARE) map_flags |=3D MAP_SHARED; =20 new_addr =3D 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 =3D new_addr; goto out; } =20 ret =3D 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" =20 -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); } =20 -/* - * 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 & --=20 2.46.0.76.ge559c4bf1a-goog