/* Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#define _GNU_SOURCE

#include "util.h"

#include <ctype.h>
#include <errno.h>
#include <limits.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>

#include "libconstants.h"
#include "libsyscalls.h"

/*
 * These are syscalls used by the syslog() C library call.  You can find them
 * by running a simple test program.  See below for x86_64 behavior:
 * $ cat test.c
 * #include <syslog.h>
 * main() { syslog(0, "foo"); }
 * $ gcc test.c -static
 * $ strace ./a.out
 * ...
 * socket(PF_FILE, SOCK_DGRAM|SOCK_CLOEXEC, 0) = 3 <- look for socket connection
 * connect(...)                                    <- important
 * sendto(...)                                     <- important
 * exit_group(0)                                   <- finish!
 */
#if defined(__x86_64__)
#if defined(__ANDROID__)
const char *const log_syscalls[] = {"socket", "connect", "fcntl", "writev"};
#else
const char *const log_syscalls[] = {"socket", "connect", "sendto", "writev"};
#endif
#elif defined(__i386__)
#if defined(__ANDROID__)
const char *const log_syscalls[] = {"socketcall", "writev", "fcntl64",
				    "clock_gettime"};
#else
const char *const log_syscalls[] = {"socketcall", "time", "writev"};
#endif
#elif defined(__arm__)
#if defined(__ANDROID__)
const char *const log_syscalls[] = {"clock_gettime", "connect", "fcntl64",
				    "socket", "writev"};
#else
const char *const log_syscalls[] = {"socket", "connect", "gettimeofday", "send",
				    "writev"};
#endif
#elif defined(__aarch64__)
#if defined(__ANDROID__)
const char *const log_syscalls[] = {"connect", "fcntl", "sendto", "socket",
				    "writev"};
#else
const char *const log_syscalls[] = {"socket", "connect", "send", "writev"};
#endif
#elif defined(__powerpc__) || defined(__ia64__) || defined(__hppa__) ||        \
    defined(__sparc__) || defined(__mips__)
const char *const log_syscalls[] = {"socket", "connect", "send"};
#elif defined(__riscv)
const char *const log_syscalls[] = {"socket", "connect", "sendto"};
#else
#error "Unsupported platform"
#endif

const size_t log_syscalls_len = ARRAY_SIZE(log_syscalls);

/* clang-format off */
static struct logging_config_t {
	/* The logging system to use. The default is syslog. */
	enum logging_system_t logger;

	/* File descriptor to log to. Only used when logger is LOG_TO_FD. */
	int fd;

	/* Minimum priority to log. Only used when logger is LOG_TO_FD. */
	int min_priority;
} logging_config = {
	.logger = LOG_TO_SYSLOG,
};
/* clang-format on */

#if defined(USE_EXIT_ON_DIE)
#define do_abort() exit(1)
#else
#define do_abort() abort()
#endif

#if defined(__clang__)
#define attribute_no_optimize __attribute__((optnone))
#else
#define attribute_no_optimize __attribute__((__optimize__(0)))
#endif

/* Forces the compiler to perform no optimizations on |var|. */
static void attribute_no_optimize alias(const void *var)
{
	(void)var;
}

void do_fatal_log(int priority, const char *format, ...)
{
	va_list args, stack_args;
	va_start(args, format);
	va_copy(stack_args, args);
	if (logging_config.logger == LOG_TO_SYSLOG) {
		vsyslog(priority, format, args);
	} else {
		vdprintf(logging_config.fd, format, args);
		dprintf(logging_config.fd, "\n");
	}
	va_end(args);

	/*
	 * Write another copy of the first few characters of the message into a
	 * stack-based buffer so that it can appear in minidumps. Choosing a
	 * small-ish buffer size since breakpad will only pick up the first few
	 * kilobytes of each stack, so that will prevent this buffer from
	 * kicking out other stack frames.
	 */
	char log_line[512];
	vsnprintf(log_line, sizeof(log_line), format, stack_args);
	va_end(stack_args);
	alias(log_line);
	do_abort();
}

void do_log(int priority, const char *format, ...)
{
	if (logging_config.logger == LOG_TO_SYSLOG) {
		va_list args;
		va_start(args, format);
		vsyslog(priority, format, args);
		va_end(args);
		return;
	}

	if (logging_config.min_priority < priority)
		return;

	va_list args;
	va_start(args, format);
	vdprintf(logging_config.fd, format, args);
	va_end(args);
	dprintf(logging_config.fd, "\n");
}

/*
 * Returns the syscall nr and optionally populates the index in the pointer
 * |ind| if it is non-NULL.
 */
int lookup_syscall(const char *name, size_t *ind)
{
	size_t ind_tmp = 0;
	const struct syscall_entry *entry = syscall_table;
	for (; entry->name && entry->nr >= 0; ++entry) {
		if (!strcmp(entry->name, name)) {
			if (ind != NULL)
				*ind = ind_tmp;
			return entry->nr;
		}
		ind_tmp++;
	}
	if (ind != NULL)
		*ind = -1;
	return -1;
}

const char *lookup_syscall_name(int nr)
{
	const struct syscall_entry *entry = syscall_table;
	for (; entry->name && entry->nr >= 0; ++entry)
		if (entry->nr == nr)
			return entry->name;
	return NULL;
}

long int parse_single_constant(char *constant_str, char **endptr)
{
	const struct constant_entry *entry = constant_table;
	long int res = 0;
	for (; entry->name; ++entry) {
		if (!strcmp(entry->name, constant_str)) {
			*endptr = constant_str + strlen(constant_str);
			return entry->value;
		}
	}

	errno = 0;
	res = strtol(constant_str, endptr, 0);
	if (errno == ERANGE) {
		if (res == LONG_MAX) {
			/* See if the constant fits in an unsigned long int. */
			errno = 0;
			res = strtoul(constant_str, endptr, 0);
			if (errno == ERANGE) {
				/*
				 * On unsigned overflow, use the same convention
				 * as when strtol(3) finds no digits: set
				 * |*endptr| to |constant_str| and return 0.
				 */
				warn("unsigned overflow: '%s'", constant_str);
				*endptr = constant_str;
				return 0;
			}
		} else if (res == LONG_MIN) {
			/*
			 * Same for signed underflow: set |*endptr| to
			 * |constant_str| and return 0.
			 */
			warn("signed underflow: '%s'", constant_str);
			*endptr = constant_str;
			return 0;
		}
	}
	if (**endptr != '\0') {
		warn("trailing garbage after constant: '%s'", constant_str);
		*endptr = constant_str;
		return 0;
	}
	return res;
}

static char *tokenize_parenthesized_expression(char **stringp)
{
	char *ret = NULL, *found = NULL;
	size_t paren_count = 1;

	/* If the string is NULL, there are no parens to be found. */
	if (stringp == NULL || *stringp == NULL)
		return NULL;

	/* If the string is not on an open paren, the results are undefined. */
	if (**stringp != '(')
		return NULL;

	for (found = *stringp + 1; *found; ++found) {
		switch (*found) {
		case '(':
			++paren_count;
			break;
		case ')':
			--paren_count;
			if (!paren_count) {
				*found = '\0';
				ret = *stringp + 1;
				*stringp = found + 1;
				return ret;
			}
			break;
		}
	}

	/* We got to the end without finding the closing paren. */
	warn("unclosed parenthesis: '%s'", *stringp);
	return NULL;
}

long int parse_constant(char *constant_str, char **endptr)
{
	long int value = 0, current_value;
	char *group, *lastpos = constant_str;

	/*
	 * If |endptr| is provided, parsing errors are signaled as |endptr|
	 * pointing to |constant_str|.
	 */
	if (endptr)
		*endptr = constant_str;

	/*
	 * Try to parse constant expressions. Valid constant expressions are:
	 *
	 * - A number that can be parsed with strtol(3).
	 * - A named constant expression.
	 * - A parenthesized, valid constant expression.
	 * - A valid constant expression prefixed with the unary bitwise
	 *   complement operator ~.
	 * - A series of valid constant expressions separated by pipes.  Note
	 *   that since |constant_str| is an atom, there can be no spaces
	 *   between the constant and the pipe.
	 *
	 * If there is an error parsing any of the constants, the whole process
	 * fails.
	 */
	while (constant_str && *constant_str) {
		bool negate = false;
		if (*constant_str == '~') {
			negate = true;
			++constant_str;
		}
		if (*constant_str == '(') {
			group =
			    tokenize_parenthesized_expression(&constant_str);
			if (group == NULL)
				return 0;
			char *end = group;
			/* Recursively parse the parenthesized subexpression. */
			current_value = parse_constant(group, &end);
			if (end == group)
				return 0;
			if (constant_str && *constant_str) {
				/*
				 * If this is not the end of the atom, there
				 * should be another | followed by more stuff.
				 */
				if (*constant_str != '|') {
					warn("unterminated constant "
					     "expression: '%s'",
					     constant_str);
					return 0;
				}
				++constant_str;
				if (*constant_str == '\0') {
					warn("unterminated constant "
					     "expression: '%s'",
					     constant_str);
					return 0;
				}
			}
			lastpos = end;
		} else {
			group = tokenize(&constant_str, "|");
			char *end = group;
			current_value = parse_single_constant(group, &end);
			if (end == group)
				return 0;
			lastpos = end;
		}
		if (negate)
			current_value = ~current_value;
		value |= current_value;
	}
	if (endptr)
		*endptr = lastpos;
	return value;
}

/*
 * parse_size, specified as a string with a decimal number in bytes,
 * possibly with one 1-character suffix like "10K" or "6G".
 * Assumes both pointers are non-NULL.
 *
 * Returns 0 on success, negative errno on failure.
 * Only writes to result on success.
 */
int parse_size(size_t *result, const char *sizespec)
{
	const char prefixes[] = "KMGTPE";
	size_t i, multiplier = 1, nsize, size = 0;
	unsigned long long parsed;
	const size_t len = strlen(sizespec);
	char *end;

	if (len == 0 || sizespec[0] == '-')
		return -EINVAL;

	for (i = 0; i < sizeof(prefixes); ++i) {
		if (sizespec[len - 1] == prefixes[i]) {
#if __WORDSIZE == 32
			if (i >= 3)
				return -ERANGE;
#endif
			multiplier = 1024;
			while (i-- > 0)
				multiplier *= 1024;
			break;
		}
	}

	/* We only need size_t but strtoul(3) is too small on IL32P64. */
	parsed = strtoull(sizespec, &end, 10);
	if (parsed == ULLONG_MAX)
		return -errno;
	if (parsed >= SIZE_MAX)
		return -ERANGE;
	if ((multiplier != 1 && end != sizespec + len - 1) ||
	    (multiplier == 1 && end != sizespec + len))
		return -EINVAL;
	size = (size_t)parsed;

	nsize = size * multiplier;
	if (nsize / multiplier != size)
		return -ERANGE;
	*result = nsize;
	return 0;
}

char *strip(char *s)
{
	char *end;
	while (*s && isblank(*s))
		s++;
	end = s + strlen(s) - 1;
	while (end >= s && *end && (isblank(*end) || *end == '\n'))
		end--;
	*(end + 1) = '\0';
	return s;
}

char *tokenize(char **stringp, const char *delim)
{
	char *ret = NULL;

	/* If the string is NULL, there are no tokens to be found. */
	if (stringp == NULL || *stringp == NULL)
		return NULL;

	/*
	 * If the delimiter is NULL or empty,
	 * the full string makes up the only token.
	 */
	if (delim == NULL || *delim == '\0') {
		ret = *stringp;
		*stringp = NULL;
		return ret;
	}

	char *found = strstr(*stringp, delim);
	if (!found) {
		/*
		 * The delimiter was not found, so the full string
		 * makes up the only token, and we're done.
		 */
		ret = *stringp;
		*stringp = NULL;
	} else {
		/* There's a token here, possibly empty.  That's OK. */
		*found = '\0';
		ret = *stringp;
		*stringp = found + strlen(delim);
	}

	return ret;
}

char *path_join(const char *external_path, const char *internal_path)
{
	char *path = NULL;
	return asprintf(&path, "%s/%s", external_path, internal_path) < 0
		   ? NULL
		   : path;
}

void *consumebytes(size_t length, char **buf, size_t *buflength)
{
	char *p = *buf;
	if (length > *buflength)
		return NULL;
	*buf += length;
	*buflength -= length;
	return p;
}

char *consumestr(char **buf, size_t *buflength)
{
	size_t len = strnlen(*buf, *buflength);
	if (len == *buflength)
		/* There's no null-terminator. */
		return NULL;
	return consumebytes(len + 1, buf, buflength);
}

void init_logging(enum logging_system_t logger, int fd, int min_priority)
{
	logging_config.logger = logger;
	logging_config.fd = fd;
	logging_config.min_priority = min_priority;
}

void minijail_free_env(char **env)
{
	if (!env)
		return;

	for (char **entry = env; *entry; ++entry) {
		free(*entry);
	}

	free(env);
}

char **minijail_copy_env(char *const *env)
{
	if (!env)
		return calloc(1, sizeof(char *));

	int len = 0;
	while (env[len])
		++len;

	char **copy = calloc(len + 1, sizeof(char *));
	if (!copy)
		return NULL;

	for (char **entry = copy; *env; ++env, ++entry) {
		*entry = strdup(*env);
		if (!*entry) {
			minijail_free_env(copy);
			return NULL;
		}
	}

	return copy;
}

/*
 * Utility function used by minijail_setenv, minijail_unsetenv and
 * minijail_getenv, returns true if |name| is found, false if not.
 * If found, |*i| is |name|'s index. If not, |*i| is the length of |envp|.
 */
static bool getenv_index(char **envp, const char *name, int *i) {
	if (!envp || !name || !i)
		return false;

	size_t name_len = strlen(name);
	for (*i = 0; envp[*i]; ++(*i)) {
		/*
		 * If we find a match the size of |name|, we must check
		 * that the next character is a '=', indicating that
		 * the full varname of envp[i] is exactly |name| and
		 * not just happening to start with |name|.
		 */
		if (!strncmp(envp[*i], name, name_len) &&
		    (envp[*i][name_len] == '=')) {
			return true;
		}
	}
	/* No match found, |*i| contains the number of elements in |envp|. */
	return false;
}

int minijail_setenv(char ***env, const char *name, const char *value,
		    int overwrite)
{
	if (!env || !*env || !name || !*name || !value)
		return EINVAL;

	char **dest = NULL;
	int i;

	/* Look in env to check if this var name already exists. */
	if (getenv_index(*env, name, &i)) {
		if (!overwrite)
			return 0;
		dest = &(*env)[i];
	}

	char *new_entry = NULL;
	if (asprintf(&new_entry, "%s=%s", name, value) == -1)
		return ENOMEM;

	if (dest) {
		free(*dest);
		*dest = new_entry;
		return 0;
	}

	/* getenv_index has set |i| to the length of |env|. */
	++i;
	char **new_env = realloc(*env, (i + 1) * sizeof(char *));
	if (!new_env) {
		free(new_entry);
		return ENOMEM;
	}

	new_env[i - 1] = new_entry;
	new_env[i] = NULL;
	*env = new_env;
	return 0;
}

/*
 * This is like getline() but supports line wrapping with \.
 */
ssize_t getmultiline(char **lineptr, size_t *n, FILE *stream)
{
	ssize_t ret = getline(lineptr, n, stream);
	if (ret < 0)
		return ret;

	char *line = *lineptr;
	/* Eat the newline to make processing below easier. */
	if (ret > 0 && line[ret - 1] == '\n')
		line[--ret] = '\0';

	/* If the line doesn't end in a backslash, we're done. */
	if (ret <= 0 || line[ret - 1] != '\\')
		return ret;

	/* This line ends in a backslash. Get the nextline. */
	line[--ret] = '\0';
	size_t next_n = 0;
	attribute_cleanup_str char *next_line = NULL;
	ssize_t next_ret = getmultiline(&next_line, &next_n, stream);
	if (next_ret == -1) {
		/* We couldn't fully read the line, so return an error. */
		return -1;
	}

	/* Merge the lines. */
	*n = ret + next_ret + 2;
	line = realloc(line, *n);
	if (!line)
		return -1;
	line[ret] = ' ';
	memcpy(&line[ret + 1], next_line, next_ret + 1);
	*lineptr = line;
	return *n - 1;
}

char *minijail_getenv(char **envp, const char *name) {
	if (!envp || !name)
		return NULL;

	int i;
	if (!getenv_index(envp, name, &i))
		return NULL;

	/* Return a ptr to the value after the '='. */
	return envp[i] + strlen(name) + 1;
}

bool minijail_unsetenv(char **envp, const char *name)
{
	if (!envp || !name)
		return false;

	int i;
	if (!getenv_index(envp, name, &i))
		return false;

	/* We found a match, replace it by the last entry of the array. */
	int last;
	for (last = i; envp[last]; ++last)
		continue;
	--last;
	envp[i] = envp[last];
	envp[last] = NULL;

	return true;
}
