[LTP] [PATCH v6] Add EPERM test for clone and clone3
Li Wang
liwang@redhat.com
Wed Nov 19 09:40:09 CET 2025
On Wed, Nov 19, 2025 at 6:29 AM Stephen Bertram via ltp <ltp@lists.linux.it>
wrote:
> Confirming EPERM is returned when CAP_SYS_ADMIN is
> removed from clone and clone3.
> And for clone3 the set_tid_size is greater than 0.
>
> Signed-off-by: Stephen Bertram <sbertram@redhat.com>
> ---
> runtest/syscalls | 2 +
> testcases/kernel/syscalls/clone/.gitignore | 1 +
> testcases/kernel/syscalls/clone/clone11.c | 74 +++++++++++++++++
> testcases/kernel/syscalls/clone3/.gitignore | 1 +
> testcases/kernel/syscalls/clone3/clone304.c | 92 +++++++++++++++++++++
> 5 files changed, 170 insertions(+)
> create mode 100644 testcases/kernel/syscalls/clone/clone11.c
> create mode 100644 testcases/kernel/syscalls/clone3/clone304.c
>
> diff --git a/runtest/syscalls b/runtest/syscalls
> index 54d94c0ca..a1ef7548b 100644
> --- a/runtest/syscalls
> +++ b/runtest/syscalls
> @@ -124,10 +124,12 @@ clone07 clone07
> clone08 clone08
> clone09 clone09
> clone10 clone10
> +clone11 clone11
>
> clone301 clone301
> clone302 clone302
> clone303 clone303
> +clone304 clone304
>
> close01 close01
> close02 close02
> diff --git a/testcases/kernel/syscalls/clone/.gitignore
> b/testcases/kernel/syscalls/clone/.gitignore
> index adfb8257d..0edcfef5d 100644
> --- a/testcases/kernel/syscalls/clone/.gitignore
> +++ b/testcases/kernel/syscalls/clone/.gitignore
> @@ -8,3 +8,4 @@
> /clone08
> /clone09
> /clone10
> +/clone11
> diff --git a/testcases/kernel/syscalls/clone/clone11.c
> b/testcases/kernel/syscalls/clone/clone11.c
> new file mode 100644
> index 000000000..e0ae9db62
> --- /dev/null
> +++ b/testcases/kernel/syscalls/clone/clone11.c
> @@ -0,0 +1,74 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Copyright (c) 2025 Stephen Bertram <sbertram@redhat.com>
> + */
> +
> +/*\
> + * This test verifies that :man2:`clone` fails with EPERM when
> CAP_SYS_ADMIN
> + * has been dropped.
> + */
> +
> +#define _GNU_SOURCE
> +#define DESC(x) .flags = x, .sflags = #x
> +
> +#include "tst_test.h"
> +#include "clone_platform.h"
> +#include "lapi/sched.h"
> +
> +static void *child_stack;
> +static int *child_pid;
> +
> +static struct tcase {
> + uint64_t flags;
> + const char *sflags;
> +} tcases[] = {
> + { DESC(CLONE_NEWPID) },
> + { DESC(CLONE_NEWCGROUP) },
> + { DESC(CLONE_NEWIPC) },
> + { DESC(CLONE_NEWNET) },
> + { DESC(CLONE_NEWNS) },
> + { DESC(CLONE_NEWUTS) },
> +};
> +
> +static int child_fn(void *arg LTP_ATTRIBUTE_UNUSED)
> +{
> + *child_pid = getpid();
> + _exit(0);
> +}
> +
> +static void run(unsigned int n)
> +{
> + struct tcase *tc = &tcases[n];
> +
> + TST_EXP_FAIL(ltp_clone(tc->flags, child_fn, NULL, CHILD_STACK_SIZE,
> + child_stack), EPERM, "clone(%s) should fail with EPERM",
> + tc->sflags);
> +}
> +
> +static void setup(void)
> +{
> + child_pid = SAFE_MMAP(NULL, sizeof(*child_pid), PROT_READ |
> PROT_WRITE,
> + MAP_SHARED | MAP_ANONYMOUS, -1, 0);
> +}
> +
> +static void cleanup(void)
> +{
> + if (child_pid)
> + SAFE_MUNMAP(child_pid, sizeof(*child_pid));
> +}
> +
> +static struct tst_test test = {
> + .tcnt = ARRAY_SIZE(tcases),
> + .setup = setup,
> + .test = run,
> + .cleanup = cleanup,
> + .needs_root = 1,
> + .caps = (struct tst_cap []) {
> + TST_CAP(TST_CAP_DROP, CAP_SYS_ADMIN),
> + {},
> + },
> + .bufs = (struct tst_buffers []) {
> + {&child_stack, .size = CHILD_STACK_SIZE},
> + {},
> + },
> +};
> diff --git a/testcases/kernel/syscalls/clone3/.gitignore
> b/testcases/kernel/syscalls/clone3/.gitignore
> index 10369954b..e9b5312f4 100644
> --- a/testcases/kernel/syscalls/clone3/.gitignore
> +++ b/testcases/kernel/syscalls/clone3/.gitignore
> @@ -1,3 +1,4 @@
> clone301
> clone302
> clone303
> +clone304
> diff --git a/testcases/kernel/syscalls/clone3/clone304.c
> b/testcases/kernel/syscalls/clone3/clone304.c
> new file mode 100644
> index 000000000..34ce0cf7b
> --- /dev/null
> +++ b/testcases/kernel/syscalls/clone3/clone304.c
> @@ -0,0 +1,92 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Copyright (c) 2025 Stephen Bertram <sbertram@redhat.com>
> + */
> +
> +/*\
> + * This test verifies that :man2:`clone3` fails with EPERM when
> CAP_SYS_ADMIN
> + * has been dropped and ``clone_args.set_tid_size`` is greater than zero.
> + */
> +
> +#define _GNU_SOURCE
> +#define DESC(x) .flags = x, .sflags = #x
> +
> +#include "tst_test.h"
> +#include "lapi/sched.h"
> +
> +enum case_type {
> + K_SET_TID, /* flags = 0 || CLONE_NEW*, set_tid_size > 0 =>
> EPERM */
> + K_NAMESPACE_ONLY, /* flags = CLONE_NEW*, set_tid_size = 0 =>
> EPERM */
> +};
> +
> +static struct clone_args args = {0};
> +static pid_t tid_array[1] = {1};
> +
> +static struct tcase {
> + uint64_t flags;
> + const char *sflags;
> + enum case_type type;
> +} tcases[] = {
> + { DESC(CLONE_NEWPID), K_NAMESPACE_ONLY },
> + { DESC(CLONE_NEWCGROUP), K_NAMESPACE_ONLY },
> + { DESC(CLONE_NEWIPC), K_NAMESPACE_ONLY },
> + { DESC(CLONE_NEWNET), K_NAMESPACE_ONLY },
> + { DESC(CLONE_NEWNS), K_NAMESPACE_ONLY },
> + { DESC(CLONE_NEWUTS), K_NAMESPACE_ONLY },
> +
> + { DESC(CLONE_NEWPID), K_SET_TID },
> + { DESC(CLONE_NEWCGROUP), K_SET_TID },
> + { DESC(CLONE_NEWIPC), K_SET_TID },
> + { DESC(CLONE_NEWNET), K_SET_TID },
> + { DESC(CLONE_NEWNS), K_SET_TID },
> + { DESC(CLONE_NEWUTS), K_SET_TID },
> +
> + { DESC(0), K_SET_TID },
> +};
> +
> +static void run(unsigned int n)
> +{
> + struct tcase *tc = &tcases[n];
> +
> + args.flags = tc->flags;
> +
> + if (tc->type == K_NAMESPACE_ONLY) {
> + args.set_tid = 0;
> + args.set_tid_size = 0;
> + } else {
> + args.set_tid = (uint64_t)(uintptr_t)tid_array;
> + args.set_tid_size = 1;
> + }
> +
>
> + if (tc->flags == 0)
> + TST_EXP_FAIL(clone3(&args, sizeof(args)), EPERM,
> + "clone3(%s)\t\t\t set_tid_size=%ld",
> + tc->sflags, args.set_tid_size);
> + else
> + TST_EXP_FAIL(clone3(&args, sizeof(args)), EPERM,
> + "clone3(%s)\t set_tid_size=%ld",
> + tc->sflags, args.set_tid_size);
>
I don't think we need two syntaxes to print the same info.
The latter one should be good enough.
Otherwise, it looks good to me:
Reviewed-by: Li Wang <liwang@redhat.com>
--
Regards,
Li Wang
More information about the ltp
mailing list