// SPDX-License-Identifier: GPL-2.0

/* Based on Christian Brauner's clone3() example */

#define _GNU_SOURCE
#include <errno.h>
#include <inttypes.h>
#include <linux/types.h>
#include <linux/sched.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <sys/un.h>
#include <sys/wait.h>
#include <unistd.h>
#include <sched.h>

#include "../kselftest.h"
#include "clone3_selftests.h"

enum test_mode {
	CLONE3_ARGS_NO_TEST,
	CLONE3_ARGS_ALL_0,
	CLONE3_ARGS_INVAL_EXIT_SIGNAL_BIG,
	CLONE3_ARGS_INVAL_EXIT_SIGNAL_NEG,
	CLONE3_ARGS_INVAL_EXIT_SIGNAL_CSIG,
	CLONE3_ARGS_INVAL_EXIT_SIGNAL_NSIG,
};

static int call_clone3(uint64_t flags, size_t size, enum test_mode test_mode)
{
	struct __clone_args args = {
		.flags = flags,
		.exit_signal = SIGCHLD,
	};

	struct clone_args_extended {
		struct __clone_args args;
		__aligned_u64 excess_space[2];
	} args_ext;

	pid_t pid = -1;
	int status;

	memset(&args_ext, 0, sizeof(args_ext));
	if (size > sizeof(struct __clone_args))
		args_ext.excess_space[1] = 1;

	if (size == 0)
		size = sizeof(struct __clone_args);

	switch (test_mode) {
	case CLONE3_ARGS_NO_TEST:
		/*
		 * Uses default 'flags' and 'SIGCHLD'
		 * assignment.
		 */
		break;
	case CLONE3_ARGS_ALL_0:
		args.flags = 0;
		args.exit_signal = 0;
		break;
	case CLONE3_ARGS_INVAL_EXIT_SIGNAL_BIG:
		args.exit_signal = 0xbadc0ded00000000ULL;
		break;
	case CLONE3_ARGS_INVAL_EXIT_SIGNAL_NEG:
		args.exit_signal = 0x0000000080000000ULL;
		break;
	case CLONE3_ARGS_INVAL_EXIT_SIGNAL_CSIG:
		args.exit_signal = 0x0000000000000100ULL;
		break;
	case CLONE3_ARGS_INVAL_EXIT_SIGNAL_NSIG:
		args.exit_signal = 0x00000000000000f0ULL;
		break;
	}

	memcpy(&args_ext.args, &args, sizeof(struct __clone_args));

	pid = sys_clone3((struct __clone_args *)&args_ext, size);
	if (pid < 0) {
		ksft_print_msg("%s - Failed to create new process\n",
				strerror(errno));
		return -errno;
	}

	if (pid == 0) {
		ksft_print_msg("I am the child, my PID is %d\n", getpid());
		_exit(EXIT_SUCCESS);
	}

	ksft_print_msg("I am the parent (%d). My child's pid is %d\n",
			getpid(), pid);

	if (waitpid(-1, &status, __WALL) < 0) {
		ksft_print_msg("Child returned %s\n", strerror(errno));
		return -errno;
	}
	if (WEXITSTATUS(status))
		return WEXITSTATUS(status);

	return 0;
}

static void test_clone3(uint64_t flags, size_t size, int expected,
		       enum test_mode test_mode)
{
	int ret;

	ksft_print_msg(
		"[%d] Trying clone3() with flags %#" PRIx64 " (size %zu)\n",
		getpid(), flags, size);
	ret = call_clone3(flags, size, test_mode);
	ksft_print_msg("[%d] clone3() with flags says: %d expected %d\n",
			getpid(), ret, expected);
	if (ret != expected)
		ksft_test_result_fail(
			"[%d] Result (%d) is different than expected (%d)\n",
			getpid(), ret, expected);
	else
		ksft_test_result_pass(
			"[%d] Result (%d) matches expectation (%d)\n",
			getpid(), ret, expected);
}

int main(int argc, char *argv[])
{
	uid_t uid = getuid();

	ksft_print_header();
	ksft_set_plan(17);
	test_clone3_supported();

	/* Just a simple clone3() should return 0.*/
	test_clone3(0, 0, 0, CLONE3_ARGS_NO_TEST);

	/* Do a clone3() in a new PID NS.*/
	if (uid == 0)
		test_clone3(CLONE_NEWPID, 0, 0, CLONE3_ARGS_NO_TEST);
	else
		ksft_test_result_skip("Skipping clone3() with CLONE_NEWPID\n");

	/* Do a clone3() with CLONE_ARGS_SIZE_VER0. */
	test_clone3(0, CLONE_ARGS_SIZE_VER0, 0, CLONE3_ARGS_NO_TEST);

	/* Do a clone3() with CLONE_ARGS_SIZE_VER0 - 8 */
	test_clone3(0, CLONE_ARGS_SIZE_VER0 - 8, -EINVAL, CLONE3_ARGS_NO_TEST);

	/* Do a clone3() with sizeof(struct clone_args) + 8 */
	test_clone3(0, sizeof(struct __clone_args) + 8, 0, CLONE3_ARGS_NO_TEST);

	/* Do a clone3() with exit_signal having highest 32 bits non-zero */
	test_clone3(0, 0, -EINVAL, CLONE3_ARGS_INVAL_EXIT_SIGNAL_BIG);

	/* Do a clone3() with negative 32-bit exit_signal */
	test_clone3(0, 0, -EINVAL, CLONE3_ARGS_INVAL_EXIT_SIGNAL_NEG);

	/* Do a clone3() with exit_signal not fitting into CSIGNAL mask */
	test_clone3(0, 0, -EINVAL, CLONE3_ARGS_INVAL_EXIT_SIGNAL_CSIG);

	/* Do a clone3() with NSIG < exit_signal < CSIG */
	test_clone3(0, 0, -EINVAL, CLONE3_ARGS_INVAL_EXIT_SIGNAL_NSIG);

	test_clone3(0, sizeof(struct __clone_args) + 8, 0, CLONE3_ARGS_ALL_0);

	test_clone3(0, sizeof(struct __clone_args) + 16, -E2BIG,
			CLONE3_ARGS_ALL_0);

	test_clone3(0, sizeof(struct __clone_args) * 2, -E2BIG,
			CLONE3_ARGS_ALL_0);

	/* Do a clone3() with > page size */
	test_clone3(0, getpagesize() + 8, -E2BIG, CLONE3_ARGS_NO_TEST);

	/* Do a clone3() with CLONE_ARGS_SIZE_VER0 in a new PID NS. */
	if (uid == 0)
		test_clone3(CLONE_NEWPID, CLONE_ARGS_SIZE_VER0, 0,
				CLONE3_ARGS_NO_TEST);
	else
		ksft_test_result_skip("Skipping clone3() with CLONE_NEWPID\n");

	/* Do a clone3() with CLONE_ARGS_SIZE_VER0 - 8 in a new PID NS */
	test_clone3(CLONE_NEWPID, CLONE_ARGS_SIZE_VER0 - 8, -EINVAL,
			CLONE3_ARGS_NO_TEST);

	/* Do a clone3() with sizeof(struct clone_args) + 8 in a new PID NS */
	if (uid == 0)
		test_clone3(CLONE_NEWPID, sizeof(struct __clone_args) + 8, 0,
				CLONE3_ARGS_NO_TEST);
	else
		ksft_test_result_skip("Skipping clone3() with CLONE_NEWPID\n");

	/* Do a clone3() with > page size in a new PID NS */
	test_clone3(CLONE_NEWPID, getpagesize() + 8, -E2BIG,
			CLONE3_ARGS_NO_TEST);

	return !ksft_get_fail_cnt() ? ksft_exit_pass() : ksft_exit_fail();
}
