public inbox for ltp@lists.linux.it
 help / color / mirror / Atom feed
* [LTP] [PATCH v3] Add new tests for clone and clone3
@ 2025-11-12 18:03 Stephen Bertram via ltp
  2025-11-12 20:11 ` Petr Vorel
  0 siblings, 1 reply; 4+ messages in thread
From: Stephen Bertram via ltp @ 2025-11-12 18:03 UTC (permalink / raw)
  To: ltp; +Cc: Stephen Bertram

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   | 72 +++++++++++++++++++++
 testcases/kernel/syscalls/clone3/.gitignore |  1 +
 testcases/kernel/syscalls/clone3/clone304.c | 63 ++++++++++++++++++
 5 files changed, 139 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..dd26c1594
--- /dev/null
+++ b/testcases/kernel/syscalls/clone/clone11.c
@@ -0,0 +1,72 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2025 Stephen Bertram <sbertram@redhat.com>
+ */
+
+/*\
+ * This test verifies that clone() fals with EPERM when CAP_SYS_ADMIN
+ * has been dropped.
+ */
+
+#define _GNU_SOURCE
+
+#include "tst_test.h"
+#include "clone_platform.h"
+
+static void *child_stack;
+static int *child_pid;
+
+static struct tcase {
+	uint64_t flags;
+	char *sflags;
+} tcases[] = {
+	{CLONE_NEWPID, "CLONE_NEWPID"},
+	{CLONE_NEWCGROUP, "CLONE_NEWCGROUP"},
+	{CLONE_NEWIPC, "CLONE_NEWIPC"},
+	{CLONE_NEWNET, "CLONE_NEWNET"},
+	{CLONE_NEWNS, "CLONE_NEWNS"},
+	{CLONE_NEWUTS, "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..e47ab313e
--- /dev/null
+++ b/testcases/kernel/syscalls/clone3/clone304.c
@@ -0,0 +1,63 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2025 Stephen Bertram <sbertram@redhat.com>
+ */
+
+/*\
+ * This test verifies that clone3() fals with EPERM when CAP_SYS_ADMIN
+ * has been dropped and ``clone_args.set_tid_size`` is greater than zero.
+ */
+
+#define _GNU_SOURCE
+#include "tst_test.h"
+#include "lapi/sched.h"
+
+static struct clone_args args = {0};
+static pid_t tid_array[4] = {0, 0, 0, 0};
+
+static struct tcase {
+	uint64_t flags;
+	char *sflags;
+} tcases[] = {
+	{CLONE_NEWPID, "CLONE_NEWPID"},
+	{CLONE_NEWCGROUP, "CLONE_NEWCGROUP"},
+	{CLONE_NEWIPC, "CLONE_NEWIPC"},
+	{CLONE_NEWNET, "CLONE_NEWNET"},
+	{CLONE_NEWNS, "CLONE_NEWNS"},
+	{CLONE_NEWUTS, "CLONE_NEWUTS"},
+};
+
+static void run(unsigned int n)
+{
+	struct tcase *tc = &tcases[n];
+
+	args.flags = tc->flags;
+
+	TST_EXP_FAIL(clone3(&args, sizeof(args)), EPERM, "clone3(%s) should fail with EPERM"
+			, tc->sflags);
+}
+
+static void setup(void)
+{
+	clone3_supported_by_kernel();
+
+	memset(&args, 0, sizeof(args));
+	args.set_tid = (uintptr_t)tid_array;
+	/* set_tid_size greater than zero - requires CAP_SYS_ADMIN */
+	args.set_tid_size = 4;
+}
+
+static struct tst_test test = {
+	.tcnt = ARRAY_SIZE(tcases),
+	.setup = setup,
+	.test = run,
+	.needs_root = 1,
+	.caps = (struct tst_cap []) {
+			TST_CAP(TST_CAP_DROP, CAP_SYS_ADMIN),
+			{},
+	},
+	.bufs = (struct tst_buffers []) {
+			{&args, .size = sizeof(struct clone_args)},
+			{},
+	},
+};
-- 
2.49.0


-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [LTP] [PATCH v3] Add new tests for clone and clone3
  2025-11-12 18:03 [LTP] [PATCH v3] Add new tests for clone and clone3 Stephen Bertram via ltp
@ 2025-11-12 20:11 ` Petr Vorel
  2025-11-12 21:05   ` Stephen Bertram via ltp
  0 siblings, 1 reply; 4+ messages in thread
From: Petr Vorel @ 2025-11-12 20:11 UTC (permalink / raw)
  To: Stephen Bertram; +Cc: ltp

Hi Ben,

> 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.

>  runtest/syscalls                            |  2 +
>  testcases/kernel/syscalls/clone/.gitignore  |  1 +
>  testcases/kernel/syscalls/clone/clone11.c   | 72 +++++++++++++++++++++
>  testcases/kernel/syscalls/clone3/.gitignore |  1 +
>  testcases/kernel/syscalls/clone3/clone304.c | 63 ++++++++++++++++++
>  5 files changed, 139 insertions(+)

This looks better then v2. Generally LGTM, few notes below.
Reviewed-by: Petr Vorel <pvorel@suse.cz>

I see adding the test for both clone() and clone3() is because Li asked
[1] for it.

[1] https://lore.kernel.org/ltp/CAEemH2cQam9tOeQj_4SdvoYG5ZNmar6Quc5M6mtr==2-HQR9yQ@mail.gmail.com/

nit: I would  phrase the subject as "Add EPERM test for clone and clone3" to
have at least a bit of information in the subject.

...
> +/*\
> + * This test verifies that clone() fals with EPERM when CAP_SYS_ADMIN
s/fals/fails/

If new version is needed, could you please use :man2:`clone` ?
This will link man clone(2) [2] in our test catalog [3].

[2] https://man7.org/linux/man-pages/man2/clone.2.html
[3] https://linux-test-project.readthedocs.io/en/latest/users/test_catalog.html

> + * has been dropped.
> + */
> +
> +#define _GNU_SOURCE

> +
> +#include "tst_test.h"
> +#include "clone_platform.h"

NOTE: we need to add
#include "lapi/sched.h"

otherwise old systems fail to compile due missing CLONE_NEWCGROUP.
This should really be fixed in a new version or before merge.

FYI we support kernel from 4.4 and glibc 2.22 [4].

[4] https://linux-test-project.readthedocs.io/en/latest/users/supported_systems.html

> +
> +static void *child_stack;
> +static int *child_pid;
> +
> +static struct tcase {
> +	uint64_t flags;
> +	char *sflags;
> +} tcases[] = {
> +	{CLONE_NEWPID, "CLONE_NEWPID"},

nit: If new version needed using macro is more elegant than copy pasting
definition as a string:

#define DESC(x) .flags = x, .sflags = #x
{ DESC(CLONE_NEWPID) },
{ DESC(CLONE_NEWCGROUP) },
...

> +	{CLONE_NEWCGROUP, "CLONE_NEWCGROUP"},
> +	{CLONE_NEWIPC, "CLONE_NEWIPC"},
> +	{CLONE_NEWNET, "CLONE_NEWNET"},
> +	{CLONE_NEWNS, "CLONE_NEWNS"},
> +	{CLONE_NEWUTS, "CLONE_NEWUTS"},
> +};
> +
> +static int child_fn(void *arg LTP_ATTRIBUTE_UNUSED)
> +{
> +		*child_pid = getpid();
> +		exit(0);
nit: there are 2 tabs.
> +}
> +
> +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);
very nit: ',' is usually on a previous line.
> +}
> +
> +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..e47ab313e
> --- /dev/null
> +++ b/testcases/kernel/syscalls/clone3/clone304.c
> @@ -0,0 +1,63 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Copyright (c) 2025 Stephen Bertram <sbertram@redhat.com>
> + */
> +
> +/*\
> + * This test verifies that clone3() fals with EPERM when CAP_SYS_ADMIN
> + * has been dropped and ``clone_args.set_tid_size`` is greater than zero.
> + */
> +
> +#define _GNU_SOURCE
> +#include "tst_test.h"
> +#include "lapi/sched.h"
> +
> +static struct clone_args args = {0};
> +static pid_t tid_array[4] = {0, 0, 0, 0};
> +
> +static struct tcase {
> +	uint64_t flags;
> +	char *sflags;
> +} tcases[] = {
> +	{CLONE_NEWPID, "CLONE_NEWPID"},
> +	{CLONE_NEWCGROUP, "CLONE_NEWCGROUP"},
> +	{CLONE_NEWIPC, "CLONE_NEWIPC"},
> +	{CLONE_NEWNET, "CLONE_NEWNET"},
> +	{CLONE_NEWNS, "CLONE_NEWNS"},
> +	{CLONE_NEWUTS, "CLONE_NEWUTS"},
> +};
> +
> +static void run(unsigned int n)
> +{
> +	struct tcase *tc = &tcases[n];
> +
> +	args.flags = tc->flags;
> +
> +	TST_EXP_FAIL(clone3(&args, sizeof(args)), EPERM, "clone3(%s) should fail with EPERM"
> +			, tc->sflags);
> +}
> +
> +static void setup(void)
> +{
> +	clone3_supported_by_kernel();
> +
> +	memset(&args, 0, sizeof(args));
> +	args.set_tid = (uintptr_t)tid_array;
> +	/* set_tid_size greater than zero - requires CAP_SYS_ADMIN */
> +	args.set_tid_size = 4;
> +}
> +
> +static struct tst_test test = {
NOTE: man clone(2) claims set_tid_size is "since Linux 5.5".
But fortunately test TCONF correctly:
../../../../include/lapi/sched.h:88: TCONF: syscall(435) __NR_clone3 not supported on your arch

Therefore we don't need to add .min_kver = "5.5".

> +	.tcnt = ARRAY_SIZE(tcases),
> +	.setup = setup,
> +	.test = run,
> +	.needs_root = 1,
> +	.caps = (struct tst_cap []) {
> +			TST_CAP(TST_CAP_DROP, CAP_SYS_ADMIN),
> +			{},
> +	},
> +	.bufs = (struct tst_buffers []) {
> +			{&args, .size = sizeof(struct clone_args)},
> +			{},
> +	},
> +};

-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [LTP] [PATCH v3] Add new tests for clone and clone3
  2025-11-12 20:11 ` Petr Vorel
@ 2025-11-12 21:05   ` Stephen Bertram via ltp
  2025-11-18 14:54     ` Petr Vorel
  0 siblings, 1 reply; 4+ messages in thread
From: Stephen Bertram via ltp @ 2025-11-12 21:05 UTC (permalink / raw)
  To: Petr Vorel; +Cc: ltp

Hi Petr,
On Wed, Nov 12, 2025 at 3:17 PM Petr Vorel <pvorel@suse.cz> wrote:

> Hi Ben,
>
stephen

>
> ...
> > +/*\
> > + * This test verifies that clone() fals with EPERM when CAP_SYS_ADMIN
> s/fals/fails/
>
> If new version is needed, could you please use :man2:`clone` ?
> This will link man clone(2) [2] in our test catalog [3].
>
So I'm clear, a lot is new to me here, I should replace "clone()" with
:man:`clone`
Will the same work for clone3? i.e. :man:`clone3`?

I understand the other comments and will implement them, nit or not :).

>
Thank you for the feedback.

stephen

-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [LTP] [PATCH v3] Add new tests for clone and clone3
  2025-11-12 21:05   ` Stephen Bertram via ltp
@ 2025-11-18 14:54     ` Petr Vorel
  0 siblings, 0 replies; 4+ messages in thread
From: Petr Vorel @ 2025-11-18 14:54 UTC (permalink / raw)
  To: Stephen Bertram; +Cc: ltp

Hi Stephen,
...
> > > +/*\
> > > + * This test verifies that clone() fals with EPERM when CAP_SYS_ADMIN
> > s/fals/fails/

> > If new version is needed, could you please use :man2:`clone` ?
> > This will link man clone(2) [2] in our test catalog [3].

> So I'm clear, a lot is new to me here, I should replace "clone()" with
> :man:`clone`
> Will the same work for clone3? i.e. :man:`clone3`?

FYI man2 is for man 2 section, man 3 is for man 3 section:

doc/conf.py

    'man2': ('https://man7.org/linux/man-pages/man2/%s.2.html', '%s(2)'),
    'man3': ('https://man7.org/linux/man-pages/man3/%s.3.html', '%s(3)'),

i.e. :man2:`clone` leads to man clone(2)
https://man7.org/linux/man-pages/man2/clone.2.html

which describes both syscalls:
clone, __clone2, clone3 - create a child process

But sure man clone3(2) links also works (the same page as man clone(2)).
https://man7.org/linux/man-pages/man2/clone3.2.html

FYI (if you have time) this should generate doc

$ cd doc; make setup && make

which is under ./html/users/test_catalog.html
and online:
https://linux-test-project.readthedocs.io/en/latest/users/test_catalog.html

> I understand the other comments and will implement them, nit or not :).

Thank you!

Kind regards,
Petr

-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2025-11-18 14:55 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-11-12 18:03 [LTP] [PATCH v3] Add new tests for clone and clone3 Stephen Bertram via ltp
2025-11-12 20:11 ` Petr Vorel
2025-11-12 21:05   ` Stephen Bertram via ltp
2025-11-18 14:54     ` Petr Vorel

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