[LTP] [PATCH] Add unshare(CLONE_NEWPID) test

Andrea Cervesato andrea.cervesato@suse.com
Fri Jul 11 10:49:22 CEST 2025


Hi!

On 7/11/25 9:24 AM, lufei wrote:
> Test unshare(CLONE_NEWPID) to make first child in new PID namespce get
> pid 1.
>
> Signed-off-by: lufei <lufei@uniontech.com>
> ---
>   runtest/syscalls                              |  1 +
>   testcases/kernel/syscalls/unshare/.gitignore  |  1 +
>   testcases/kernel/syscalls/unshare/unshare05.c | 54 +++++++++++++++++++
>   3 files changed, 56 insertions(+)
>   create mode 100644 testcases/kernel/syscalls/unshare/unshare05.c
>
> diff --git a/runtest/syscalls b/runtest/syscalls
> index 57338297a..82e222bf4 100644
> --- a/runtest/syscalls
> +++ b/runtest/syscalls
> @@ -1726,6 +1726,7 @@ unshare01 unshare01
>   unshare02 unshare02
>   unshare03 unshare03
>   unshare04 unshare04
> +unshare05 unshare05
>   
>   #
>   # These tests require an unmounted block device
> diff --git a/testcases/kernel/syscalls/unshare/.gitignore b/testcases/kernel/syscalls/unshare/.gitignore
> index b1206e452..8ece5f988 100644
> --- a/testcases/kernel/syscalls/unshare/.gitignore
> +++ b/testcases/kernel/syscalls/unshare/.gitignore
> @@ -2,3 +2,4 @@
>   /unshare02
>   /unshare03
>   /unshare04
> +/unshare05
> diff --git a/testcases/kernel/syscalls/unshare/unshare05.c b/testcases/kernel/syscalls/unshare/unshare05.c
> new file mode 100644
> index 000000000..cfc5877da
> --- /dev/null
> +++ b/testcases/kernel/syscalls/unshare/unshare05.c
> @@ -0,0 +1,54 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Copyright (c) 2025 lufei <lufei@uniontech.com>
> + */
> +
> +/*\
> + * This test case verifies unshare(CLONE_NEWPID) creates a new PID namespace
> + * and that the first child process in the new namespace gets PID 1.
> + */
> +
> +#define _GNU_SOURCE
> +
> +#include "tst_test.h"
> +#include "lapi/sched.h"
> +
> +static void run(void)
> +{
> +	struct tst_clone_args args = {
> +		.flags = CLONE_NEWPID,
> +		.exit_signal = SIGCHLD,
> +	};
This should be created in tst_test.bufs and initialized inside setup().
> +
> +	if (!SAFE_CLONE(&args)) {
> +		TST_EXP_PASS(unshare(CLONE_NEWPID));
We can use SAFE_UNSHARE() since we need to break the test if unshare() 
is not passing.
> +
> +		pid_t child_pid = SAFE_FORK();
> +
> +		if (child_pid == 0) {
> +			pid_t pid = getpid();
> +
> +			if (pid == 1)
> +				tst_res(TPASS, "First child in new PID "
> +						"namespace has PID 1");
> +			else
> +				tst_res(TFAIL, "First child in new PID "
> +						"namespace has PID %d, "
> +						"expected 1", pid);
> +			exit(0);
> +		} else {
> +			SAFE_WAIT(NULL);
> +		}
> +
> +		exit(0);
> +	}
> +
> +	SAFE_WAIT(NULL);
All this part can be summed up like this:

if (!SAFE_FORK()) {
     TST_EXP_EQ_LI(getpid(), 1);
     exit(0);
}

And no need for wait() since LTP will take care of collecting child 
results after reaping it.

> +}
> +
> +static struct tst_test test = {
> +	.forks_child = 1,
> +	.needs_root = 1,
> +	.test_all = run,
> +	.min_kver = "3.8",
We support from 4.15, so we don't need to define the minimum kernel 
version here.
https://linux-test-project.readthedocs.io/en/latest/users/supported_systems.html
> +};
- Andrea


More information about the ltp mailing list