// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright IBM Corporation, 2021
 *
 * Author: Mike Rapoport <rppt@linux.ibm.com>
 */

#define _GNU_SOURCE
#include <sys/uio.h>
#include <sys/mman.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <sys/ptrace.h>
#include <sys/syscall.h>
#include <sys/resource.h>
#include <sys/capability.h>

#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <stdio.h>

#include "../kselftest.h"

#define fail(fmt, ...) ksft_test_result_fail(fmt, ##__VA_ARGS__)
#define pass(fmt, ...) ksft_test_result_pass(fmt, ##__VA_ARGS__)
#define skip(fmt, ...) ksft_test_result_skip(fmt, ##__VA_ARGS__)

#ifdef __NR_memfd_secret

#define PATTERN	0x55

static const int prot = PROT_READ | PROT_WRITE;
static const int mode = MAP_SHARED;

static unsigned long page_size;
static unsigned long mlock_limit_cur;
static unsigned long mlock_limit_max;

static int memfd_secret(unsigned int flags)
{
	return syscall(__NR_memfd_secret, flags);
}

static void test_file_apis(int fd)
{
	char buf[64];

	if ((read(fd, buf, sizeof(buf)) >= 0) ||
	    (write(fd, buf, sizeof(buf)) >= 0) ||
	    (pread(fd, buf, sizeof(buf), 0) >= 0) ||
	    (pwrite(fd, buf, sizeof(buf), 0) >= 0))
		fail("unexpected file IO\n");
	else
		pass("file IO is blocked as expected\n");
}

static void test_mlock_limit(int fd)
{
	size_t len;
	char *mem;

	len = mlock_limit_cur;
	mem = mmap(NULL, len, prot, mode, fd, 0);
	if (mem == MAP_FAILED) {
		fail("unable to mmap secret memory\n");
		return;
	}
	munmap(mem, len);

	len = mlock_limit_max * 2;
	mem = mmap(NULL, len, prot, mode, fd, 0);
	if (mem != MAP_FAILED) {
		fail("unexpected mlock limit violation\n");
		munmap(mem, len);
		return;
	}

	pass("mlock limit is respected\n");
}

static void try_process_vm_read(int fd, int pipefd[2])
{
	struct iovec liov, riov;
	char buf[64];
	char *mem;

	if (read(pipefd[0], &mem, sizeof(mem)) < 0) {
		fail("pipe write: %s\n", strerror(errno));
		exit(KSFT_FAIL);
	}

	liov.iov_len = riov.iov_len = sizeof(buf);
	liov.iov_base = buf;
	riov.iov_base = mem;

	if (process_vm_readv(getppid(), &liov, 1, &riov, 1, 0) < 0) {
		if (errno == ENOSYS)
			exit(KSFT_SKIP);
		exit(KSFT_PASS);
	}

	exit(KSFT_FAIL);
}

static void try_ptrace(int fd, int pipefd[2])
{
	pid_t ppid = getppid();
	int status;
	char *mem;
	long ret;

	if (read(pipefd[0], &mem, sizeof(mem)) < 0) {
		perror("pipe write");
		exit(KSFT_FAIL);
	}

	ret = ptrace(PTRACE_ATTACH, ppid, 0, 0);
	if (ret) {
		perror("ptrace_attach");
		exit(KSFT_FAIL);
	}

	ret = waitpid(ppid, &status, WUNTRACED);
	if ((ret != ppid) || !(WIFSTOPPED(status))) {
		fprintf(stderr, "weird waitppid result %ld stat %x\n",
			ret, status);
		exit(KSFT_FAIL);
	}

	if (ptrace(PTRACE_PEEKDATA, ppid, mem, 0))
		exit(KSFT_PASS);

	exit(KSFT_FAIL);
}

static void check_child_status(pid_t pid, const char *name)
{
	int status;

	waitpid(pid, &status, 0);

	if (WIFEXITED(status) && WEXITSTATUS(status) == KSFT_SKIP) {
		skip("%s is not supported\n", name);
		return;
	}

	if ((WIFEXITED(status) && WEXITSTATUS(status) == KSFT_PASS) ||
	    WIFSIGNALED(status)) {
		pass("%s is blocked as expected\n", name);
		return;
	}

	fail("%s: unexpected memory access\n", name);
}

static void test_remote_access(int fd, const char *name,
			       void (*func)(int fd, int pipefd[2]))
{
	int pipefd[2];
	pid_t pid;
	char *mem;

	if (pipe(pipefd)) {
		fail("pipe failed: %s\n", strerror(errno));
		return;
	}

	pid = fork();
	if (pid < 0) {
		fail("fork failed: %s\n", strerror(errno));
		return;
	}

	if (pid == 0) {
		func(fd, pipefd);
		return;
	}

	mem = mmap(NULL, page_size, prot, mode, fd, 0);
	if (mem == MAP_FAILED) {
		fail("Unable to mmap secret memory\n");
		return;
	}

	ftruncate(fd, page_size);
	memset(mem, PATTERN, page_size);

	if (write(pipefd[1], &mem, sizeof(mem)) < 0) {
		fail("pipe write: %s\n", strerror(errno));
		return;
	}

	check_child_status(pid, name);
}

static void test_process_vm_read(int fd)
{
	test_remote_access(fd, "process_vm_read", try_process_vm_read);
}

static void test_ptrace(int fd)
{
	test_remote_access(fd, "ptrace", try_ptrace);
}

static int set_cap_limits(rlim_t max)
{
	struct rlimit new;
	cap_t cap = cap_init();

	new.rlim_cur = max;
	new.rlim_max = max;
	if (setrlimit(RLIMIT_MEMLOCK, &new)) {
		perror("setrlimit() returns error");
		return -1;
	}

	/* drop capabilities including CAP_IPC_LOCK */
	if (cap_set_proc(cap)) {
		perror("cap_set_proc() returns error");
		return -2;
	}

	return 0;
}

static void prepare(void)
{
	struct rlimit rlim;

	page_size = sysconf(_SC_PAGE_SIZE);
	if (!page_size)
		ksft_exit_fail_msg("Failed to get page size %s\n",
				   strerror(errno));

	if (getrlimit(RLIMIT_MEMLOCK, &rlim))
		ksft_exit_fail_msg("Unable to detect mlock limit: %s\n",
				   strerror(errno));

	mlock_limit_cur = rlim.rlim_cur;
	mlock_limit_max = rlim.rlim_max;

	printf("page_size: %ld, mlock.soft: %ld, mlock.hard: %ld\n",
	       page_size, mlock_limit_cur, mlock_limit_max);

	if (page_size > mlock_limit_cur)
		mlock_limit_cur = page_size;
	if (page_size > mlock_limit_max)
		mlock_limit_max = page_size;

	if (set_cap_limits(mlock_limit_max))
		ksft_exit_fail_msg("Unable to set mlock limit: %s\n",
				   strerror(errno));
}

#define NUM_TESTS 4

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

	prepare();

	ksft_print_header();
	ksft_set_plan(NUM_TESTS);

	fd = memfd_secret(0);
	if (fd < 0) {
		if (errno == ENOSYS)
			ksft_exit_skip("memfd_secret is not supported\n");
		else
			ksft_exit_fail_msg("memfd_secret failed: %s\n",
					   strerror(errno));
	}

	test_mlock_limit(fd);
	test_file_apis(fd);
	test_process_vm_read(fd);
	test_ptrace(fd);

	close(fd);

	ksft_exit(!ksft_get_fail_cnt());
}

#else /* __NR_memfd_secret */

int main(int argc, char *argv[])
{
	printf("skip: skipping memfd_secret test (missing __NR_memfd_secret)\n");
	return KSFT_SKIP;
}

#endif /* __NR_memfd_secret */
