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_string.c (4701B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2#include <linux/module.h>
      3#include <linux/printk.h>
      4#include <linux/slab.h>
      5#include <linux/string.h>
      6
      7static __init int memset16_selftest(void)
      8{
      9	unsigned i, j, k;
     10	u16 v, *p;
     11
     12	p = kmalloc(256 * 2 * 2, GFP_KERNEL);
     13	if (!p)
     14		return -1;
     15
     16	for (i = 0; i < 256; i++) {
     17		for (j = 0; j < 256; j++) {
     18			memset(p, 0xa1, 256 * 2 * sizeof(v));
     19			memset16(p + i, 0xb1b2, j);
     20			for (k = 0; k < 512; k++) {
     21				v = p[k];
     22				if (k < i) {
     23					if (v != 0xa1a1)
     24						goto fail;
     25				} else if (k < i + j) {
     26					if (v != 0xb1b2)
     27						goto fail;
     28				} else {
     29					if (v != 0xa1a1)
     30						goto fail;
     31				}
     32			}
     33		}
     34	}
     35
     36fail:
     37	kfree(p);
     38	if (i < 256)
     39		return (i << 24) | (j << 16) | k | 0x8000;
     40	return 0;
     41}
     42
     43static __init int memset32_selftest(void)
     44{
     45	unsigned i, j, k;
     46	u32 v, *p;
     47
     48	p = kmalloc(256 * 2 * 4, GFP_KERNEL);
     49	if (!p)
     50		return -1;
     51
     52	for (i = 0; i < 256; i++) {
     53		for (j = 0; j < 256; j++) {
     54			memset(p, 0xa1, 256 * 2 * sizeof(v));
     55			memset32(p + i, 0xb1b2b3b4, j);
     56			for (k = 0; k < 512; k++) {
     57				v = p[k];
     58				if (k < i) {
     59					if (v != 0xa1a1a1a1)
     60						goto fail;
     61				} else if (k < i + j) {
     62					if (v != 0xb1b2b3b4)
     63						goto fail;
     64				} else {
     65					if (v != 0xa1a1a1a1)
     66						goto fail;
     67				}
     68			}
     69		}
     70	}
     71
     72fail:
     73	kfree(p);
     74	if (i < 256)
     75		return (i << 24) | (j << 16) | k | 0x8000;
     76	return 0;
     77}
     78
     79static __init int memset64_selftest(void)
     80{
     81	unsigned i, j, k;
     82	u64 v, *p;
     83
     84	p = kmalloc(256 * 2 * 8, GFP_KERNEL);
     85	if (!p)
     86		return -1;
     87
     88	for (i = 0; i < 256; i++) {
     89		for (j = 0; j < 256; j++) {
     90			memset(p, 0xa1, 256 * 2 * sizeof(v));
     91			memset64(p + i, 0xb1b2b3b4b5b6b7b8ULL, j);
     92			for (k = 0; k < 512; k++) {
     93				v = p[k];
     94				if (k < i) {
     95					if (v != 0xa1a1a1a1a1a1a1a1ULL)
     96						goto fail;
     97				} else if (k < i + j) {
     98					if (v != 0xb1b2b3b4b5b6b7b8ULL)
     99						goto fail;
    100				} else {
    101					if (v != 0xa1a1a1a1a1a1a1a1ULL)
    102						goto fail;
    103				}
    104			}
    105		}
    106	}
    107
    108fail:
    109	kfree(p);
    110	if (i < 256)
    111		return (i << 24) | (j << 16) | k | 0x8000;
    112	return 0;
    113}
    114
    115static __init int strchr_selftest(void)
    116{
    117	const char *test_string = "abcdefghijkl";
    118	const char *empty_string = "";
    119	char *result;
    120	int i;
    121
    122	for (i = 0; i < strlen(test_string) + 1; i++) {
    123		result = strchr(test_string, test_string[i]);
    124		if (result - test_string != i)
    125			return i + 'a';
    126	}
    127
    128	result = strchr(empty_string, '\0');
    129	if (result != empty_string)
    130		return 0x101;
    131
    132	result = strchr(empty_string, 'a');
    133	if (result)
    134		return 0x102;
    135
    136	result = strchr(test_string, 'z');
    137	if (result)
    138		return 0x103;
    139
    140	return 0;
    141}
    142
    143static __init int strnchr_selftest(void)
    144{
    145	const char *test_string = "abcdefghijkl";
    146	const char *empty_string = "";
    147	char *result;
    148	int i, j;
    149
    150	for (i = 0; i < strlen(test_string) + 1; i++) {
    151		for (j = 0; j < strlen(test_string) + 2; j++) {
    152			result = strnchr(test_string, j, test_string[i]);
    153			if (j <= i) {
    154				if (!result)
    155					continue;
    156				return ((i + 'a') << 8) | j;
    157			}
    158			if (result - test_string != i)
    159				return ((i + 'a') << 8) | j;
    160		}
    161	}
    162
    163	result = strnchr(empty_string, 0, '\0');
    164	if (result)
    165		return 0x10001;
    166
    167	result = strnchr(empty_string, 1, '\0');
    168	if (result != empty_string)
    169		return 0x10002;
    170
    171	result = strnchr(empty_string, 1, 'a');
    172	if (result)
    173		return 0x10003;
    174
    175	result = strnchr(NULL, 0, '\0');
    176	if (result)
    177		return 0x10004;
    178
    179	return 0;
    180}
    181
    182static __init int strspn_selftest(void)
    183{
    184	static const struct strspn_test {
    185		const char str[16];
    186		const char accept[16];
    187		const char reject[16];
    188		unsigned a;
    189		unsigned r;
    190	} tests[] __initconst = {
    191		{ "foobar", "", "", 0, 6 },
    192		{ "abba", "abc", "ABBA", 4, 4 },
    193		{ "abba", "a", "b", 1, 1 },
    194		{ "", "abc", "abc", 0, 0},
    195	};
    196	const struct strspn_test *s = tests;
    197	size_t i, res;
    198
    199	for (i = 0; i < ARRAY_SIZE(tests); ++i, ++s) {
    200		res = strspn(s->str, s->accept);
    201		if (res != s->a)
    202			return 0x100 + 2*i;
    203		res = strcspn(s->str, s->reject);
    204		if (res != s->r)
    205			return 0x100 + 2*i + 1;
    206	}
    207	return 0;
    208}
    209
    210static __exit void string_selftest_remove(void)
    211{
    212}
    213
    214static __init int string_selftest_init(void)
    215{
    216	int test, subtest;
    217
    218	test = 1;
    219	subtest = memset16_selftest();
    220	if (subtest)
    221		goto fail;
    222
    223	test = 2;
    224	subtest = memset32_selftest();
    225	if (subtest)
    226		goto fail;
    227
    228	test = 3;
    229	subtest = memset64_selftest();
    230	if (subtest)
    231		goto fail;
    232
    233	test = 4;
    234	subtest = strchr_selftest();
    235	if (subtest)
    236		goto fail;
    237
    238	test = 5;
    239	subtest = strnchr_selftest();
    240	if (subtest)
    241		goto fail;
    242
    243	test = 6;
    244	subtest = strspn_selftest();
    245	if (subtest)
    246		goto fail;
    247
    248	pr_info("String selftests succeeded\n");
    249	return 0;
    250fail:
    251	pr_crit("String selftest failure %d.%08x\n", test, subtest);
    252	return 0;
    253}
    254
    255module_init(string_selftest_init);
    256module_exit(string_selftest_remove);
    257MODULE_LICENSE("GPL v2");