// 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) {
			u32 *str_item;
			int str_loc = entry_size & 0xffff;

			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;
	unsigned long irq_flags;
	void *entry = NULL;
	int entry_size;
	u64 val = 0;
	int len;

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

	local_save_flags(irq_flags);
	tracing_generic_entry_update(entry, call->event.type, irq_flags,
				     preempt_count());

	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) {
				strlcpy(entry + field->offset, addr, field->size);
			} else if (field->filter_type == FILTER_DYN_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;

				strlcpy(entry + (entry_size - str_len), addr, str_len);
				str_item = (u32 *)(entry + field->offset);
				*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_data(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_generic,
	.read = event_inject_read,
	.write = event_inject_write,
};
