// SPDX-License-Identifier: GPL-2.0

#define _GNU_SOURCE
#include <errno.h>
#include <fcntl.h>
#include <limits.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/prctl.h>
#include <sys/wait.h>
#include <unistd.h>
#include <sys/socket.h>
#include <linux/kcmp.h>

#include "pidfd.h"
#include "../kselftest_harness.h"

/*
 * UNKNOWN_FD is an fd number that should never exist in the child, as it is
 * used to check the negative case.
 */
#define UNKNOWN_FD 111
#define UID_NOBODY 65535

static int sys_kcmp(pid_t pid1, pid_t pid2, int type, unsigned long idx1,
		    unsigned long idx2)
{
	return syscall(__NR_kcmp, pid1, pid2, type, idx1, idx2);
}

static int __child(int sk, int memfd)
{
	int ret;
	char buf;

	/*
	 * Ensure we don't leave around a bunch of orphaned children if our
	 * tests fail.
	 */
	ret = prctl(PR_SET_PDEATHSIG, SIGKILL);
	if (ret) {
		fprintf(stderr, "%s: Child could not set DEATHSIG\n",
			strerror(errno));
		return -1;
	}

	ret = send(sk, &memfd, sizeof(memfd), 0);
	if (ret != sizeof(memfd)) {
		fprintf(stderr, "%s: Child failed to send fd number\n",
			strerror(errno));
		return -1;
	}

	/*
	 * The fixture setup is completed at this point. The tests will run.
	 *
	 * This blocking recv enables the parent to message the child.
	 * Either we will read 'P' off of the sk, indicating that we need
	 * to disable ptrace, or we will read a 0, indicating that the other
	 * side has closed the sk. This occurs during fixture teardown time,
	 * indicating that the child should exit.
	 */
	while ((ret = recv(sk, &buf, sizeof(buf), 0)) > 0) {
		if (buf == 'P') {
			ret = prctl(PR_SET_DUMPABLE, 0);
			if (ret < 0) {
				fprintf(stderr,
					"%s: Child failed to disable ptrace\n",
					strerror(errno));
				return -1;
			}
		} else {
			fprintf(stderr, "Child received unknown command %c\n",
				buf);
			return -1;
		}
		ret = send(sk, &buf, sizeof(buf), 0);
		if (ret != 1) {
			fprintf(stderr, "%s: Child failed to ack\n",
				strerror(errno));
			return -1;
		}
	}
	if (ret < 0) {
		fprintf(stderr, "%s: Child failed to read from socket\n",
			strerror(errno));
		return -1;
	}

	return 0;
}

static int child(int sk)
{
	int memfd, ret;

	memfd = sys_memfd_create("test", 0);
	if (memfd < 0) {
		fprintf(stderr, "%s: Child could not create memfd\n",
			strerror(errno));
		ret = -1;
	} else {
		ret = __child(sk, memfd);
		close(memfd);
	}

	close(sk);
	return ret;
}

FIXTURE(child)
{
	/*
	 * remote_fd is the number of the FD which we are trying to retrieve
	 * from the child.
	 */
	int remote_fd;
	/* pid points to the child which we are fetching FDs from */
	pid_t pid;
	/* pidfd is the pidfd of the child */
	int pidfd;
	/*
	 * sk is our side of the socketpair used to communicate with the child.
	 * When it is closed, the child will exit.
	 */
	int sk;
};

FIXTURE_SETUP(child)
{
	int ret, sk_pair[2];

	ASSERT_EQ(0, socketpair(PF_LOCAL, SOCK_SEQPACKET, 0, sk_pair)) {
		TH_LOG("%s: failed to create socketpair", strerror(errno));
	}
	self->sk = sk_pair[0];

	self->pid = fork();
	ASSERT_GE(self->pid, 0);

	if (self->pid == 0) {
		close(sk_pair[0]);
		if (child(sk_pair[1]))
			_exit(EXIT_FAILURE);
		_exit(EXIT_SUCCESS);
	}

	close(sk_pair[1]);

	self->pidfd = sys_pidfd_open(self->pid, 0);
	ASSERT_GE(self->pidfd, 0);

	/*
	 * Wait for the child to complete setup. It'll send the remote memfd's
	 * number when ready.
	 */
	ret = recv(sk_pair[0], &self->remote_fd, sizeof(self->remote_fd), 0);
	ASSERT_EQ(sizeof(self->remote_fd), ret);
}

FIXTURE_TEARDOWN(child)
{
	EXPECT_EQ(0, close(self->pidfd));
	EXPECT_EQ(0, close(self->sk));

	EXPECT_EQ(0, wait_for_pid(self->pid));
}

TEST_F(child, disable_ptrace)
{
	int uid, fd;
	char c;

	/*
	 * Turn into nobody if we're root, to avoid CAP_SYS_PTRACE
	 *
	 * The tests should run in their own process, so even this test fails,
	 * it shouldn't result in subsequent tests failing.
	 */
	uid = getuid();
	if (uid == 0)
		ASSERT_EQ(0, seteuid(UID_NOBODY));

	ASSERT_EQ(1, send(self->sk, "P", 1, 0));
	ASSERT_EQ(1, recv(self->sk, &c, 1, 0));

	fd = sys_pidfd_getfd(self->pidfd, self->remote_fd, 0);
	EXPECT_EQ(-1, fd);
	EXPECT_EQ(EPERM, errno);

	if (uid == 0)
		ASSERT_EQ(0, seteuid(0));
}

TEST_F(child, fetch_fd)
{
	int fd, ret;

	fd = sys_pidfd_getfd(self->pidfd, self->remote_fd, 0);
	ASSERT_GE(fd, 0);

	ret = sys_kcmp(getpid(), self->pid, KCMP_FILE, fd, self->remote_fd);
	if (ret < 0 && errno == ENOSYS)
		SKIP(return, "kcmp() syscall not supported");
	EXPECT_EQ(ret, 0);

	ret = fcntl(fd, F_GETFD);
	ASSERT_GE(ret, 0);
	EXPECT_GE(ret & FD_CLOEXEC, 0);

	close(fd);
}

TEST_F(child, test_unknown_fd)
{
	int fd;

	fd = sys_pidfd_getfd(self->pidfd, UNKNOWN_FD, 0);
	EXPECT_EQ(-1, fd) {
		TH_LOG("getfd succeeded while fetching unknown fd");
	};
	EXPECT_EQ(EBADF, errno) {
		TH_LOG("%s: getfd did not get EBADF", strerror(errno));
	}
}

TEST(flags_set)
{
	ASSERT_EQ(-1, sys_pidfd_getfd(0, 0, 1));
	EXPECT_EQ(errno, EINVAL);
}

#if __NR_pidfd_getfd == -1
int main(void)
{
	fprintf(stderr, "__NR_pidfd_getfd undefined. The pidfd_getfd syscall is unavailable. Test aborting\n");
	return KSFT_SKIP;
}
#else
TEST_HARNESS_MAIN
#endif
