* Copyright (c) 2025 Andrea Cervesato <andrea.cervesato@suse.com>
*/
* Verify that ioctl() doesn't allow to obtain the exit status of an isolated
* process via PIDFD_INFO_EXIT in within an another isolated process, which
* doesn't have any parent connection.
*/
#include "ioctl_pidfd.h"
#include "lapi/sched.h"
static struct tst_clone_args *args;
static struct pidfd_info *info;
static void run(void)
{
int pidfd;
pid_t pid_child;
memset(args, 0, sizeof(struct tst_clone_args));
memset(info, 0, sizeof(struct pidfd_info));
info->mask = PIDFD_INFO_EXIT;
args->flags = CLONE_PIDFD | CLONE_NEWUSER | CLONE_NEWPID;
args->pidfd = (uint64_t)&pidfd;
args->exit_signal = SIGCHLD;
pid_child = SAFE_CLONE(args);
if (!pid_child)
exit(100);
SAFE_WAITPID(pid_child, NULL, 0);
memset(args, 0, sizeof(struct tst_clone_args));
args->flags = CLONE_NEWUSER | CLONE_NEWPID;
args->exit_signal = SIGCHLD;
if (!SAFE_CLONE(args)) {
TST_EXP_FAIL(ioctl(pidfd, PIDFD_GET_INFO, info), ESRCH);
exit(0);
}
SAFE_CLOSE(pidfd);
}
static void setup(void)
{
if (!ioctl_pidfd_info_exit_supported())
tst_brk(TCONF, "PIDFD_INFO_EXIT is not supported by ioctl()");
}
static struct tst_test test = {
.test_all = run,
.setup = setup,
.forks_child = 1,
.bufs = (struct tst_buffers []) {
{&args, .size = sizeof(*args)},
{&info, .size = sizeof(*info)},
{}
}
};