cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

test_ubsan.c (2498B)


      1// SPDX-License-Identifier: GPL-2.0
      2#include <linux/init.h>
      3#include <linux/kernel.h>
      4#include <linux/module.h>
      5
      6typedef void(*test_ubsan_fp)(void);
      7
      8#define UBSAN_TEST(config, ...)	do {					\
      9		pr_info("%s " __VA_ARGS__ "%s(%s=%s)\n", __func__,	\
     10			sizeof(" " __VA_ARGS__) > 2 ? " " : "",		\
     11			#config, IS_ENABLED(config) ? "y" : "n");	\
     12	} while (0)
     13
     14static void test_ubsan_divrem_overflow(void)
     15{
     16	volatile int val = 16;
     17	volatile int val2 = 0;
     18
     19	UBSAN_TEST(CONFIG_UBSAN_DIV_ZERO);
     20	val /= val2;
     21}
     22
     23static void test_ubsan_shift_out_of_bounds(void)
     24{
     25	volatile int neg = -1, wrap = 4;
     26	int val1 = 10;
     27	int val2 = INT_MAX;
     28
     29	UBSAN_TEST(CONFIG_UBSAN_SHIFT, "negative exponent");
     30	val1 <<= neg;
     31
     32	UBSAN_TEST(CONFIG_UBSAN_SHIFT, "left overflow");
     33	val2 <<= wrap;
     34}
     35
     36static void test_ubsan_out_of_bounds(void)
     37{
     38	volatile int i = 4, j = 5, k = -1;
     39	volatile char above[4] = { }; /* Protect surrounding memory. */
     40	volatile int arr[4];
     41	volatile char below[4] = { }; /* Protect surrounding memory. */
     42
     43	above[0] = below[0];
     44
     45	UBSAN_TEST(CONFIG_UBSAN_BOUNDS, "above");
     46	arr[j] = i;
     47
     48	UBSAN_TEST(CONFIG_UBSAN_BOUNDS, "below");
     49	arr[k] = i;
     50}
     51
     52enum ubsan_test_enum {
     53	UBSAN_TEST_ZERO = 0,
     54	UBSAN_TEST_ONE,
     55	UBSAN_TEST_MAX,
     56};
     57
     58static void test_ubsan_load_invalid_value(void)
     59{
     60	volatile char *dst, *src;
     61	bool val, val2, *ptr;
     62	enum ubsan_test_enum eval, eval2, *eptr;
     63	unsigned char c = 0xff;
     64
     65	UBSAN_TEST(CONFIG_UBSAN_BOOL, "bool");
     66	dst = (char *)&val;
     67	src = &c;
     68	*dst = *src;
     69
     70	ptr = &val2;
     71	val2 = val;
     72
     73	UBSAN_TEST(CONFIG_UBSAN_ENUM, "enum");
     74	dst = (char *)&eval;
     75	src = &c;
     76	*dst = *src;
     77
     78	eptr = &eval2;
     79	eval2 = eval;
     80}
     81
     82static void test_ubsan_misaligned_access(void)
     83{
     84	volatile char arr[5] __aligned(4) = {1, 2, 3, 4, 5};
     85	volatile int *ptr, val = 6;
     86
     87	UBSAN_TEST(CONFIG_UBSAN_ALIGNMENT);
     88	ptr = (int *)(arr + 1);
     89	*ptr = val;
     90}
     91
     92static const test_ubsan_fp test_ubsan_array[] = {
     93	test_ubsan_shift_out_of_bounds,
     94	test_ubsan_out_of_bounds,
     95	test_ubsan_load_invalid_value,
     96	test_ubsan_misaligned_access,
     97};
     98
     99/* Excluded because they Oops the module. */
    100static const test_ubsan_fp skip_ubsan_array[] = {
    101	test_ubsan_divrem_overflow,
    102};
    103
    104static int __init test_ubsan_init(void)
    105{
    106	unsigned int i;
    107
    108	for (i = 0; i < ARRAY_SIZE(test_ubsan_array); i++)
    109		test_ubsan_array[i]();
    110
    111	return 0;
    112}
    113module_init(test_ubsan_init);
    114
    115static void __exit test_ubsan_exit(void)
    116{
    117	/* do nothing */
    118}
    119module_exit(test_ubsan_exit);
    120
    121MODULE_AUTHOR("Jinbum Park <jinb.park7@gmail.com>");
    122MODULE_LICENSE("GPL v2");