mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Muhammad Usama Anjum <usama.anjum@collabora.com>
To: jeffxu@chromium.org
Cc: Muhammad Usama Anjum <usama.anjum@collabora.com>,
	jeffxu@google.com, jorgelo@chromium.org, groeck@chromium.org,
	jannh@google.com, linux-kernel@vger.kernel.org,
	linux-kselftest@vger.kernel.org, linux-mm@kvack.org,
	willy@infradead.org, pedro.falcato@gmail.com,
	keescook@chromium.org, dave.hansen@intel.com,
	gregkh@linuxfoundation.org, linux-hardening@vger.kernel.org,
	deraadt@openbsd.org, akpm@linux-foundation.org,
	torvalds@linux-foundation.org, sroettger@google.com
Subject: Re: [RFC PATCH v3 10/11] selftest mm/mseal memory sealing
Date: Sun, 31 Dec 2023 11:39:43 +0500	[thread overview]
Message-ID: <45cc343e-f727-4cd5-b688-9a60a87875c8@collabora.com> (raw)
In-Reply-To: <20231212231706.2680890-11-jeffxu@chromium.org>

I wasn't CC-ed on the patch even though I'd reviewed the earlier revision.


On 12/13/23 4:17 AM, jeffxu@chromium.org wrote:
> From: Jeff Xu <jeffxu@chromium.org>
> 
> selftest for memory sealing change in mmap() and mseal().
> 
> Signed-off-by: Jeff Xu <jeffxu@chromium.org>
> ---
>  tools/testing/selftests/mm/.gitignore   |    1 +
>  tools/testing/selftests/mm/Makefile     |    1 +
>  tools/testing/selftests/mm/config       |    1 +
>  tools/testing/selftests/mm/mseal_test.c | 2141 +++++++++++++++++++++++
>  4 files changed, 2144 insertions(+)
>  create mode 100644 tools/testing/selftests/mm/mseal_test.c
> 
> diff --git a/tools/testing/selftests/mm/.gitignore b/tools/testing/selftests/mm/.gitignore
> index cdc9ce4426b9..f0f22a649985 100644
> --- a/tools/testing/selftests/mm/.gitignore
> +++ b/tools/testing/selftests/mm/.gitignore
> @@ -43,3 +43,4 @@ mdwe_test
>  gup_longterm
>  mkdirty
>  va_high_addr_switch
> +mseal_test
> diff --git a/tools/testing/selftests/mm/Makefile b/tools/testing/selftests/mm/Makefile
> index 6a9fc5693145..0c086cecc093 100644
> --- a/tools/testing/selftests/mm/Makefile
> +++ b/tools/testing/selftests/mm/Makefile
> @@ -59,6 +59,7 @@ TEST_GEN_FILES += mlock2-tests
>  TEST_GEN_FILES += mrelease_test
>  TEST_GEN_FILES += mremap_dontunmap
>  TEST_GEN_FILES += mremap_test
> +TEST_GEN_FILES += mseal_test
>  TEST_GEN_FILES += on-fault-limit
>  TEST_GEN_FILES += thuge-gen
>  TEST_GEN_FILES += transhuge-stress
> diff --git a/tools/testing/selftests/mm/config b/tools/testing/selftests/mm/config
> index be087c4bc396..cf2b8780e9b1 100644
> --- a/tools/testing/selftests/mm/config
> +++ b/tools/testing/selftests/mm/config
> @@ -6,3 +6,4 @@ CONFIG_TEST_HMM=m
>  CONFIG_GUP_TEST=y
>  CONFIG_TRANSPARENT_HUGEPAGE=y
>  CONFIG_MEM_SOFT_DIRTY=y
> +CONFIG_MSEAL=y
> diff --git a/tools/testing/selftests/mm/mseal_test.c b/tools/testing/selftests/mm/mseal_test.c
> new file mode 100644
> index 000000000000..0692485d8b3c
> --- /dev/null
> +++ b/tools/testing/selftests/mm/mseal_test.c
> @@ -0,0 +1,2141 @@
> +// SPDX-License-Identifier: GPL-2.0
> +#define _GNU_SOURCE
> +#include <sys/mman.h>
> +#include <stdint.h>
> +#include <unistd.h>
> +#include <string.h>
> +#include <sys/time.h>
> +#include <sys/resource.h>
> +#include <stdbool.h>
> +#include "../kselftest.h"
> +#include <syscall.h>
> +#include <errno.h>
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <assert.h>
> +#include <fcntl.h>
> +#include <assert.h>
> +#include <sys/ioctl.h>
> +#include <sys/vfs.h>
> +#include <sys/stat.h>
> +
> +/*
> + * need those definition for manually build using gcc.
> + * gcc -I ../../../../usr/include   -DDEBUG -O3  -DDEBUG -O3 mseal_test.c -o mseal_test
> + */
> +#ifndef MM_SEAL_SEAL
> +#define MM_SEAL_SEAL 0x1
> +#endif
> +
> +#ifndef MM_SEAL_BASE
> +#define MM_SEAL_BASE 0x2
> +#endif
> +
> +#ifndef MM_SEAL_PROT_PKEY
> +#define MM_SEAL_PROT_PKEY 0x4
> +#endif
> +
> +#ifndef MM_SEAL_DISCARD_RO_ANON
> +#define MM_SEAL_DISCARD_RO_ANON 0x8
> +#endif
> +
> +#ifndef MAP_SEALABLE
> +#define MAP_SEALABLE 0x8000000
> +#endif
> +
> +#ifndef PROT_SEAL_SEAL
> +#define PROT_SEAL_SEAL 0x04000000
> +#endif
> +
> +#ifndef PROT_SEAL_BASE
> +#define PROT_SEAL_BASE 0x08000000
> +#endif
> +
> +#ifndef PROT_SEAL_PROT_PKEY
> +#define PROT_SEAL_PROT_PKEY 0x10000000
> +#endif
> +
> +#ifndef PROT_SEAL_DISCARD_RO_ANON
> +#define PROT_SEAL_DISCARD_RO_ANON 0x20000000
> +#endif
> +
> +#ifndef PKEY_DISABLE_ACCESS
> +# define PKEY_DISABLE_ACCESS    0x1
> +#endif
> +
> +#ifndef PKEY_DISABLE_WRITE
> +# define PKEY_DISABLE_WRITE     0x2
> +#endif
> +
> +#ifndef PKEY_BITS_PER_KEY
> +#define PKEY_BITS_PER_PKEY      2
> +#endif
> +
> +#ifndef PKEY_MASK
> +#define PKEY_MASK       (PKEY_DISABLE_ACCESS | PKEY_DISABLE_WRITE)
> +#endif
> +
> +#ifndef DEBUG
> +#define LOG_TEST_ENTER()	{}
> +#else
> +#define LOG_TEST_ENTER()	{ksft_print_msg("%s\n", __func__); }
> +#endif
> +
> +#ifndef u64
> +#define u64 unsigned long long
> +#endif
> +
> +/*
> + * define sys_xyx to call syscall directly.
> + */
> +static int sys_mseal(void *start, size_t len, int types)
> +{
> +	int sret;
> +
> +	errno = 0;
> +	sret = syscall(__NR_mseal, start, len, types, 0);
> +	return sret;
> +}
> +
> +int sys_mprotect(void *ptr, size_t size, unsigned long prot)
> +{
> +	int sret;
> +
> +	errno = 0;
> +	sret = syscall(SYS_mprotect, ptr, size, prot);
> +	return sret;
> +}
> +
> +int sys_mprotect_pkey(void *ptr, size_t size, unsigned long orig_prot,
> +		unsigned long pkey)
> +{
> +	int sret;
> +
> +	errno = 0;
> +	sret = syscall(__NR_pkey_mprotect, ptr, size, orig_prot, pkey);
> +	return sret;
> +}
> +
> +int sys_munmap(void *ptr, size_t size)
> +{
> +	int sret;
> +
> +	errno = 0;
> +	sret = syscall(SYS_munmap, ptr, size);
> +	return sret;
> +}
> +
> +static int sys_madvise(void *start, size_t len, int types)
> +{
> +	int sret;
> +
> +	errno = 0;
> +	sret = syscall(__NR_madvise, start, len, types);
> +	return sret;
> +}
> +
> +int sys_pkey_alloc(unsigned long flags, unsigned long init_val)
> +{
> +	int ret = syscall(SYS_pkey_alloc, flags, init_val);
Add empty line here.

> +	return ret;
> +}
> +
> +static inline unsigned int __read_pkey_reg(void)
> +{
> +	unsigned int eax, edx;
> +	unsigned int ecx = 0;
> +	unsigned int pkey_reg;
> +
> +	asm volatile(".byte 0x0f,0x01,0xee\n\t"
> +			: "=a" (eax), "=d" (edx)
> +			: "c" (ecx));
> +	pkey_reg = eax;
> +	return pkey_reg;
> +}
> +
> +static inline void __write_pkey_reg(u64 pkey_reg)
> +{
> +	unsigned int eax = pkey_reg;
> +	unsigned int ecx = 0;
> +	unsigned int edx = 0;
> +
> +	asm volatile(".byte 0x0f,0x01,0xef\n\t"
> +			: : "a" (eax), "c" (ecx), "d" (edx));
> +	assert(pkey_reg == __read_pkey_reg());
> +}
> +
> +static inline unsigned long pkey_bit_position(int pkey)
> +{
> +	return pkey * PKEY_BITS_PER_PKEY;
> +}
> +
> +static inline u64 set_pkey_bits(u64 reg, int pkey, u64 flags)
> +{
> +	unsigned long shift = pkey_bit_position(pkey);
> +	/* mask out bits from pkey in old value */
> +	reg &= ~((u64)PKEY_MASK << shift);
> +	/* OR in new bits for pkey */
> +	reg |= (flags & PKEY_MASK) << shift;
> +	return reg;
> +}
> +
> +static inline void set_pkey(int pkey, unsigned long pkey_value)
> +{
> +	unsigned long mask = (PKEY_DISABLE_ACCESS | PKEY_DISABLE_WRITE);
> +	u64 new_pkey_reg;
> +
> +	assert(!(pkey_value & ~mask));
> +	new_pkey_reg = set_pkey_bits(__read_pkey_reg(), pkey, pkey_value);
> +	__write_pkey_reg(new_pkey_reg);
> +}
> +
> +void setup_single_address(int size, void **ptrOut)
> +{
> +	void *ptr;
> +
> +	ptr = mmap(NULL, size, PROT_READ, MAP_ANONYMOUS | MAP_PRIVATE | MAP_SEALABLE, -1, 0);
> +	assert(ptr != (void *)-1);
> +	*ptrOut = ptr;
> +}
> +
> +void setup_single_address_sealable(int size, void **ptrOut, bool sealable)
> +{
> +	void *ptr;
> +	unsigned long mapflags = MAP_ANONYMOUS | MAP_PRIVATE;
> +
> +	if (sealable)
> +		mapflags |= MAP_SEALABLE;
> +
> +	ptr = mmap(NULL, size, PROT_READ, mapflags, -1, 0);
> +	assert(ptr != (void *)-1);
> +	*ptrOut = ptr;
> +}
> +
> +void setup_single_address_rw_sealable(int size, void **ptrOut, bool sealable)
> +{
> +	void *ptr;
> +	unsigned long mapflags = MAP_ANONYMOUS | MAP_PRIVATE;
> +
> +	if (sealable)
> +		mapflags |= MAP_SEALABLE;
> +
> +	ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, mapflags, -1, 0);
> +	assert(ptr != (void *)-1);
> +	*ptrOut = ptr;
> +}
> +
> +void clean_single_address(void *ptr, int size)
> +{
> +	int ret;
> +
> +	ret = munmap(ptr, size);
> +	assert(!ret);
> +}
> +
> +void seal_mprotect_single_address(void *ptr, int size)
> +{
> +	int ret;
> +
> +	ret = sys_mseal(ptr, size, MM_SEAL_PROT_PKEY);
> +	assert(!ret);
> +}
> +
> +void seal_discard_ro_anon_single_address(void *ptr, int size)
> +{
> +	int ret;
> +
> +	ret = sys_mseal(ptr, size, MM_SEAL_DISCARD_RO_ANON);
> +	assert(!ret);
> +}
> +
> +static void test_seal_addseals(void)
> +{
> +	LOG_TEST_ENTER();
> +	int ret;
> +	void *ptr;
> +	unsigned long page_size = getpagesize();
> +	unsigned long size = 4 * page_size;
> +
> +	setup_single_address(size, &ptr);
> +
> +	/* adding seal one by one */
> +
> +	ret = sys_mseal(ptr, size, MM_SEAL_BASE);
> +	assert(!ret);
> +	ret = sys_mseal(ptr, size, MM_SEAL_PROT_PKEY);
> +	assert(!ret);
> +	ret = sys_mseal(ptr, size, MM_SEAL_SEAL);
> +	assert(!ret);
> +}
> +
> +static void test_seal_addseals_combined(void)
> +{
> +	LOG_TEST_ENTER();
> +	int ret;
> +	void *ptr;
> +	unsigned long page_size = getpagesize();
> +	unsigned long size = 4 * page_size;
> +
> +	setup_single_address(size, &ptr);
> +
> +	ret = sys_mseal(ptr, size, MM_SEAL_PROT_PKEY);
> +	assert(!ret);
> +
> +	/* adding multiple seals */
> +	ret = sys_mseal(ptr, size,
> +			MM_SEAL_PROT_PKEY | MM_SEAL_BASE|
> +			MM_SEAL_SEAL);
> +	assert(!ret);
> +
> +	/* not adding more seal type, so ok. */
> +	ret = sys_mseal(ptr, size, MM_SEAL_BASE);
> +	assert(!ret);
> +
> +	/* not adding more seal type, so ok. */
> +	ret = sys_mseal(ptr, size, MM_SEAL_SEAL);
> +	assert(!ret);
> +}
> +
> +static void test_seal_addseals_reject(void)
> +{
> +	LOG_TEST_ENTER();
> +	int ret;
> +	void *ptr;
> +	unsigned long page_size = getpagesize();
> +	unsigned long size = 4 * page_size;
> +
> +	setup_single_address(size, &ptr);
> +
> +	ret = sys_mseal(ptr, size, MM_SEAL_BASE | MM_SEAL_SEAL);
> +	assert(!ret);
> +
> +	/* MM_SEAL_SEAL is set, so not allow new seal type . */
> +	ret = sys_mseal(ptr, size,
> +			MM_SEAL_PROT_PKEY | MM_SEAL_BASE | MM_SEAL_SEAL);
> +	assert(ret < 0);
> +}
> +
> +static void test_seal_unmapped_start(void)
> +{
> +	LOG_TEST_ENTER();
> +	int ret;
> +	void *ptr;
> +	unsigned long page_size = getpagesize();
> +	unsigned long size = 4 * page_size;
> +
> +	setup_single_address(size, &ptr);
> +
> +	// munmap 2 pages from ptr.
Don't use different commenting styles in one file. Use /* */ for comments.

> +	ret = sys_munmap(ptr, 2 * page_size);
> +	assert(!ret);
> +
> +	// mprotect will fail because 2 pages from ptr are unmapped.
> +	ret = sys_mprotect(ptr, size, PROT_READ | PROT_WRITE);
> +	assert(ret < 0);
> +
> +	// mseal will fail because 2 pages from ptr are unmapped.
> +	ret = sys_mseal(ptr, size, MM_SEAL_SEAL);
> +	assert(ret < 0);
> +
> +	ret = sys_mseal(ptr + 2 * page_size, 2 * page_size, MM_SEAL_SEAL);
> +	assert(!ret);
> +}
> +

  reply	other threads:[~2023-12-31  6:39 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-12-12 23:16 [RFC PATCH v3 00/11] Introduce mseal() jeffxu
2023-12-12 23:16 ` [RFC PATCH v3 01/11] mseal: Add mseal syscall jeffxu
2023-12-13  7:24   ` Greg KH
2023-12-12 23:16 ` [RFC PATCH v3 02/11] mseal: Wire up " jeffxu
2023-12-12 23:16 ` [RFC PATCH v3 03/11] mseal: add can_modify_mm and can_modify_vma jeffxu
2023-12-12 23:16 ` [RFC PATCH v3 04/11] mseal: add MM_SEAL_BASE jeffxu
2023-12-12 23:16 ` [RFC PATCH v3 05/11] mseal: add MM_SEAL_PROT_PKEY jeffxu
2023-12-12 23:17 ` [RFC PATCH v3 06/11] mseal: add sealing support for mmap jeffxu
2023-12-12 23:17 ` [RFC PATCH v3 07/11] mseal: make sealed VMA mergeable jeffxu
2023-12-12 23:17 ` [RFC PATCH v3 08/11] mseal: add MM_SEAL_DISCARD_RO_ANON jeffxu
2023-12-12 23:17 ` [RFC PATCH v3 09/11] mseal: add MAP_SEALABLE to mmap() jeffxu
2023-12-12 23:17 ` [RFC PATCH v3 10/11] selftest mm/mseal memory sealing jeffxu
2023-12-31  6:39   ` Muhammad Usama Anjum [this message]
2023-12-12 23:17 ` [RFC PATCH v3 11/11] mseal:add documentation jeffxu
2023-12-13  0:39   ` Linus Torvalds
2023-12-14  0:35     ` Jeff Xu
2023-12-14  1:09       ` Theo de Raadt
2023-12-14  1:31       ` Linus Torvalds
2023-12-14 18:06         ` Stephen Röttger
2023-12-14 20:11           ` Pedro Falcato
2023-12-14 20:14           ` Linus Torvalds
2023-12-14 22:52             ` Jeff Xu
2024-01-20 15:23               ` Theo de Raadt
2024-01-20 16:40                 ` Linus Torvalds
2024-01-20 16:59                   ` Theo de Raadt
2024-01-21  0:16                   ` Jeff Xu
2024-01-21  0:43                     ` Theo de Raadt
2023-12-14 15:04       ` Theo de Raadt

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=45cc343e-f727-4cd5-b688-9a60a87875c8@collabora.com \
    --to=usama.anjum@collabora.com \
    --cc=akpm@linux-foundation.org \
    --cc=dave.hansen@intel.com \
    --cc=deraadt@openbsd.org \
    --cc=gregkh@linuxfoundation.org \
    --cc=groeck@chromium.org \
    --cc=jannh@google.com \
    --cc=jeffxu@chromium.org \
    --cc=jeffxu@google.com \
    --cc=jorgelo@chromium.org \
    --cc=keescook@chromium.org \
    --cc=linux-hardening@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-kselftest@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=pedro.falcato@gmail.com \
    --cc=sroettger@google.com \
    --cc=torvalds@linux-foundation.org \
    --cc=willy@infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®