// SPDX-License-Identifier: GPL-2.0
/*
 * trace_events_inject - trace event injection
 *
 * Copyright (C) 2019 Cong Wang <cwang@twitter.com>
 */

#include <linux/module.h>
#include <linux/ctype.h>
#include <linux/mutex.h>
#include <linux/slab.h>
#include <linux/rculist.h>

#include "trace.h"

static int
trace_inject_entry(struct trace_event_file *file, void *rec, int len)
{
	struct trace_event_buffer fbuffer;
	int written = 0;
	void *entry;

	rcu_read_lock_sched();
	entry = trace_event_buffer_reserve(&fbuffer, file, len);
	if (entry) {
		memcpy(entry, rec, len);
		written = len;
		trace_event_buffer_commit(&fbuffer);
	}
	rcu_read_unlock_sched();

	return written;
}

static int
parse_field(char *str, struct trace_event_call *call,
	    struct ftrace_event_field **pf, u64 *pv)
{
	struct ftrace_event_field *field;
	char *field_name;
	int s, i = 0;
	int len;
	u64 val;

	if (!str[i])
		return 0;
	/* First find the field to associate to */
	while (isspace(str[i]))
		i++;
	s = i;
	while (isalnum(str[i]) || str[i] == '_')
		i++;
	len = i - s;
	if (!len)
		return -EINVAL;

	field_name = kmemdup_nul(str + s, len, GFP_KERNEL);
	if (!field_name)
		return -ENOMEM;
	field = trace_find_event_field(call, field_name);
	kfree(field_name);
	if (!field)
		return -ENOENT;

	*pf = field;
	while (isspace(str[i]))
		i++;
	if (str[i] != '=')
		return -EINVAL;
	i++;
	while (isspace(str[i]))
		i++;
	s = i;
	if (isdigit(str[i]) || str[i] == '-') {
		char *num, c;
		int ret;

		/* Make sure the field is not a string */
		if (is_string_field(field))
			return -EINVAL;

		if (str[i] == '-')
			i++;

		/* We allow 0xDEADBEEF */
		while (isalnum(str[i]))
			i++;
		num = str + s;
		c = str[i];
		if (c != '\0' && !isspace(c))
			return -EINVAL;
		str[i] = '\0';
		/* Make sure it is a value */
		if (field->is_signed)
			ret = kstrtoll(num, 0, &val);
		else
			ret = kstrtoull(num, 0, &val);
		str[i] = c;
		if (ret)
			return ret;

		*pv = val;
		return i;
	} else if (str[i] == '\'' || str[i] == '"') {
		char q = str[i];

		/* Make sure the field is OK for strings */
		if (!is_string_field(field))
			return -EINVAL;

		for (i++; str[i]; i++) {
			if (str[i] == '\\' && str[i + 1]) {
				i++;
				continue;
			}
			if (str[i] == q)
				break;
		}
		if (!str[i])
			return -EINVAL;

		/* Skip quotes */
		s++;
		len = i - s;
		if (len >= MAX_FILTER_STR_VAL)
			return -EINVAL;

		*pv = (unsigned long)(str + s);
		str[i] = 0;
		/* go past the last quote */
		i++;
		return i;
	}

	return -EINVAL;
}

static int trace_get_entry_size(struct trace_event_call *call)
{
	struct ftrace_event_field *field;
	struct list_head *head;
	int size = 0;

	head = trace_get_fields(call);
	list_for_each_entry(field, head, link) {
		if (field->size + field->offset > size)
			size = field->size + field->offset;
	}

	return size;
}

static void *trace_alloc_entry(struct trace_event_call *call, int *size)
{
	int entry_size = trace_get_entry_size(call);
	struct ftrace_event_field *field;
	struct list_head *head;
	void *entry = NULL;

	/* We need an extra '\0' at the end. */
	entry = kzalloc(entry_size + 1, GFP_KERNEL);
	if (!entry)
		return NULL;

	head = trace_get_fields(call);
	list_for_each_entry(field, head, link) {
		if (!is_string_field(field))
			continue;
		if (field->filter_type == FILTER_STATIC_STRING)
			continue;
		if (field->filter_type == FILTER_DYN_STRING ||
		    field->filter_type == FILTER_RDYN_STRING) {
			u32 *str_item;
			int str_loc = entry_size & 0xffff;

			if (field->filter_type == FILTER_RDYN_STRING)
				str_loc -= field->offset + field->size;

			str_item = (u32 *)(entry + field->offset);
			*str_item = str_loc; /* string length is 0. */
		} else {
			char **paddr;

			paddr = (char **)(entry + field->offset);
			*paddr = "";
		}
	}

	*size = entry_size + 1;
	return entry;
}

#define INJECT_STRING "STATIC STRING CAN NOT BE INJECTED"

/* Caller is responsible to free the *pentry. */
static int parse_entry(char *str, struct trace_event_call *call, void **pentry)
{
	struct ftrace_event_field *field;
	void *entry = NULL;
	int entry_size;
	u64 val = 0;
	int len;

	entry = trace_alloc_entry(call, &entry_size);
	*pentry = entry;
	if (!entry)
		return -ENOMEM;

	tracing_generic_entry_update(entry, call->event.type,
				     tracing_gen_ctx());

	while ((len = parse_field(str, call, &field, &val)) > 0) {
		if (is_function_field(field))
			return -EINVAL;

		if (is_string_field(field)) {
			char *addr = (char *)(unsigned long) val;

			if (field->filter_type == FILTER_STATIC_STRING) {
				strscpy(entry + field->offset, addr, field->size);
			} else if (field->filter_type == FILTER_DYN_STRING ||
				   field->filter_type == FILTER_RDYN_STRING) {
				int str_len = strlen(addr) + 1;
				int str_loc = entry_size & 0xffff;
				u32 *str_item;

				entry_size += str_len;
				*pentry = krealloc(entry, entry_size, GFP_KERNEL);
				if (!*pentry) {
					kfree(entry);
					return -ENOMEM;
				}
				entry = *pentry;

				strscpy(entry + (entry_size - str_len), addr, str_len);
				str_item = (u32 *)(entry + field->offset);
				if (field->filter_type == FILTER_RDYN_STRING)
					str_loc -= field->offset + field->size;
				*str_item = (str_len << 16) | str_loc;
			} else {
				char **paddr;

				paddr = (char **)(entry + field->offset);
				*paddr = INJECT_STRING;
			}
		} else {
			switch (field->size) {
			case 1: {
				u8 tmp = (u8) val;

				memcpy(entry + field->offset, &tmp, 1);
				break;
			}
			case 2: {
				u16 tmp = (u16) val;

				memcpy(entry + field->offset, &tmp, 2);
				break;
			}
			case 4: {
				u32 tmp = (u32) val;

				memcpy(entry + field->offset, &tmp, 4);
				break;
			}
			case 8:
				memcpy(entry + field->offset, &val, 8);
				break;
			default:
				return -EINVAL;
			}
		}

		str += len;
	}

	if (len < 0)
		return len;

	return entry_size;
}

static ssize_t
event_inject_write(struct file *filp, const char __user *ubuf, size_t cnt,
		   loff_t *ppos)
{
	struct trace_event_call *call;
	struct trace_event_file *file;
	int err = -ENODEV, size;
	void *entry = NULL;
	char *buf;

	if (cnt >= PAGE_SIZE)
		return -EINVAL;

	buf = memdup_user_nul(ubuf, cnt);
	if (IS_ERR(buf))
		return PTR_ERR(buf);
	strim(buf);

	mutex_lock(&event_mutex);
	file = event_file_file(filp);
	if (file) {
		call = file->event_call;
		size = parse_entry(buf, call, &entry);
		if (size < 0)
			err = size;
		else
			err = trace_inject_entry(file, entry, size);
	}
	mutex_unlock(&event_mutex);

	kfree(entry);
	kfree(buf);

	if (err < 0)
		return err;

	*ppos += err;
	return cnt;
}

static ssize_t
event_inject_read(struct file *file, char __user *buf, size_t size,
		  loff_t *ppos)
{
	return -EPERM;
}

const struct file_operations event_inject_fops = {
	.open = tracing_open_file_tr,
	.read = event_inject_read,
	.write = event_inject_write,
	.release = tracing_release_file_tr,
};
