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

globtest.c (4306B)


      1/*
      2 * Extracted fronm glob.c
      3 */
      4
      5#include <linux/module.h>
      6#include <linux/moduleparam.h>
      7#include <linux/glob.h>
      8#include <linux/printk.h>
      9
     10/* Boot with "glob.verbose=1" to show successful tests, too */
     11static bool verbose = false;
     12module_param(verbose, bool, 0);
     13
     14struct glob_test {
     15	char const *pat, *str;
     16	bool expected;
     17};
     18
     19static bool __pure __init test(char const *pat, char const *str, bool expected)
     20{
     21	bool match = glob_match(pat, str);
     22	bool success = match == expected;
     23
     24	/* Can't get string literals into a particular section, so... */
     25	static char const msg_error[] __initconst =
     26		KERN_ERR "glob: \"%s\" vs. \"%s\": %s *** ERROR ***\n";
     27	static char const msg_ok[] __initconst =
     28		KERN_DEBUG "glob: \"%s\" vs. \"%s\": %s OK\n";
     29	static char const mismatch[] __initconst = "mismatch";
     30	char const *message;
     31
     32	if (!success)
     33		message = msg_error;
     34	else if (verbose)
     35		message = msg_ok;
     36	else
     37		return success;
     38
     39	printk(message, pat, str, mismatch + 3*match);
     40	return success;
     41}
     42
     43/*
     44 * The tests are all jammed together in one array to make it simpler
     45 * to place that array in the .init.rodata section.  The obvious
     46 * "array of structures containing char *" has no way to force the
     47 * pointed-to strings to be in a particular section.
     48 *
     49 * Anyway, a test consists of:
     50 * 1. Expected glob_match result: '1' or '0'.
     51 * 2. Pattern to match: null-terminated string
     52 * 3. String to match against: null-terminated string
     53 *
     54 * The list of tests is terminated with a final '\0' instead of
     55 * a glob_match result character.
     56 */
     57static char const glob_tests[] __initconst =
     58	/* Some basic tests */
     59	"1" "a\0" "a\0"
     60	"0" "a\0" "b\0"
     61	"0" "a\0" "aa\0"
     62	"0" "a\0" "\0"
     63	"1" "\0" "\0"
     64	"0" "\0" "a\0"
     65	/* Simple character class tests */
     66	"1" "[a]\0" "a\0"
     67	"0" "[a]\0" "b\0"
     68	"0" "[!a]\0" "a\0"
     69	"1" "[!a]\0" "b\0"
     70	"1" "[ab]\0" "a\0"
     71	"1" "[ab]\0" "b\0"
     72	"0" "[ab]\0" "c\0"
     73	"1" "[!ab]\0" "c\0"
     74	"1" "[a-c]\0" "b\0"
     75	"0" "[a-c]\0" "d\0"
     76	/* Corner cases in character class parsing */
     77	"1" "[a-c-e-g]\0" "-\0"
     78	"0" "[a-c-e-g]\0" "d\0"
     79	"1" "[a-c-e-g]\0" "f\0"
     80	"1" "[]a-ceg-ik[]\0" "a\0"
     81	"1" "[]a-ceg-ik[]\0" "]\0"
     82	"1" "[]a-ceg-ik[]\0" "[\0"
     83	"1" "[]a-ceg-ik[]\0" "h\0"
     84	"0" "[]a-ceg-ik[]\0" "f\0"
     85	"0" "[!]a-ceg-ik[]\0" "h\0"
     86	"0" "[!]a-ceg-ik[]\0" "]\0"
     87	"1" "[!]a-ceg-ik[]\0" "f\0"
     88	/* Simple wild cards */
     89	"1" "?\0" "a\0"
     90	"0" "?\0" "aa\0"
     91	"0" "??\0" "a\0"
     92	"1" "?x?\0" "axb\0"
     93	"0" "?x?\0" "abx\0"
     94	"0" "?x?\0" "xab\0"
     95	/* Asterisk wild cards (backtracking) */
     96	"0" "*??\0" "a\0"
     97	"1" "*??\0" "ab\0"
     98	"1" "*??\0" "abc\0"
     99	"1" "*??\0" "abcd\0"
    100	"0" "??*\0" "a\0"
    101	"1" "??*\0" "ab\0"
    102	"1" "??*\0" "abc\0"
    103	"1" "??*\0" "abcd\0"
    104	"0" "?*?\0" "a\0"
    105	"1" "?*?\0" "ab\0"
    106	"1" "?*?\0" "abc\0"
    107	"1" "?*?\0" "abcd\0"
    108	"1" "*b\0" "b\0"
    109	"1" "*b\0" "ab\0"
    110	"0" "*b\0" "ba\0"
    111	"1" "*b\0" "bb\0"
    112	"1" "*b\0" "abb\0"
    113	"1" "*b\0" "bab\0"
    114	"1" "*bc\0" "abbc\0"
    115	"1" "*bc\0" "bc\0"
    116	"1" "*bc\0" "bbc\0"
    117	"1" "*bc\0" "bcbc\0"
    118	/* Multiple asterisks (complex backtracking) */
    119	"1" "*ac*\0" "abacadaeafag\0"
    120	"1" "*ac*ae*ag*\0" "abacadaeafag\0"
    121	"1" "*a*b*[bc]*[ef]*g*\0" "abacadaeafag\0"
    122	"0" "*a*b*[ef]*[cd]*g*\0" "abacadaeafag\0"
    123	"1" "*abcd*\0" "abcabcabcabcdefg\0"
    124	"1" "*ab*cd*\0" "abcabcabcabcdefg\0"
    125	"1" "*abcd*abcdef*\0" "abcabcdabcdeabcdefg\0"
    126	"0" "*abcd*\0" "abcabcabcabcefg\0"
    127	"0" "*ab*cd*\0" "abcabcabcabcefg\0";
    128
    129static int __init glob_init(void)
    130{
    131	unsigned successes = 0;
    132	unsigned n = 0;
    133	char const *p = glob_tests;
    134	static char const message[] __initconst =
    135		KERN_INFO "glob: %u self-tests passed, %u failed\n";
    136
    137	/*
    138	 * Tests are jammed together in a string.  The first byte is '1'
    139	 * or '0' to indicate the expected outcome, or '\0' to indicate the
    140	 * end of the tests.  Then come two null-terminated strings: the
    141	 * pattern and the string to match it against.
    142	 */
    143	while (*p) {
    144		bool expected = *p++ & 1;
    145		char const *pat = p;
    146
    147		p += strlen(p) + 1;
    148		successes += test(pat, p, expected);
    149		p += strlen(p) + 1;
    150		n++;
    151	}
    152
    153	n -= successes;
    154	printk(message, successes, n);
    155
    156	/* What's the errno for "kernel bug detected"?  Guess... */
    157	return n ? -ECANCELED : 0;
    158}
    159
    160/* We need a dummy exit function to allow unload */
    161static void __exit glob_fini(void) { }
    162
    163module_init(glob_init);
    164module_exit(glob_fini);
    165
    166MODULE_DESCRIPTION("glob(7) matching tests");
    167MODULE_LICENSE("Dual MIT/GPL");