github.com/google/syzkaller@v0.0.0-20240517125934-c0f1611a36d6/executor/test.h (about)

     1  // Copyright 2017 syzkaller project authors. All rights reserved.
     2  // Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
     3  
     4  #if GOOS_linux && (GOARCH_amd64 | GOARCH_ppc64 | GOARCH_ppc64le)
     5  #include "test_linux.h"
     6  #endif
     7  
     8  static int test_copyin()
     9  {
    10  	static uint16 buf[3];
    11  	STORE_BY_BITMASK(uint16, htole16, &buf[1], 0x1234, 0, 16);
    12  	unsigned char x[sizeof(buf)];
    13  	memcpy(x, buf, sizeof(x));
    14  	if (x[0] != 0 || x[1] != 0 ||
    15  	    x[2] != 0x34 || x[3] != 0x12 ||
    16  	    x[4] != 0 || x[5] != 0) {
    17  		printf("bad result of STORE_BY_BITMASK(le16, 0x1234, 0, 16): %x %x %x %x %x %x\n",
    18  		       x[0], x[1], x[2], x[3], x[4], x[5]);
    19  		return 1;
    20  	}
    21  	STORE_BY_BITMASK(uint16, htole16, &buf[1], 0x555a, 5, 4);
    22  	memcpy(x, buf, sizeof(x));
    23  	if (x[0] != 0 || x[1] != 0 ||
    24  	    x[2] != 0x54 || x[3] != 0x13 ||
    25  	    x[4] != 0 || x[5] != 0) {
    26  		printf("bad result of STORE_BY_BITMASK(le16, 0x555a, 5, 4): %x %x %x %x %x %x\n",
    27  		       x[0], x[1], x[2], x[3], x[4], x[5]);
    28  		return 1;
    29  	}
    30  	STORE_BY_BITMASK(uint16, htobe16, &buf[1], 0x4567, 13, 3);
    31  	memcpy(x, buf, sizeof(x));
    32  	if (x[0] != 0 || x[1] != 0 ||
    33  	    x[2] != 0xf4 || x[3] != 0x13 ||
    34  	    x[4] != 0 || x[5] != 0) {
    35  		printf("bad result of STORE_BY_BITMASK(be16, 0x4567, 13, 3): %x %x %x %x %x %x\n",
    36  		       x[0], x[1], x[2], x[3], x[4], x[5]);
    37  		return 1;
    38  	}
    39  	return 0;
    40  }
    41  
    42  static int test_csum_inet()
    43  {
    44  	struct csum_inet_test {
    45  		const char* data;
    46  		size_t length;
    47  		uint16 csum;
    48  	};
    49  	struct csum_inet_test tests[] = {
    50  	    {// 0
    51  	     "",
    52  	     0,
    53  	     le16toh(0xffff)},
    54  	    {
    55  		// 1
    56  		"\x00",
    57  		1,
    58  		le16toh(0xffff),
    59  	    },
    60  	    {
    61  		// 2
    62  		"\x00\x00",
    63  		2,
    64  		le16toh(0xffff),
    65  	    },
    66  	    {
    67  		// 3
    68  		"\x00\x00\xff\xff",
    69  		4,
    70  		le16toh(0x0000),
    71  	    },
    72  	    {
    73  		// 4
    74  		"\xfc",
    75  		1,
    76  		le16toh(0xff03),
    77  	    },
    78  	    {
    79  		// 5
    80  		"\xfc\x12",
    81  		2,
    82  		le16toh(0xed03),
    83  	    },
    84  	    {
    85  		// 6
    86  		"\xfc\x12\x3e",
    87  		3,
    88  		le16toh(0xecc5),
    89  	    },
    90  	    {
    91  		// 7
    92  		"\xfc\x12\x3e\x00\xc5\xec",
    93  		6,
    94  		le16toh(0x0000),
    95  	    },
    96  	    {
    97  		// 8
    98  		"\x42\x00\x00\x43\x44\x00\x00\x00\x45\x00\x00\x00\xba\xaa\xbb\xcc\xdd",
    99  		17,
   100  		le16toh(0x43e1),
   101  	    },
   102  	    {
   103  		// 9
   104  		"\x42\x00\x00\x43\x44\x00\x00\x00\x45\x00\x00\x00\xba\xaa\xbb\xcc\xdd\x00",
   105  		18,
   106  		le16toh(0x43e1),
   107  	    },
   108  	    {
   109  		// 10
   110  		"\x00\x00\x42\x00\x00\x43\x44\x00\x00\x00\x45\x00\x00\x00\xba\xaa\xbb\xcc\xdd",
   111  		19,
   112  		le16toh(0x43e1),
   113  	    },
   114  	    {
   115  		// 11
   116  		"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\xab\xcd",
   117  		15,
   118  		le16toh(0x5032),
   119  	    },
   120  	    {
   121  		// 12
   122  		"\x00\x00\x12\x34\x56\x78",
   123  		6,
   124  		le16toh(0x5397),
   125  	    },
   126  	    {
   127  		// 13
   128  		"\x00\x00\x12\x34\x00\x00\x56\x78\x00\x06\x00\x04\xab\xcd",
   129  		14,
   130  		le16toh(0x7beb),
   131  	    },
   132  	    {
   133  		// 14
   134  		"\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa\xbb\xcc\xdd\xee\xff\xff\xee\xdd\xcc\xbb\xaa\x99\x88\x77\x66\x55\x44\x33\x22\x11\x00\x00\x00\x00\x04\x00\x00\x00\x06\x00\x00\xab\xcd",
   135  		44,
   136  		le16toh(0x2854),
   137  	    },
   138  	    {
   139  		// 15
   140  		"\x00\x00\x12\x34\x00\x00\x56\x78\x00\x11\x00\x04\xab\xcd",
   141  		14,
   142  		le16toh(0x70eb),
   143  	    },
   144  	    {
   145  		// 16
   146  		"\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa\xbb\xcc\xdd\xee\xff\xff\xee\xdd\xcc\xbb\xaa\x99\x88\x77\x66\x55\x44\x33\x22\x11\x00\x00\x00\x00\x04\x00\x00\x00\x11\x00\x00\xab\xcd",
   147  		44,
   148  		le16toh(0x1d54),
   149  	    },
   150  	    {
   151  		// 17
   152  		"\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa\xbb\xcc\xdd\xee\xff\xff\xee\xdd\xcc\xbb\xaa\x99\x88\x77\x66\x55\x44\x33\x22\x11\x00\x00\x00\x00\x04\x00\x00\x00\x3a\x00\x00\xab\xcd",
   153  		44,
   154  		le16toh(0xf453),
   155  	    }};
   156  
   157  	for (unsigned i = 0; i < ARRAY_SIZE(tests); i++) {
   158  		struct csum_inet csum;
   159  		csum_inet_init(&csum);
   160  		csum_inet_update(&csum, (const uint8*)tests[i].data, tests[i].length);
   161  		if (csum_inet_digest(&csum) != tests[i].csum) {
   162  			fprintf(stderr, "bad checksum in test #%u, want: %hx, got: %hx\n", i, tests[i].csum, csum_inet_digest(&csum));
   163  			return 1;
   164  		}
   165  	}
   166  
   167  	return 0;
   168  }
   169  
   170  static int rand_int_range(int start, int end)
   171  {
   172  	return rand() % (end + 1 - start) + start;
   173  }
   174  
   175  static int test_csum_inet_acc()
   176  {
   177  	uint8 buffer[128];
   178  
   179  	for (int test = 0; test < 256; test++) {
   180  		int size = rand_int_range(1, 128);
   181  		int step = rand_int_range(1, 8) * 2;
   182  
   183  		for (int i = 0; i < size; i++)
   184  			buffer[i] = rand_int_range(0, 255);
   185  
   186  		struct csum_inet csum_acc;
   187  		csum_inet_init(&csum_acc);
   188  
   189  		for (int i = 0; i < size / step; i++)
   190  			csum_inet_update(&csum_acc, &buffer[i * step], step);
   191  		if (size % step != 0)
   192  			csum_inet_update(&csum_acc, &buffer[size - size % step], size % step);
   193  
   194  		struct csum_inet csum;
   195  		csum_inet_init(&csum);
   196  		csum_inet_update(&csum, &buffer[0], size);
   197  
   198  		if (csum_inet_digest(&csum_acc) != csum_inet_digest(&csum))
   199  			return 1;
   200  	}
   201  	return 0;
   202  }
   203  
   204  #if SYZ_EXECUTOR_USES_SHMEM
   205  static int test_coverage_filter()
   206  {
   207  	struct tmp_cov_filter_t {
   208  		uint32 pcstart;
   209  		uint32 pcsize;
   210  		uint8 bitmap[((0x1000 >> 4) + 7) / 8];
   211  	};
   212  	static struct tmp_cov_filter_t tmp_cov_filter;
   213  	tmp_cov_filter.pcstart = 0x81000000;
   214  	tmp_cov_filter.pcsize = 0x1000;
   215  	cov_filter = (cov_filter_t*)&tmp_cov_filter;
   216  	flag_coverage_filter = true;
   217  
   218  	uint64 full_enable_pc = 0xffffffff81000765;
   219  	uint64 full_disable_pc = 0xffffffff81000627;
   220  	uint64 full_out_pc = 0xffffffff82000000;
   221  
   222  	uint32 enable_pc = (uint32)full_enable_pc & 0xffffffff;
   223  	uint32 idx = ((enable_pc - cov_filter->pcstart) >> 4) / 8;
   224  	uint32 shift = ((enable_pc - cov_filter->pcstart) >> 4) % 8;
   225  	cov_filter->bitmap[idx] |= (1 << shift);
   226  
   227  	if (!coverage_filter(full_enable_pc))
   228  		return 1;
   229  	if (coverage_filter(full_disable_pc))
   230  		return 1;
   231  	if (coverage_filter(full_out_pc))
   232  		return 1;
   233  
   234  	cov_filter = NULL;
   235  	flag_coverage_filter = false;
   236  	return 0;
   237  }
   238  #endif
   239  
   240  static struct {
   241  	const char* name;
   242  	int (*f)();
   243  } tests[] = {
   244      {"test_copyin", test_copyin},
   245      {"test_csum_inet", test_csum_inet},
   246      {"test_csum_inet_acc", test_csum_inet_acc},
   247  #if GOOS_linux && (GOARCH_amd64 || GOARCH_ppc64 || GOARCH_ppc64le)
   248      {"test_kvm", test_kvm},
   249  #endif
   250  #if SYZ_EXECUTOR_USES_SHMEM
   251      {"test_coverage_filter", test_coverage_filter},
   252  #endif
   253  };
   254  
   255  static int run_tests()
   256  {
   257  	int ret = 0;
   258  	for (size_t i = 0; i < ARRAY_SIZE(tests); i++) {
   259  		const char* name = tests[i].name;
   260  		printf("=== RUN  %s\n", name);
   261  		int res = tests[i].f();
   262  		ret |= res > 0;
   263  		const char* strres = res < 0 ? "SKIP" : (res > 0 ? "FAIL" : "OK");
   264  		printf("--- %-4s %s\n", strres, name);
   265  	}
   266  	return ret;
   267  }