// SPDX-License-Identifier: GPL-2.0

#define _GNU_SOURCE
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <linux/types.h>
#include <sched.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <syscall.h>
#include <sys/wait.h>
#include <sys/mman.h>

#include "pidfd.h"
#include "../kselftest.h"

struct error {
	int  code;
	char msg[512];
};

static int error_set(struct error *err, int code, const char *fmt, ...)
{
	va_list args;
	int r;

	if (code == PIDFD_PASS || !err || err->code != PIDFD_PASS)
		return code;

	err->code = code;
	va_start(args, fmt);
	r = vsnprintf(err->msg, sizeof(err->msg), fmt, args);
	assert((size_t)r < sizeof(err->msg));
	va_end(args);

	return code;
}

static void error_report(struct error *err, const char *test_name)
{
	switch (err->code) {
	case PIDFD_ERROR:
		ksft_exit_fail_msg("%s test: Fatal: %s\n", test_name, err->msg);
		break;

	case PIDFD_FAIL:
		/* will be: not ok %d # error %s test: %s */
		ksft_test_result_error("%s test: %s\n", test_name, err->msg);
		break;

	case PIDFD_SKIP:
		/* will be: not ok %d # SKIP %s test: %s */
		ksft_test_result_skip("%s test: %s\n", test_name, err->msg);
		break;

	case PIDFD_XFAIL:
		ksft_test_result_pass("%s test: Expected failure: %s\n",
				      test_name, err->msg);
		break;

	case PIDFD_PASS:
		ksft_test_result_pass("%s test: Passed\n", test_name);
		break;

	default:
		ksft_exit_fail_msg("%s test: Unknown code: %d %s\n",
				   test_name, err->code, err->msg);
		break;
	}
}

static inline int error_check(struct error *err, const char *test_name)
{
	/* In case of error we bail out and terminate the test program */
	if (err->code == PIDFD_ERROR)
		error_report(err, test_name);

	return err->code;
}

#define CHILD_STACK_SIZE 8192

struct child {
	char *stack;
	pid_t pid;
	int   fd;
};

static struct child clone_newns(int (*fn)(void *), void *args,
				struct error *err)
{
	static int flags = CLONE_PIDFD | CLONE_NEWPID | CLONE_NEWNS | SIGCHLD;
	struct child ret;

	if (!(flags & CLONE_NEWUSER) && geteuid() != 0)
		flags |= CLONE_NEWUSER;

	ret.stack = mmap(NULL, CHILD_STACK_SIZE, PROT_READ | PROT_WRITE,
			 MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, -1, 0);
	if (ret.stack == MAP_FAILED) {
		error_set(err, -1, "mmap of stack failed (errno %d)", errno);
		return ret;
	}

#ifdef __ia64__
	ret.pid = __clone2(fn, ret.stack, CHILD_STACK_SIZE, flags, args, &ret.fd);
#else
	ret.pid = clone(fn, ret.stack + CHILD_STACK_SIZE, flags, args, &ret.fd);
#endif

	if (ret.pid < 0) {
		error_set(err, PIDFD_ERROR, "clone failed (ret %d, errno %d)",
			  ret.fd, errno);
		return ret;
	}

	ksft_print_msg("New child: %d, fd: %d\n", ret.pid, ret.fd);

	return ret;
}

static inline void child_close(struct child *child)
{
	close(child->fd);
}

static inline int child_join(struct child *child, struct error *err)
{
	int r;

	r = wait_for_pid(child->pid);
	if (r < 0)
		error_set(err, PIDFD_ERROR, "waitpid failed (ret %d, errno %d)",
			  r, errno);
	else if (r > 0)
		error_set(err, r, "child %d reported: %d", child->pid, r);

	if (munmap(child->stack, CHILD_STACK_SIZE)) {
		error_set(err, -1, "munmap of child stack failed (errno %d)", errno);
		r = -1;
	}

	ksft_print_msg("waitpid WEXITSTATUS=%d\n", r);
	return r;
}

static inline int child_join_close(struct child *child, struct error *err)
{
	child_close(child);
	return child_join(child, err);
}

static inline void trim_newline(char *str)
{
	char *pos = strrchr(str, '\n');

	if (pos)
		*pos = '\0';
}

static int verify_fdinfo(int pidfd, struct error *err, const char *prefix,
			 size_t prefix_len, const char *expect, ...)
{
	char buffer[512] = {0, };
	char path[512] = {0, };
	va_list args;
	FILE *f;
	char *line = NULL;
	size_t n = 0;
	int found = 0;
	int r;

	va_start(args, expect);
	r = vsnprintf(buffer, sizeof(buffer), expect, args);
	assert((size_t)r < sizeof(buffer));
	va_end(args);

	snprintf(path, sizeof(path), "/proc/self/fdinfo/%d", pidfd);
	f = fopen(path, "re");
	if (!f)
		return error_set(err, PIDFD_ERROR, "fdinfo open failed for %d",
				 pidfd);

	while (getline(&line, &n, f) != -1) {
		char *val;

		if (strncmp(line, prefix, prefix_len))
			continue;

		found = 1;

		val = line + prefix_len;
		r = strcmp(val, buffer);
		if (r != 0) {
			trim_newline(line);
			trim_newline(buffer);
			error_set(err, PIDFD_FAIL, "%s '%s' != '%s'",
				  prefix, val, buffer);
		}
		break;
	}

	free(line);
	fclose(f);

	if (found == 0)
		return error_set(err, PIDFD_FAIL, "%s not found for fd %d",
				 prefix, pidfd);

	return PIDFD_PASS;
}

static int child_fdinfo_nspid_test(void *args)
{
	struct error err;
	int pidfd;
	int r;

	/* if we got no fd for the sibling, we are done */
	if (!args)
		return PIDFD_PASS;

	/* verify that we can not resolve the pidfd for a process
	 * in a sibling pid namespace, i.e. a pid namespace it is
	 * not in our or a descended namespace
	 */
	r = mount(NULL, "/", NULL, MS_REC | MS_PRIVATE, 0);
	if (r < 0) {
		ksft_print_msg("Failed to remount / private\n");
		return PIDFD_ERROR;
	}

	(void)umount2("/proc", MNT_DETACH);
	r = mount("proc", "/proc", "proc", 0, NULL);
	if (r < 0) {
		ksft_print_msg("Failed to remount /proc\n");
		return PIDFD_ERROR;
	}

	pidfd = *(int *)args;
	r = verify_fdinfo(pidfd, &err, "NSpid:", 6, "\t0\n");

	if (r != PIDFD_PASS)
		ksft_print_msg("NSpid fdinfo check failed: %s\n", err.msg);

	return r;
}

static void test_pidfd_fdinfo_nspid(void)
{
	struct child a, b;
	struct error err = {0, };
	const char *test_name = "pidfd check for NSpid in fdinfo";

	/* Create a new child in a new pid and mount namespace */
	a = clone_newns(child_fdinfo_nspid_test, NULL, &err);
	error_check(&err, test_name);

	/* Pass the pidfd representing the first child to the
	 * second child, which will be in a sibling pid namespace,
	 * which means that the fdinfo NSpid entry for the pidfd
	 * should only contain '0'.
	 */
	b = clone_newns(child_fdinfo_nspid_test, &a.fd, &err);
	error_check(&err, test_name);

	/* The children will have pid 1 in the new pid namespace,
	 * so the line must be 'NSPid:\t<pid>\t1'.
	 */
	verify_fdinfo(a.fd, &err, "NSpid:", 6, "\t%d\t%d\n", a.pid, 1);
	verify_fdinfo(b.fd, &err, "NSpid:", 6, "\t%d\t%d\n", b.pid, 1);

	/* wait for the process, check the exit status and set
	 * 'err' accordingly, if it is not already set.
	 */
	child_join_close(&a, &err);
	child_join_close(&b, &err);

	error_report(&err, test_name);
}

static void test_pidfd_dead_fdinfo(void)
{
	struct child a;
	struct error err = {0, };
	const char *test_name = "pidfd check fdinfo for dead process";

	/* Create a new child in a new pid and mount namespace */
	a = clone_newns(child_fdinfo_nspid_test, NULL, &err);
	error_check(&err, test_name);
	child_join(&a, &err);

	verify_fdinfo(a.fd, &err, "Pid:", 4, "\t-1\n");
	verify_fdinfo(a.fd, &err, "NSpid:", 6, "\t-1\n");
	child_close(&a);
	error_report(&err, test_name);
}

int main(int argc, char **argv)
{
	ksft_print_header();
	ksft_set_plan(2);

	test_pidfd_fdinfo_nspid();
	test_pidfd_dead_fdinfo();

	return ksft_exit_pass();
}
