// SPDX-License-Identifier: GPL-2.0
/*
 * KMSAN compiler API.
 *
 * This file implements __msan_XXX hooks that Clang inserts into the code
 * compiled with -fsanitize=kernel-memory.
 * See Documentation/dev-tools/kmsan.rst for more information on how KMSAN
 * instrumentation works.
 *
 * Copyright (C) 2017-2022 Google LLC
 * Author: Alexander Potapenko <glider@google.com>
 *
 */

#include "kmsan.h"
#include <linux/gfp.h>
#include <linux/kmsan.h>
#include <linux/kmsan_string.h>
#include <linux/mm.h>
#include <linux/uaccess.h>

static inline bool is_bad_asm_addr(void *addr, uintptr_t size, bool is_store)
{
	if (IS_ENABLED(CONFIG_ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE) &&
	    (u64)addr < TASK_SIZE)
		return true;
	if (!kmsan_get_metadata(addr, KMSAN_META_SHADOW))
		return true;
	return false;
}

static inline struct shadow_origin_ptr
get_shadow_origin_ptr(void *addr, u64 size, bool store)
{
	unsigned long ua_flags = user_access_save();
	struct shadow_origin_ptr ret;

	ret = kmsan_get_shadow_origin_ptr(addr, size, store);
	user_access_restore(ua_flags);
	return ret;
}

/*
 * KMSAN instrumentation functions follow. They are not declared elsewhere in
 * the kernel code, so they are preceded by prototypes, to silence
 * -Wmissing-prototypes warnings.
 */

/* Get shadow and origin pointers for a memory load with non-standard size. */
struct shadow_origin_ptr __msan_metadata_ptr_for_load_n(void *addr,
							uintptr_t size);
struct shadow_origin_ptr __msan_metadata_ptr_for_load_n(void *addr,
							uintptr_t size)
{
	return get_shadow_origin_ptr(addr, size, /*store*/ false);
}
EXPORT_SYMBOL(__msan_metadata_ptr_for_load_n);

/* Get shadow and origin pointers for a memory store with non-standard size. */
struct shadow_origin_ptr __msan_metadata_ptr_for_store_n(void *addr,
							 uintptr_t size);
struct shadow_origin_ptr __msan_metadata_ptr_for_store_n(void *addr,
							 uintptr_t size)
{
	return get_shadow_origin_ptr(addr, size, /*store*/ true);
}
EXPORT_SYMBOL(__msan_metadata_ptr_for_store_n);

/*
 * Declare functions that obtain shadow/origin pointers for loads and stores
 * with fixed size.
 */
#define DECLARE_METADATA_PTR_GETTER(size)                                  \
	struct shadow_origin_ptr __msan_metadata_ptr_for_load_##size(      \
		void *addr);                                               \
	struct shadow_origin_ptr __msan_metadata_ptr_for_load_##size(      \
		void *addr)                                                \
	{                                                                  \
		return get_shadow_origin_ptr(addr, size, /*store*/ false); \
	}                                                                  \
	EXPORT_SYMBOL(__msan_metadata_ptr_for_load_##size);                \
	struct shadow_origin_ptr __msan_metadata_ptr_for_store_##size(     \
		void *addr);                                               \
	struct shadow_origin_ptr __msan_metadata_ptr_for_store_##size(     \
		void *addr)                                                \
	{                                                                  \
		return get_shadow_origin_ptr(addr, size, /*store*/ true);  \
	}                                                                  \
	EXPORT_SYMBOL(__msan_metadata_ptr_for_store_##size)

DECLARE_METADATA_PTR_GETTER(1);
DECLARE_METADATA_PTR_GETTER(2);
DECLARE_METADATA_PTR_GETTER(4);
DECLARE_METADATA_PTR_GETTER(8);

/*
 * Handle a memory store performed by inline assembly. KMSAN conservatively
 * attempts to unpoison the outputs of asm() directives to prevent false
 * positives caused by missed stores.
 *
 * __msan_instrument_asm_store() may be called for inline assembly code when
 * entering or leaving IRQ. We omit the check for kmsan_in_runtime() to ensure
 * the memory written to in these cases is also marked as initialized.
 */
void __msan_instrument_asm_store(void *addr, uintptr_t size);
void __msan_instrument_asm_store(void *addr, uintptr_t size)
{
	unsigned long ua_flags;

	if (!kmsan_enabled)
		return;

	ua_flags = user_access_save();
	/*
	 * Most of the accesses are below 32 bytes. The exceptions so far are
	 * clwb() (64 bytes), FPU state (512 bytes) and chsc() (4096 bytes).
	 */
	if (size > 4096) {
		WARN_ONCE(1, "assembly store size too big: %ld\n", size);
		size = 8;
	}
	if (is_bad_asm_addr(addr, size, /*is_store*/ true)) {
		user_access_restore(ua_flags);
		return;
	}
	/* Unpoisoning the memory on best effort. */
	kmsan_internal_unpoison_memory(addr, size, /*checked*/ false);
	user_access_restore(ua_flags);
}
EXPORT_SYMBOL(__msan_instrument_asm_store);

/*
 * KMSAN instrumentation pass replaces LLVM memcpy, memmove and memset
 * intrinsics with calls to respective __msan_ functions. We use
 * get_param0_metadata() and set_retval_metadata() to store the shadow/origin
 * values for the destination argument of these functions and use them for the
 * functions' return values.
 */
static inline void get_param0_metadata(u64 *shadow,
				       depot_stack_handle_t *origin)
{
	struct kmsan_ctx *ctx = kmsan_get_context();

	*shadow = *(u64 *)(ctx->cstate.param_tls);
	*origin = ctx->cstate.param_origin_tls[0];
}

static inline void set_retval_metadata(u64 shadow, depot_stack_handle_t origin)
{
	struct kmsan_ctx *ctx = kmsan_get_context();

	*(u64 *)(ctx->cstate.retval_tls) = shadow;
	ctx->cstate.retval_origin_tls = origin;
}

/* Handle llvm.memmove intrinsic. */
void *__msan_memmove(void *dst, const void *src, uintptr_t n);
void *__msan_memmove(void *dst, const void *src, uintptr_t n)
{
	depot_stack_handle_t origin;
	void *result;
	u64 shadow;

	get_param0_metadata(&shadow, &origin);
	result = __memmove(dst, src, n);
	if (!n)
		/* Some people call memmove() with zero length. */
		return result;
	if (!kmsan_enabled || kmsan_in_runtime())
		return result;

	kmsan_enter_runtime();
	kmsan_internal_memmove_metadata(dst, (void *)src, n);
	kmsan_leave_runtime();

	set_retval_metadata(shadow, origin);
	return result;
}
EXPORT_SYMBOL(__msan_memmove);

/* Handle llvm.memcpy intrinsic. */
void *__msan_memcpy(void *dst, const void *src, uintptr_t n);
void *__msan_memcpy(void *dst, const void *src, uintptr_t n)
{
	depot_stack_handle_t origin;
	void *result;
	u64 shadow;

	get_param0_metadata(&shadow, &origin);
	result = __memcpy(dst, src, n);
	if (!n)
		/* Some people call memcpy() with zero length. */
		return result;

	if (!kmsan_enabled || kmsan_in_runtime())
		return result;

	kmsan_enter_runtime();
	/* Using memmove instead of memcpy doesn't affect correctness. */
	kmsan_internal_memmove_metadata(dst, (void *)src, n);
	kmsan_leave_runtime();

	set_retval_metadata(shadow, origin);
	return result;
}
EXPORT_SYMBOL(__msan_memcpy);

/* Handle llvm.memset intrinsic. */
void *__msan_memset(void *dst, int c, uintptr_t n);
void *__msan_memset(void *dst, int c, uintptr_t n)
{
	depot_stack_handle_t origin;
	void *result;
	u64 shadow;

	get_param0_metadata(&shadow, &origin);
	result = __memset(dst, c, n);
	if (!kmsan_enabled || kmsan_in_runtime())
		return result;

	kmsan_enter_runtime();
	/*
	 * Clang doesn't pass parameter metadata here, so it is impossible to
	 * use shadow of @c to set up the shadow for @dst.
	 */
	kmsan_internal_unpoison_memory(dst, n, /*checked*/ false);
	kmsan_leave_runtime();

	set_retval_metadata(shadow, origin);
	return result;
}
EXPORT_SYMBOL(__msan_memset);

/*
 * Create a new origin from an old one. This is done when storing an
 * uninitialized value to memory. When reporting an error, KMSAN unrolls and
 * prints the whole chain of stores that preceded the use of this value.
 */
depot_stack_handle_t __msan_chain_origin(depot_stack_handle_t origin);
depot_stack_handle_t __msan_chain_origin(depot_stack_handle_t origin)
{
	depot_stack_handle_t ret = 0;
	unsigned long ua_flags;

	if (!kmsan_enabled || kmsan_in_runtime())
		return ret;

	ua_flags = user_access_save();

	/* Creating new origins may allocate memory. */
	kmsan_enter_runtime();
	ret = kmsan_internal_chain_origin(origin);
	kmsan_leave_runtime();
	user_access_restore(ua_flags);
	return ret;
}
EXPORT_SYMBOL(__msan_chain_origin);

/* Poison a local variable when entering a function. */
void __msan_poison_alloca(void *address, uintptr_t size, char *descr);
void __msan_poison_alloca(void *address, uintptr_t size, char *descr)
{
	depot_stack_handle_t handle;
	unsigned long entries[4];
	unsigned long ua_flags;

	if (!kmsan_enabled || kmsan_in_runtime())
		return;

	ua_flags = user_access_save();
	entries[0] = KMSAN_ALLOCA_MAGIC_ORIGIN;
	entries[1] = (u64)descr;
	entries[2] = (u64)__builtin_return_address(0);
	/*
	 * With frame pointers enabled, it is possible to quickly fetch the
	 * second frame of the caller stack without calling the unwinder.
	 * Without them, simply do not bother.
	 */
	if (IS_ENABLED(CONFIG_UNWINDER_FRAME_POINTER))
		entries[3] = (u64)__builtin_return_address(1);
	else
		entries[3] = 0;

	/* stack_depot_save() may allocate memory. */
	kmsan_enter_runtime();
	handle = stack_depot_save(entries, ARRAY_SIZE(entries), __GFP_HIGH);
	kmsan_leave_runtime();

	kmsan_internal_set_shadow_origin(address, size, -1, handle,
					 /*checked*/ true);
	user_access_restore(ua_flags);
}
EXPORT_SYMBOL(__msan_poison_alloca);

/* Unpoison a local variable. */
void __msan_unpoison_alloca(void *address, uintptr_t size);
void __msan_unpoison_alloca(void *address, uintptr_t size)
{
	if (!kmsan_enabled || kmsan_in_runtime())
		return;

	kmsan_enter_runtime();
	kmsan_internal_unpoison_memory(address, size, /*checked*/ true);
	kmsan_leave_runtime();
}
EXPORT_SYMBOL(__msan_unpoison_alloca);

/*
 * Report that an uninitialized value with the given origin was used in a way
 * that constituted undefined behavior.
 */
void __msan_warning(u32 origin);
void __msan_warning(u32 origin)
{
	if (!kmsan_enabled || kmsan_in_runtime())
		return;
	kmsan_enter_runtime();
	kmsan_report(origin, /*address*/ NULL, /*size*/ 0,
		     /*off_first*/ 0, /*off_last*/ 0, /*user_addr*/ NULL,
		     REASON_ANY);
	kmsan_leave_runtime();
}
EXPORT_SYMBOL(__msan_warning);

/*
 * At the beginning of an instrumented function, obtain the pointer to
 * `struct kmsan_context_state` holding the metadata for function parameters.
 */
struct kmsan_context_state *__msan_get_context_state(void);
struct kmsan_context_state *__msan_get_context_state(void)
{
	return &kmsan_get_context()->cstate;
}
EXPORT_SYMBOL(__msan_get_context_state);
