linux/drivers/misc/lkdtm/usercopy.c

// SPDX-License-Identifier: GPL-2.0
/*
 * This is for all the tests related to copy_to_user() and copy_from_user()
 * hardening.
 */
#include "lkdtm.h"
#include <linux/slab.h>
#include <linux/highmem.h>
#include <linux/vmalloc.h>
#include <linux/sched/task_stack.h>
#include <linux/mman.h>
#include <linux/uaccess.h>
#include <asm/cacheflush.h>

/*
 * Many of the tests here end up using const sizes, but those would
 * normally be ignored by hardened usercopy, so force the compiler
 * into choosing the non-const path to make sure we trigger the
 * hardened usercopy checks by added "unconst" to all the const copies,
 * and making sure "cache_size" isn't optimized into a const.
 */
static volatile size_t unconst;
static volatile size_t cache_size =;
static struct kmem_cache *whitelist_cache;

static const unsigned char test_text[] =;

/*
 * Instead of adding -Wno-return-local-addr, just pass the stack address
 * through a function to obfuscate it from the compiler.
 */
static noinline unsigned char *trick_compiler(unsigned char *stack)
{}

static noinline unsigned char *do_usercopy_stack_callee(int value)
{}

static noinline void do_usercopy_stack(bool to_user, bool bad_frame)
{}

/*
 * This checks for whole-object size validation with hardened usercopy,
 * with or without usercopy whitelisting.
 */
static void do_usercopy_slab_size(bool to_user)
{}

/*
 * This checks for the specific whitelist window within an object. If this
 * test passes, then do_usercopy_slab_size() tests will pass too.
 */
static void do_usercopy_slab_whitelist(bool to_user)
{}

/* Callable tests. */
static void lkdtm_USERCOPY_SLAB_SIZE_TO(void)
{}

static void lkdtm_USERCOPY_SLAB_SIZE_FROM(void)
{}

static void lkdtm_USERCOPY_SLAB_WHITELIST_TO(void)
{}

static void lkdtm_USERCOPY_SLAB_WHITELIST_FROM(void)
{}

static void lkdtm_USERCOPY_STACK_FRAME_TO(void)
{}

static void lkdtm_USERCOPY_STACK_FRAME_FROM(void)
{}

static void lkdtm_USERCOPY_STACK_BEYOND(void)
{}

static void lkdtm_USERCOPY_KERNEL(void)
{}

/*
 * This expects "kaddr" to point to a PAGE_SIZE allocation, which means
 * a more complete test that would include copy_from_user() would risk
 * memory corruption. Just test copy_to_user() here, as that exercises
 * almost exactly the same code paths.
 */
static void do_usercopy_page_span(const char *name, void *kaddr)
{}

static void lkdtm_USERCOPY_VMALLOC(void)
{}

static void lkdtm_USERCOPY_FOLIO(void)
{}

void __init lkdtm_usercopy_init(void)
{}

void __exit lkdtm_usercopy_exit(void)
{}

static struct crashtype crashtypes[] =;

struct crashtype_category usercopy_crashtypes =;