/* SPDX-License-Identifier: GPL-2.0 */
/*
 * Landlock test helpers
 *
 * Copyright © 2017-2020 Mickaël Salaün <mic@digikod.net>
 * Copyright © 2019-2020 ANSSI
 * Copyright © 2021 Microsoft Corporation
 */

#include <errno.h>
#include <linux/landlock.h>
#include <sys/capability.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

#include "../kselftest_harness.h"

#ifndef ARRAY_SIZE
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
#endif

/*
 * TEST_F_FORK() is useful when a test drop privileges but the corresponding
 * FIXTURE_TEARDOWN() requires them (e.g. to remove files from a directory
 * where write actions are denied).  For convenience, FIXTURE_TEARDOWN() is
 * also called when the test failed, but not when FIXTURE_SETUP() failed.  For
 * this to be possible, we must not call abort() but instead exit smoothly
 * (hence the step print).
 */
#define TEST_F_FORK(fixture_name, test_name) \
	static void fixture_name##_##test_name##_child( \
		struct __test_metadata *_metadata, \
		FIXTURE_DATA(fixture_name) *self, \
		const FIXTURE_VARIANT(fixture_name) *variant); \
	TEST_F(fixture_name, test_name) \
	{ \
		int status; \
		const pid_t child = fork(); \
		if (child < 0) \
			abort(); \
		if (child == 0) { \
			_metadata->no_print = 1; \
			fixture_name##_##test_name##_child(_metadata, self, variant); \
			if (_metadata->skip) \
				_exit(255); \
			if (_metadata->passed) \
				_exit(0); \
			_exit(_metadata->step); \
		} \
		if (child != waitpid(child, &status, 0)) \
			abort(); \
		if (WIFSIGNALED(status) || !WIFEXITED(status)) { \
			_metadata->passed = 0; \
			_metadata->step = 1; \
			return; \
		} \
		switch (WEXITSTATUS(status)) { \
		case 0: \
			_metadata->passed = 1; \
			break; \
		case 255: \
			_metadata->passed = 1; \
			_metadata->skip = 1; \
			break; \
		default: \
			_metadata->passed = 0; \
			_metadata->step = WEXITSTATUS(status); \
			break; \
		} \
	} \
	static void fixture_name##_##test_name##_child( \
		struct __test_metadata __attribute__((unused)) *_metadata, \
		FIXTURE_DATA(fixture_name) __attribute__((unused)) *self, \
		const FIXTURE_VARIANT(fixture_name) \
			__attribute__((unused)) *variant)

#ifndef landlock_create_ruleset
static inline int landlock_create_ruleset(
		const struct landlock_ruleset_attr *const attr,
		const size_t size, const __u32 flags)
{
	return syscall(__NR_landlock_create_ruleset, attr, size, flags);
}
#endif

#ifndef landlock_add_rule
static inline int landlock_add_rule(const int ruleset_fd,
		const enum landlock_rule_type rule_type,
		const void *const rule_attr, const __u32 flags)
{
	return syscall(__NR_landlock_add_rule, ruleset_fd, rule_type,
			rule_attr, flags);
}
#endif

#ifndef landlock_restrict_self
static inline int landlock_restrict_self(const int ruleset_fd,
		const __u32 flags)
{
	return syscall(__NR_landlock_restrict_self, ruleset_fd, flags);
}
#endif

static void _init_caps(struct __test_metadata *const _metadata, bool drop_all)
{
	cap_t cap_p;
	/* Only these three capabilities are useful for the tests. */
	const cap_value_t caps[] = {
		CAP_DAC_OVERRIDE,
		CAP_MKNOD,
		CAP_SYS_ADMIN,
		CAP_SYS_CHROOT,
	};

	cap_p = cap_get_proc();
	EXPECT_NE(NULL, cap_p) {
		TH_LOG("Failed to cap_get_proc: %s", strerror(errno));
	}
	EXPECT_NE(-1, cap_clear(cap_p)) {
		TH_LOG("Failed to cap_clear: %s", strerror(errno));
	}
	if (!drop_all) {
		EXPECT_NE(-1, cap_set_flag(cap_p, CAP_PERMITTED,
					ARRAY_SIZE(caps), caps, CAP_SET)) {
			TH_LOG("Failed to cap_set_flag: %s", strerror(errno));
		}
	}
	EXPECT_NE(-1, cap_set_proc(cap_p)) {
		TH_LOG("Failed to cap_set_proc: %s", strerror(errno));
	}
	EXPECT_NE(-1, cap_free(cap_p)) {
		TH_LOG("Failed to cap_free: %s", strerror(errno));
	}
}

/* We cannot put such helpers in a library because of kselftest_harness.h . */
__attribute__((__unused__))
static void disable_caps(struct __test_metadata *const _metadata)
{
	_init_caps(_metadata, false);
}

__attribute__((__unused__))
static void drop_caps(struct __test_metadata *const _metadata)
{
	_init_caps(_metadata, true);
}

static void _effective_cap(struct __test_metadata *const _metadata,
		const cap_value_t caps, const cap_flag_value_t value)
{
	cap_t cap_p;

	cap_p = cap_get_proc();
	EXPECT_NE(NULL, cap_p) {
		TH_LOG("Failed to cap_get_proc: %s", strerror(errno));
	}
	EXPECT_NE(-1, cap_set_flag(cap_p, CAP_EFFECTIVE, 1, &caps, value)) {
		TH_LOG("Failed to cap_set_flag: %s", strerror(errno));
	}
	EXPECT_NE(-1, cap_set_proc(cap_p)) {
		TH_LOG("Failed to cap_set_proc: %s", strerror(errno));
	}
	EXPECT_NE(-1, cap_free(cap_p)) {
		TH_LOG("Failed to cap_free: %s", strerror(errno));
	}
}

__attribute__((__unused__))
static void set_cap(struct __test_metadata *const _metadata,
		const cap_value_t caps)
{
	_effective_cap(_metadata, caps, CAP_SET);
}

__attribute__((__unused__))
static void clear_cap(struct __test_metadata *const _metadata,
		const cap_value_t caps)
{
	_effective_cap(_metadata, caps, CAP_CLEAR);
}
