Linux Security Modules development
 help / color / mirror / Atom feed
* Re: [LTP] [PATCH v3 2/2] syscalls/cma: Handle Yama ptrace_scope in tests
       [not found] ` <20261020-fix_process_vm_writev_permissions-v3-2-1e92d7a29aef@suse.com>
@ 2026-11-05 17:44   ` Petr Vorel
  0 siblings, 0 replies; only message in thread
From: Petr Vorel @ 2026-11-05 17:44 UTC (permalink / raw)
  To: Andrea Cervesato; +Cc: Linux Test Project, linux-security-module

Hi Andrea,

[ Cc Yama list ]

thanks merged.

Kind regards,
Petr

> From: Andrea Cervesato <andrea.cervesato@suse.com>

> With Yama LSM enabled, process_vm_readv() and process_vm_writev() fail
> with EPERM when a sibling process accesses the target's memory.

> Let the target child declare its parent as ptracer, so that mode 1
> works for unprivileged users too. Require CAP_SYS_PTRACE for mode 2
> and skip on mode 3, where access is never allowed.

> Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
> ---
>  testcases/kernel/syscalls/cma/cma.h                | 38 ++++++++++++++++++++++
>  testcases/kernel/syscalls/cma/process_vm_readv02.c |  5 +++
>  testcases/kernel/syscalls/cma/process_vm_readv03.c |  5 +++
>  .../kernel/syscalls/cma/process_vm_writev02.c      |  5 +++
>  4 files changed, 53 insertions(+)

> diff --git a/testcases/kernel/syscalls/cma/cma.h b/testcases/kernel/syscalls/cma/cma.h
> new file mode 100644
> index 000000000..6636cb5a3
> --- /dev/null
> +++ b/testcases/kernel/syscalls/cma/cma.h
> @@ -0,0 +1,38 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Copyright (C) 2026 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com>
> + */
> +
> +#ifndef CMA_H__
> +#define CMA_H__
> +
> +#include <sys/prctl.h>
> +#include "tst_test.h"
> +#include "tst_capability.h"
> +
> +#define PTRACE_SCOPE "/proc/sys/kernel/yama/ptrace_scope"
> +
> +static inline void cma_check_ptrace_scope(void)
> +{
> +	struct tst_cap cap = TST_CAP(TST_CAP_REQ, CAP_SYS_PTRACE);
> +	int scope;
> +
> +	if (access(PTRACE_SCOPE, F_OK))
> +		return;
> +
> +	SAFE_FILE_SCANF(PTRACE_SCOPE, "%d", &scope);
> +
> +	if (scope >= 3)
> +		tst_brk(TCONF, "Yama ptrace_scope=%d forbids process_vm_*()", scope);
> +
> +	if (scope == 2)
> +		tst_cap_action(&cap);
> +}
> +
> +static inline void cma_allow_parent_ptracer(void)
> +{
> +	if (prctl(PR_SET_PTRACER, getppid(), 0, 0, 0) && errno != EINVAL)
> +		tst_brk(TBROK | TERRNO, "prctl(PR_SET_PTRACER)");
> +}
> +
> +#endif /* CMA_H__ */
> diff --git a/testcases/kernel/syscalls/cma/process_vm_readv02.c b/testcases/kernel/syscalls/cma/process_vm_readv02.c
> index 1e2ac38fa..ceff77e29 100644
> --- a/testcases/kernel/syscalls/cma/process_vm_readv02.c
> +++ b/testcases/kernel/syscalls/cma/process_vm_readv02.c
> @@ -17,6 +17,7 @@
>  #include <sys/wait.h>
>  #include "tst_test.h"
>  #include "lapi/syscalls.h"
> +#include "cma.h"

>  static uintptr_t *data_ptr;

> @@ -29,6 +30,8 @@ static void child_alloc(const char *data)

>  	tst_res(TINFO, "child 0: memory allocated and initialized");

> +	cma_allow_parent_ptracer();
> +
>  	/* wake and wait until child_invoke is done reading from our VM */
>  	TST_CHECKPOINT_WAKE_AND_WAIT(0);
>  }
> @@ -64,6 +67,8 @@ static void setup(void)
>  	/* Just a sanity check of the existence of syscall */
>  	tst_syscall(__NR_process_vm_readv, getpid(), NULL, 0UL, NULL, 0UL, 0UL);

> +	cma_check_ptrace_scope();
> +
>  	data_ptr = SAFE_MMAP(NULL, sizeof(uintptr_t), PROT_READ | PROT_WRITE,
>  						 MAP_SHARED | MAP_ANONYMOUS, -1, 0);
>  }
> diff --git a/testcases/kernel/syscalls/cma/process_vm_readv03.c b/testcases/kernel/syscalls/cma/process_vm_readv03.c
> index 95d35c422..831f79c89 100644
> --- a/testcases/kernel/syscalls/cma/process_vm_readv03.c
> +++ b/testcases/kernel/syscalls/cma/process_vm_readv03.c
> @@ -20,6 +20,7 @@
>  #include <sys/wait.h>
>  #include "tst_test.h"
>  #include "lapi/syscalls.h"
> +#include "cma.h"

>  #define MAX_IOVECS 1024

> @@ -80,6 +81,8 @@ static void child_alloc(const int *sizes, int nr_iovecs)

>  	tst_res(TINFO, "child_alloc: memory allocated and initialized");

> +	cma_allow_parent_ptracer();
> +
>  	TST_CHECKPOINT_WAKE_AND_WAIT(0);
>  }

> @@ -139,6 +142,8 @@ static void setup(void)
>  {
>  	tst_syscall(__NR_process_vm_readv, getpid(), NULL, 0UL, NULL, 0UL, 0UL);

> +	cma_check_ptrace_scope();
> +
>  	data_ptr = SAFE_MMAP(NULL, sizeof(void *) * MAX_IOVECS, PROT_READ | PROT_WRITE,
>  			     MAP_SHARED | MAP_ANONYMOUS, -1, 0);
>  }
> diff --git a/testcases/kernel/syscalls/cma/process_vm_writev02.c b/testcases/kernel/syscalls/cma/process_vm_writev02.c
> index 15bd66a44..78b98200f 100644
> --- a/testcases/kernel/syscalls/cma/process_vm_writev02.c
> +++ b/testcases/kernel/syscalls/cma/process_vm_writev02.c
> @@ -16,6 +16,7 @@
>  #include <sys/uio.h>
>  #include "tst_test.h"
>  #include "lapi/syscalls.h"
> +#include "cma.h"

>  static uintptr_t *data_ptr;
>  static char *str_buffsize;
> @@ -33,6 +34,8 @@ static void child_alloc_and_verify(int buffsize)
>  	memset(foo, 'a', buffsize);
>  	*data_ptr = (uintptr_t)foo;

> +	cma_allow_parent_ptracer();
> +
>  	TST_CHECKPOINT_WAKE_AND_WAIT(0);

>  	err = 0;
> @@ -81,6 +84,8 @@ static void setup(void)
>  	if (tst_parse_int(str_buffsize, &bufsize, 1, INT_MAX))
>  		tst_brk(TBROK, "Invalid buffer size '%s'", str_buffsize);

> +	cma_check_ptrace_scope();
> +
>  	data_ptr = SAFE_MMAP(NULL, sizeof(uintptr_t), PROT_READ | PROT_WRITE,
>  			     MAP_SHARED | MAP_ANONYMOUS, -1, 0);
>  }

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2026-11-05 17:44 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <20261020-fix_process_vm_writev_permissions-v3-0-1e92d7a29aef@suse.com>
     [not found] ` <20261020-fix_process_vm_writev_permissions-v3-2-1e92d7a29aef@suse.com>
2026-11-05 17:44   ` [LTP] [PATCH v3 2/2] syscalls/cma: Handle Yama ptrace_scope in tests Petr Vorel

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox