// SPDX-License-Identifier: GPL-2.0
#define _GNU_SOURCE
#include <errno.h>
#include <fcntl.h>
#include <sched.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <asm/ioctls.h>
#include <sys/mount.h>
#include <sys/wait.h>
#include "kselftest.h"

static bool terminal_dup2(int duplicate, int original)
{
	int ret;

	ret = dup2(duplicate, original);
	if (ret < 0)
		return false;

	return true;
}

static int terminal_set_stdfds(int fd)
{
	int i;

	if (fd < 0)
		return 0;

	for (i = 0; i < 3; i++)
		if (!terminal_dup2(fd, (int[]){STDIN_FILENO, STDOUT_FILENO,
					       STDERR_FILENO}[i]))
			return -1;

	return 0;
}

static int login_pty(int fd)
{
	int ret;

	setsid();

	ret = ioctl(fd, TIOCSCTTY, NULL);
	if (ret < 0)
		return -1;

	ret = terminal_set_stdfds(fd);
	if (ret < 0)
		return -1;

	if (fd > STDERR_FILENO)
		close(fd);

	return 0;
}

static int wait_for_pid(pid_t pid)
{
	int status, ret;

again:
	ret = waitpid(pid, &status, 0);
	if (ret == -1) {
		if (errno == EINTR)
			goto again;
		return -1;
	}
	if (ret != pid)
		goto again;

	if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
		return -1;

	return 0;
}

static int resolve_procfd_symlink(int fd, char *buf, size_t buflen)
{
	int ret;
	char procfd[4096];

	ret = snprintf(procfd, 4096, "/proc/self/fd/%d", fd);
	if (ret < 0 || ret >= 4096)
		return -1;

	ret = readlink(procfd, buf, buflen);
	if (ret < 0 || (size_t)ret >= buflen)
		return -1;

	buf[ret] = '\0';

	return 0;
}

static int do_tiocgptpeer(char *ptmx, char *expected_procfd_contents)
{
	int ret;
	int master = -1, slave = -1, fret = -1;

	master = open(ptmx, O_RDWR | O_NOCTTY | O_CLOEXEC);
	if (master < 0) {
		fprintf(stderr, "Failed to open \"%s\": %s\n", ptmx,
			strerror(errno));
		return -1;
	}

	/*
	 * grantpt() makes assumptions about /dev/pts/ so ignore it. It's also
	 * not really needed.
	 */
	ret = unlockpt(master);
	if (ret < 0) {
		fprintf(stderr, "Failed to unlock terminal\n");
		goto do_cleanup;
	}

	slave = ioctl(master, TIOCGPTPEER, O_RDWR | O_NOCTTY | O_CLOEXEC);
	if (slave < 0) {
		if (errno == EINVAL) {
			fprintf(stderr, "TIOCGPTPEER is not supported. "
					"Skipping test.\n");
			fret = KSFT_SKIP;
		} else {
			fprintf(stderr,
				"Failed to perform TIOCGPTPEER ioctl\n");
			fret = EXIT_FAILURE;
		}
		goto do_cleanup;
	}

	pid_t pid = fork();
	if (pid < 0)
		goto do_cleanup;

	if (pid == 0) {
		char buf[4096];

		ret = login_pty(slave);
		if (ret < 0) {
			fprintf(stderr, "Failed to setup terminal\n");
			_exit(EXIT_FAILURE);
		}

		ret = resolve_procfd_symlink(STDIN_FILENO, buf, sizeof(buf));
		if (ret < 0) {
			fprintf(stderr, "Failed to retrieve pathname of pts "
					"slave file descriptor\n");
			_exit(EXIT_FAILURE);
		}

		if (strncmp(expected_procfd_contents, buf,
			    strlen(expected_procfd_contents)) != 0) {
			fprintf(stderr, "Received invalid contents for "
					"\"/proc/<pid>/fd/%d\" symlink: %s\n",
					STDIN_FILENO, buf);
			_exit(-1);
		}

		fprintf(stderr, "Contents of \"/proc/<pid>/fd/%d\" "
				"symlink are valid: %s\n", STDIN_FILENO, buf);

		_exit(EXIT_SUCCESS);
	}

	ret = wait_for_pid(pid);
	if (ret < 0)
		goto do_cleanup;

	fret = EXIT_SUCCESS;

do_cleanup:
	if (master >= 0)
		close(master);
	if (slave >= 0)
		close(slave);

	return fret;
}

static int verify_non_standard_devpts_mount(void)
{
	char *mntpoint;
	int ret = -1;
	char devpts[] = P_tmpdir "/devpts_fs_XXXXXX";
	char ptmx[] = P_tmpdir "/devpts_fs_XXXXXX/ptmx";

	ret = umount("/dev/pts");
	if (ret < 0) {
		fprintf(stderr, "Failed to unmount \"/dev/pts\": %s\n",
				strerror(errno));
		return -1;
	}

	(void)umount("/dev/ptmx");

	mntpoint = mkdtemp(devpts);
	if (!mntpoint) {
		fprintf(stderr, "Failed to create temporary mountpoint: %s\n",
				 strerror(errno));
		return -1;
	}

	ret = mount("devpts", mntpoint, "devpts", MS_NOSUID | MS_NOEXEC,
		    "newinstance,ptmxmode=0666,mode=0620,gid=5");
	if (ret < 0) {
		fprintf(stderr, "Failed to mount devpts fs to \"%s\" in new "
				"mount namespace: %s\n", mntpoint,
				strerror(errno));
		unlink(mntpoint);
		return -1;
	}

	ret = snprintf(ptmx, sizeof(ptmx), "%s/ptmx", devpts);
	if (ret < 0 || (size_t)ret >= sizeof(ptmx)) {
		unlink(mntpoint);
		return -1;
	}

	ret = do_tiocgptpeer(ptmx, mntpoint);
	unlink(mntpoint);
	if (ret < 0)
		return -1;

	return 0;
}

static int verify_ptmx_bind_mount(void)
{
	int ret;

	ret = mount("/dev/pts/ptmx", "/dev/ptmx", NULL, MS_BIND, NULL);
	if (ret < 0) {
		fprintf(stderr, "Failed to bind mount \"/dev/pts/ptmx\" to "
				"\"/dev/ptmx\" mount namespace\n");
		return -1;
	}

	ret = do_tiocgptpeer("/dev/ptmx", "/dev/pts/");
	if (ret < 0)
		return -1;

	return 0;
}

static int verify_invalid_ptmx_bind_mount(void)
{
	int ret;
	char mntpoint_fd;
	char ptmx[] = P_tmpdir "/devpts_ptmx_XXXXXX";

	mntpoint_fd = mkstemp(ptmx);
	if (mntpoint_fd < 0) {
		fprintf(stderr, "Failed to create temporary directory: %s\n",
				 strerror(errno));
		return -1;
	}

	ret = mount("/dev/pts/ptmx", ptmx, NULL, MS_BIND, NULL);
	close(mntpoint_fd);
	if (ret < 0) {
		fprintf(stderr, "Failed to bind mount \"/dev/pts/ptmx\" to "
				"\"%s\" mount namespace\n", ptmx);
		return -1;
	}

	ret = do_tiocgptpeer(ptmx, "/dev/pts/");
	if (ret == 0)
		return -1;

	return 0;
}

int main(int argc, char *argv[])
{
	int ret;

	if (!isatty(STDIN_FILENO)) {
		fprintf(stderr, "Standard input file descriptor is not attached "
				"to a terminal. Skipping test\n");
		exit(KSFT_SKIP);
	}

	ret = unshare(CLONE_NEWNS);
	if (ret < 0) {
		fprintf(stderr, "Failed to unshare mount namespace\n");
		exit(EXIT_FAILURE);
	}

	ret = mount("", "/", NULL, MS_PRIVATE | MS_REC, 0);
	if (ret < 0) {
		fprintf(stderr, "Failed to make \"/\" MS_PRIVATE in new mount "
				"namespace\n");
		exit(EXIT_FAILURE);
	}

	ret = verify_ptmx_bind_mount();
	if (ret < 0)
		exit(EXIT_FAILURE);

	ret = verify_invalid_ptmx_bind_mount();
	if (ret < 0)
		exit(EXIT_FAILURE);

	ret = verify_non_standard_devpts_mount();
	if (ret < 0)
		exit(EXIT_FAILURE);

	exit(EXIT_SUCCESS);
}
