[LTP] [PATCH v6] Add EPERM test for clone and clone3
Stephen Bertram
sbertram@redhat.com
Wed Nov 19 12:49:07 CET 2025
Hi Li,
I did this for output formatting. Yes not needed but it looks nicer when
the results are displayed.
Let me know which you prefer.
As is:
clone304.c:66: TPASS: clone3(CLONE_NEWPID) set_tid_size=0 :
EPERM (1)
clone304.c:66: TPASS: clone3(CLONE_NEWCGROUP) set_tid_size=0 : EPERM (1)
clone304.c:66: TPASS: clone3(CLONE_NEWIPC) set_tid_size=0 :
EPERM (1)
clone304.c:66: TPASS: clone3(CLONE_NEWNET) set_tid_size=0 :
EPERM (1)
clone304.c:66: TPASS: clone3(CLONE_NEWNS) set_tid_size=0 :
EPERM (1)
clone304.c:66: TPASS: clone3(CLONE_NEWUTS) set_tid_size=0 :
EPERM (1)
clone304.c:66: TPASS: clone3(CLONE_NEWPID) set_tid_size=1 :
EPERM (1)
clone304.c:66: TPASS: clone3(CLONE_NEWCGROUP) set_tid_size=1 : EPERM (1)
clone304.c:66: TPASS: clone3(CLONE_NEWIPC) set_tid_size=1 :
EPERM (1)
clone304.c:66: TPASS: clone3(CLONE_NEWNET) set_tid_size=1 :
EPERM (1)
clone304.c:66: TPASS: clone3(CLONE_NEWNS) set_tid_size=1 :
EPERM (1)
clone304.c:66: TPASS: clone3(CLONE_NEWUTS) set_tid_size=1 :
EPERM (1)
clone304.c:62: TPASS: clone3(0)
set_tid_size=1 : EPERM (1)
Without:
clone304.c:66: TPASS: clone3(CLONE_NEWPID) set_tid_size=0 :
EPERM (1)
clone304.c:66: TPASS: clone3(CLONE_NEWCGROUP) set_tid_size=0 : EPERM (1)
clone304.c:66: TPASS: clone3(CLONE_NEWIPC) set_tid_size=0 :
EPERM (1)
clone304.c:66: TPASS: clone3(CLONE_NEWNET) set_tid_size=0 :
EPERM (1)
clone304.c:66: TPASS: clone3(CLONE_NEWNS) set_tid_size=0 :
EPERM (1)
clone304.c:66: TPASS: clone3(CLONE_NEWUTS) set_tid_size=0 :
EPERM (1)
clone304.c:66: TPASS: clone3(CLONE_NEWPID) set_tid_size=1 :
EPERM (1)
clone304.c:66: TPASS: clone3(CLONE_NEWCGROUP) set_tid_size=1 : EPERM (1)
clone304.c:66: TPASS: clone3(CLONE_NEWIPC) set_tid_size=1 :
EPERM (1)
clone304.c:66: TPASS: clone3(CLONE_NEWNET) set_tid_size=1 :
EPERM (1)
clone304.c:66: TPASS: clone3(CLONE_NEWNS) set_tid_size=1 :
EPERM (1)
clone304.c:66: TPASS: clone3(CLONE_NEWUTS) set_tid_size=1 :
EPERM (1)
clone304.c:62: TPASS: clone3(0) set_tid_size=1 : EPERM (1)
Obviously I think it's worth it to have a nicely reporting output.
thanks,
stephen
He/His/Him
On Wed, Nov 19, 2025 at 3:40 AM Li Wang <liwang@redhat.com> wrote:
>
>
> 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