xref: /freebsd/contrib/wpa/src/utils/utils_module_tests.c (revision c1d255d3ffdbe447de3ab875bf4e7d7accc5bfc5)
1 /*
2  * utils module tests
3  * Copyright (c) 2014-2015, Jouni Malinen <j@w1.fi>
4  *
5  * This software may be distributed under the terms of the BSD license.
6  * See README for more details.
7  */
8 
9 #include "utils/includes.h"
10 
11 #include "utils/common.h"
12 #include "utils/const_time.h"
13 #include "common/ieee802_11_defs.h"
14 #include "utils/bitfield.h"
15 #include "utils/ext_password.h"
16 #include "utils/trace.h"
17 #include "utils/base64.h"
18 #include "utils/ip_addr.h"
19 #include "utils/eloop.h"
20 #include "utils/json.h"
21 #include "utils/module_tests.h"
22 
23 
24 struct printf_test_data {
25 	u8 *data;
26 	size_t len;
27 	char *encoded;
28 };
29 
30 static const struct printf_test_data printf_tests[] = {
31 	{ (u8 *) "abcde", 5, "abcde" },
32 	{ (u8 *) "a\0b\nc\ed\re\tf\"\\", 13, "a\\0b\\nc\\ed\\re\\tf\\\"\\\\" },
33 	{ (u8 *) "\x00\x31\x00\x32\x00\x39", 6, "\\x001\\0002\\09" },
34 	{ (u8 *) "\n\n\n", 3, "\n\12\x0a" },
35 	{ (u8 *) "\303\245\303\244\303\266\303\205\303\204\303\226", 12,
36 	  "\\xc3\\xa5\xc3\\xa4\\xc3\\xb6\\xc3\\x85\\xc3\\x84\\xc3\\x96" },
37 	{ (u8 *) "\303\245\303\244\303\266\303\205\303\204\303\226", 12,
38 	  "\\303\\245\\303\\244\\303\\266\\303\\205\\303\\204\\303\\226" },
39 	{ (u8 *) "\xe5\xe4\xf6\xc5\xc4\xd6", 6,
40 	  "\\xe5\\xe4\\xf6\\xc5\\xc4\\xd6" },
41 	{ NULL, 0, NULL }
42 };
43 
44 
printf_encode_decode_tests(void)45 static int printf_encode_decode_tests(void)
46 {
47 	int i;
48 	size_t binlen;
49 	char buf[100];
50 	u8 bin[100];
51 	int errors = 0;
52 	int array[10];
53 
54 	wpa_printf(MSG_INFO, "printf encode/decode tests");
55 
56 	for (i = 0; printf_tests[i].data; i++) {
57 		const struct printf_test_data *test = &printf_tests[i];
58 		printf_encode(buf, sizeof(buf), test->data, test->len);
59 		wpa_printf(MSG_INFO, "%d: -> \"%s\"", i, buf);
60 
61 		binlen = printf_decode(bin, sizeof(bin), buf);
62 		if (binlen != test->len ||
63 		    os_memcmp(bin, test->data, binlen) != 0) {
64 			wpa_hexdump(MSG_ERROR, "Error in decoding#1",
65 				    bin, binlen);
66 			errors++;
67 		}
68 
69 		binlen = printf_decode(bin, sizeof(bin), test->encoded);
70 		if (binlen != test->len ||
71 		    os_memcmp(bin, test->data, binlen) != 0) {
72 			wpa_hexdump(MSG_ERROR, "Error in decoding#2",
73 				    bin, binlen);
74 			errors++;
75 		}
76 	}
77 
78 	buf[5] = 'A';
79 	printf_encode(buf, 5, (const u8 *) "abcde", 5);
80 	if (buf[5] != 'A') {
81 		wpa_printf(MSG_ERROR, "Error in bounds checking#1");
82 		errors++;
83 	}
84 
85 	for (i = 5; i < 10; i++) {
86 		buf[i] = 'A';
87 		printf_encode(buf, i, (const u8 *) "\xdd\xdd\xdd\xdd\xdd", 5);
88 		if (buf[i] != 'A') {
89 			wpa_printf(MSG_ERROR, "Error in bounds checking#2(%d)",
90 				   i);
91 			errors++;
92 		}
93 	}
94 
95 	if (printf_decode(bin, 3, "abcde") != 2)
96 		errors++;
97 
98 	if (printf_decode(bin, 3, "\\xa") != 1 || bin[0] != 10)
99 		errors++;
100 
101 	if (printf_decode(bin, 3, "\\xq") != 1 || bin[0] != 'q')
102 		errors++;
103 
104 	if (printf_decode(bin, 3, "\\a") != 1 || bin[0] != 'a')
105 		errors++;
106 
107 	array[0] = 10;
108 	array[1] = 10;
109 	array[2] = 5;
110 	array[3] = 10;
111 	array[4] = 5;
112 	array[5] = 0;
113 	if (int_array_len(array) != 5)
114 		errors++;
115 	int_array_sort_unique(array);
116 	if (int_array_len(array) != 2)
117 		errors++;
118 
119 	if (errors) {
120 		wpa_printf(MSG_ERROR, "%d printf test(s) failed", errors);
121 		return -1;
122 	}
123 
124 	return 0;
125 }
126 
127 
bitfield_tests(void)128 static int bitfield_tests(void)
129 {
130 	struct bitfield *bf;
131 	int i;
132 	int errors = 0;
133 
134 	wpa_printf(MSG_INFO, "bitfield tests");
135 
136 	bf = bitfield_alloc(123);
137 	if (bf == NULL)
138 		return -1;
139 
140 	for (i = 0; i < 123; i++) {
141 		if (bitfield_is_set(bf, i) || bitfield_is_set(bf, i + 1))
142 			errors++;
143 		if (i > 0 && bitfield_is_set(bf, i - 1))
144 			errors++;
145 		bitfield_set(bf, i);
146 		if (!bitfield_is_set(bf, i))
147 			errors++;
148 		bitfield_clear(bf, i);
149 		if (bitfield_is_set(bf, i))
150 			errors++;
151 	}
152 
153 	for (i = 123; i < 200; i++) {
154 		if (bitfield_is_set(bf, i) || bitfield_is_set(bf, i + 1))
155 			errors++;
156 		if (i > 0 && bitfield_is_set(bf, i - 1))
157 			errors++;
158 		bitfield_set(bf, i);
159 		if (bitfield_is_set(bf, i))
160 			errors++;
161 		bitfield_clear(bf, i);
162 		if (bitfield_is_set(bf, i))
163 			errors++;
164 	}
165 
166 	for (i = 0; i < 123; i++) {
167 		if (bitfield_is_set(bf, i) || bitfield_is_set(bf, i + 1))
168 			errors++;
169 		bitfield_set(bf, i);
170 		if (!bitfield_is_set(bf, i))
171 			errors++;
172 	}
173 
174 	for (i = 0; i < 123; i++) {
175 		if (!bitfield_is_set(bf, i))
176 			errors++;
177 		bitfield_clear(bf, i);
178 		if (bitfield_is_set(bf, i))
179 			errors++;
180 	}
181 
182 	for (i = 0; i < 123; i++) {
183 		if (bitfield_get_first_zero(bf) != i)
184 			errors++;
185 		bitfield_set(bf, i);
186 	}
187 	if (bitfield_get_first_zero(bf) != -1)
188 		errors++;
189 	for (i = 0; i < 123; i++) {
190 		if (!bitfield_is_set(bf, i))
191 			errors++;
192 		bitfield_clear(bf, i);
193 		if (bitfield_get_first_zero(bf) != i)
194 			errors++;
195 		bitfield_set(bf, i);
196 	}
197 	if (bitfield_get_first_zero(bf) != -1)
198 		errors++;
199 
200 	bitfield_free(bf);
201 
202 	bf = bitfield_alloc(8);
203 	if (bf == NULL)
204 		return -1;
205 	if (bitfield_get_first_zero(bf) != 0)
206 		errors++;
207 	for (i = 0; i < 8; i++)
208 		bitfield_set(bf, i);
209 	if (bitfield_get_first_zero(bf) != -1)
210 		errors++;
211 	bitfield_free(bf);
212 
213 	if (errors) {
214 		wpa_printf(MSG_ERROR, "%d bitfield test(s) failed", errors);
215 		return -1;
216 	}
217 
218 	return 0;
219 }
220 
221 
int_array_tests(void)222 static int int_array_tests(void)
223 {
224 	int test1[] = { 1, 2, 3, 4, 5, 6, 0 };
225 	int test2[] = { 1, -1, 0 };
226 	int test3[] = { 1, 1, 1, -1, 2, 3, 4, 1, 2, 0 };
227 	int test3_res[] = { -1, 1, 2, 3, 4, 0 };
228 	int errors = 0;
229 	size_t len;
230 
231 	wpa_printf(MSG_INFO, "int_array tests");
232 
233 	if (int_array_len(test1) != 6 ||
234 	    int_array_len(test2) != 2)
235 		errors++;
236 
237 	int_array_sort_unique(test3);
238 	len = int_array_len(test3_res);
239 	if (int_array_len(test3) != len)
240 		errors++;
241 	else if (os_memcmp(test3, test3_res, len * sizeof(int)) != 0)
242 		errors++;
243 
244 	if (errors) {
245 		wpa_printf(MSG_ERROR, "%d int_array test(s) failed", errors);
246 		return -1;
247 	}
248 
249 	return 0;
250 }
251 
252 
ext_password_tests(void)253 static int ext_password_tests(void)
254 {
255 	struct ext_password_data *data;
256 	int ret = 0;
257 	struct wpabuf *pw;
258 
259 	wpa_printf(MSG_INFO, "ext_password tests");
260 
261 	data = ext_password_init("unknown", "foo");
262 	if (data != NULL)
263 		return -1;
264 
265 	data = ext_password_init("test", NULL);
266 	if (data == NULL)
267 		return -1;
268 	pw = ext_password_get(data, "foo");
269 	if (pw != NULL)
270 		ret = -1;
271 	ext_password_free(pw);
272 
273 	ext_password_deinit(data);
274 
275 	pw = ext_password_get(NULL, "foo");
276 	if (pw != NULL)
277 		ret = -1;
278 	ext_password_free(pw);
279 
280 	return ret;
281 }
282 
283 
trace_tests(void)284 static int trace_tests(void)
285 {
286 	wpa_printf(MSG_INFO, "trace tests");
287 
288 	wpa_trace_show("test backtrace");
289 	wpa_trace_dump_funcname("test funcname", trace_tests);
290 
291 	return 0;
292 }
293 
294 
base64_tests(void)295 static int base64_tests(void)
296 {
297 	int errors = 0;
298 	unsigned char *res;
299 	char *res2;
300 	size_t res_len;
301 
302 	wpa_printf(MSG_INFO, "base64 tests");
303 
304 	res2 = base64_encode("", ~0, &res_len);
305 	if (res2) {
306 		errors++;
307 		os_free(res2);
308 	}
309 
310 	res2 = base64_encode("=", 1, &res_len);
311 	if (!res2 || res_len != 5 || res2[0] != 'P' || res2[1] != 'Q' ||
312 	    res2[2] != '=' || res2[3] != '=' || res2[4] != '\n')
313 		errors++;
314 	os_free(res2);
315 
316 	res2 = base64_encode("=", 1, NULL);
317 	if (!res2 || res2[0] != 'P' || res2[1] != 'Q' ||
318 	    res2[2] != '=' || res2[3] != '=' || res2[4] != '\n')
319 		errors++;
320 	os_free(res2);
321 
322 	res = base64_decode("", 0, &res_len);
323 	if (res) {
324 		errors++;
325 		os_free(res);
326 	}
327 
328 	res = base64_decode("a", 1, &res_len);
329 	if (res) {
330 		errors++;
331 		os_free(res);
332 	}
333 
334 	res = base64_decode("====", 4, &res_len);
335 	if (res) {
336 		errors++;
337 		os_free(res);
338 	}
339 
340 	res = base64_decode("PQ==", 4, &res_len);
341 	if (!res || res_len != 1 || res[0] != '=')
342 		errors++;
343 	os_free(res);
344 
345 	res = base64_decode("P.Q-=!=*", 8, &res_len);
346 	if (!res || res_len != 1 || res[0] != '=')
347 		errors++;
348 	os_free(res);
349 
350 	if (errors) {
351 		wpa_printf(MSG_ERROR, "%d base64 test(s) failed", errors);
352 		return -1;
353 	}
354 
355 	return 0;
356 }
357 
358 
common_tests(void)359 static int common_tests(void)
360 {
361 	char buf[3], longbuf[100];
362 	u8 addr[ETH_ALEN] = { 1, 2, 3, 4, 5, 6 };
363 	u8 bin[3];
364 	int errors = 0;
365 	struct wpa_freq_range_list ranges;
366 	size_t len;
367 	const char *txt;
368 	u8 ssid[255];
369 
370 	wpa_printf(MSG_INFO, "common tests");
371 
372 	if (hwaddr_mask_txt(buf, 3, addr, addr) != -1)
373 		errors++;
374 
375 	if (wpa_scnprintf(buf, 0, "hello") != 0 ||
376 	    wpa_scnprintf(buf, 3, "hello") != 2)
377 		errors++;
378 
379 	if (wpa_snprintf_hex(buf, 0, addr, ETH_ALEN) != 0 ||
380 	    wpa_snprintf_hex(buf, 3, addr, ETH_ALEN) != 2)
381 		errors++;
382 
383 	if (merge_byte_arrays(bin, 3, addr, ETH_ALEN, NULL, 0) != 3 ||
384 	    merge_byte_arrays(bin, 3, NULL, 0, addr, ETH_ALEN) != 3)
385 		errors++;
386 
387 	if (dup_binstr(NULL, 0) != NULL)
388 		errors++;
389 
390 	if (freq_range_list_includes(NULL, 0) != 0)
391 		errors++;
392 
393 	os_memset(&ranges, 0, sizeof(ranges));
394 	if (freq_range_list_parse(&ranges, "") != 0 ||
395 	    freq_range_list_includes(&ranges, 0) != 0 ||
396 	    freq_range_list_str(&ranges) != NULL)
397 		errors++;
398 
399 	if (utf8_unescape(NULL, 0, buf, sizeof(buf)) != 0 ||
400 	    utf8_unescape("a", 1, NULL, 0) != 0 ||
401 	    utf8_unescape("a\\", 2, buf, sizeof(buf)) != 0 ||
402 	    utf8_unescape("abcde", 5, buf, sizeof(buf)) != 0 ||
403 	    utf8_unescape("abc", 3, buf, 3) != 3)
404 		errors++;
405 
406 	if (utf8_unescape("a", 0, buf, sizeof(buf)) != 1 || buf[0] != 'a')
407 		errors++;
408 
409 	if (utf8_unescape("\\b", 2, buf, sizeof(buf)) != 1 || buf[0] != 'b')
410 		errors++;
411 
412 	if (utf8_escape(NULL, 0, buf, sizeof(buf)) != 0 ||
413 	    utf8_escape("a", 1, NULL, 0) != 0 ||
414 	    utf8_escape("abcde", 5, buf, sizeof(buf)) != 0 ||
415 	    utf8_escape("a\\bcde", 6, buf, sizeof(buf)) != 0 ||
416 	    utf8_escape("ab\\cde", 6, buf, sizeof(buf)) != 0 ||
417 	    utf8_escape("abc\\de", 6, buf, sizeof(buf)) != 0 ||
418 	    utf8_escape("abc", 3, buf, 3) != 3)
419 		errors++;
420 
421 	if (utf8_escape("a", 0, buf, sizeof(buf)) != 1 || buf[0] != 'a')
422 		errors++;
423 
424 	os_memset(ssid, 0, sizeof(ssid));
425 	txt = wpa_ssid_txt(ssid, sizeof(ssid));
426 	len = os_strlen(txt);
427 	/* Verify that SSID_MAX_LEN * 4 buffer limit is enforced. */
428 	if (len != SSID_MAX_LEN * 4) {
429 		wpa_printf(MSG_ERROR,
430 			   "Unexpected wpa_ssid_txt() result with too long SSID");
431 		errors++;
432 	}
433 
434 	if (wpa_snprintf_hex_sep(longbuf, 0, addr, ETH_ALEN, '-') != 0 ||
435 	    wpa_snprintf_hex_sep(longbuf, 5, addr, ETH_ALEN, '-') != 3 ||
436 	    os_strcmp(longbuf, "01-0") != 0)
437 		errors++;
438 
439 	if (errors) {
440 		wpa_printf(MSG_ERROR, "%d common test(s) failed", errors);
441 		return -1;
442 	}
443 
444 	return 0;
445 }
446 
447 
os_tests(void)448 static int os_tests(void)
449 {
450 	int errors = 0;
451 	void *ptr;
452 	os_time_t t;
453 
454 	wpa_printf(MSG_INFO, "os tests");
455 
456 	ptr = os_calloc((size_t) -1, (size_t) -1);
457 	if (ptr) {
458 		errors++;
459 		os_free(ptr);
460 	}
461 	ptr = os_calloc((size_t) 2, (size_t) -1);
462 	if (ptr) {
463 		errors++;
464 		os_free(ptr);
465 	}
466 	ptr = os_calloc((size_t) -1, (size_t) 2);
467 	if (ptr) {
468 		errors++;
469 		os_free(ptr);
470 	}
471 
472 	ptr = os_realloc_array(NULL, (size_t) -1, (size_t) -1);
473 	if (ptr) {
474 		errors++;
475 		os_free(ptr);
476 	}
477 
478 	os_sleep(1, 1);
479 
480 	if (os_mktime(1969, 1, 1, 1, 1, 1, &t) == 0 ||
481 	    os_mktime(1971, 0, 1, 1, 1, 1, &t) == 0 ||
482 	    os_mktime(1971, 13, 1, 1, 1, 1, &t) == 0 ||
483 	    os_mktime(1971, 1, 0, 1, 1, 1, &t) == 0 ||
484 	    os_mktime(1971, 1, 32, 1, 1, 1, &t) == 0 ||
485 	    os_mktime(1971, 1, 1, -1, 1, 1, &t) == 0 ||
486 	    os_mktime(1971, 1, 1, 24, 1, 1, &t) == 0 ||
487 	    os_mktime(1971, 1, 1, 1, -1, 1, &t) == 0 ||
488 	    os_mktime(1971, 1, 1, 1, 60, 1, &t) == 0 ||
489 	    os_mktime(1971, 1, 1, 1, 1, -1, &t) == 0 ||
490 	    os_mktime(1971, 1, 1, 1, 1, 61, &t) == 0 ||
491 	    os_mktime(1971, 1, 1, 1, 1, 1, &t) != 0 ||
492 	    os_mktime(2020, 1, 2, 3, 4, 5, &t) != 0 ||
493 	    os_mktime(2015, 12, 31, 23, 59, 59, &t) != 0)
494 		errors++;
495 
496 	if (os_setenv("hwsim_test_env", "test value", 0) != 0 ||
497 	    os_setenv("hwsim_test_env", "test value 2", 1) != 0 ||
498 	    os_unsetenv("hwsim_test_env") != 0)
499 		errors++;
500 
501 	if (os_file_exists("/this-file-does-not-exists-hwsim") != 0)
502 		errors++;
503 
504 	if (errors) {
505 		wpa_printf(MSG_ERROR, "%d os test(s) failed", errors);
506 		return -1;
507 	}
508 
509 	return 0;
510 }
511 
512 
wpabuf_tests(void)513 static int wpabuf_tests(void)
514 {
515 	int errors = 0;
516 	void *ptr;
517 	struct wpabuf *buf;
518 
519 	wpa_printf(MSG_INFO, "wpabuf tests");
520 
521 	ptr = os_malloc(100);
522 	if (ptr) {
523 		buf = wpabuf_alloc_ext_data(ptr, 100);
524 		if (buf) {
525 			if (wpabuf_resize(&buf, 100) < 0)
526 				errors++;
527 			else
528 				wpabuf_put(buf, 100);
529 			wpabuf_free(buf);
530 		} else {
531 			errors++;
532 			os_free(ptr);
533 		}
534 	} else {
535 		errors++;
536 	}
537 
538 	buf = wpabuf_alloc(100);
539 	if (buf) {
540 		struct wpabuf *buf2;
541 
542 		wpabuf_put(buf, 100);
543 		if (wpabuf_resize(&buf, 100) < 0)
544 			errors++;
545 		else
546 			wpabuf_put(buf, 100);
547 		buf2 = wpabuf_concat(buf, NULL);
548 		if (buf2 != buf)
549 			errors++;
550 		wpabuf_free(buf2);
551 	} else {
552 		errors++;
553 	}
554 
555 	buf = NULL;
556 	buf = wpabuf_zeropad(buf, 10);
557 	if (buf != NULL)
558 		errors++;
559 
560 	if (errors) {
561 		wpa_printf(MSG_ERROR, "%d wpabuf test(s) failed", errors);
562 		return -1;
563 	}
564 
565 	return 0;
566 }
567 
568 
ip_addr_tests(void)569 static int ip_addr_tests(void)
570 {
571 	int errors = 0;
572 	struct hostapd_ip_addr addr;
573 	char buf[100];
574 
575 	wpa_printf(MSG_INFO, "ip_addr tests");
576 
577 	if (hostapd_parse_ip_addr("1.2.3.4", &addr) != 0 ||
578 	    addr.af != AF_INET ||
579 	    hostapd_ip_txt(NULL, buf, sizeof(buf)) != NULL ||
580 	    hostapd_ip_txt(&addr, buf, 1) != buf || buf[0] != '\0' ||
581 	    hostapd_ip_txt(&addr, buf, 0) != NULL ||
582 	    hostapd_ip_txt(&addr, buf, sizeof(buf)) != buf)
583 		errors++;
584 
585 	if (hostapd_parse_ip_addr("::", &addr) != 0 ||
586 	    addr.af != AF_INET6 ||
587 	    hostapd_ip_txt(&addr, buf, 1) != buf || buf[0] != '\0' ||
588 	    hostapd_ip_txt(&addr, buf, sizeof(buf)) != buf)
589 		errors++;
590 
591 	if (errors) {
592 		wpa_printf(MSG_ERROR, "%d ip_addr test(s) failed", errors);
593 		return -1;
594 	}
595 
596 	return 0;
597 }
598 
599 
600 struct test_eloop {
601 	unsigned int magic;
602 	int close_in_timeout;
603 	int pipefd1[2];
604 	int pipefd2[2];
605 };
606 
607 
608 static void eloop_tests_start(int close_in_timeout);
609 
610 
eloop_test_read_2(int sock,void * eloop_ctx,void * sock_ctx)611 static void eloop_test_read_2(int sock, void *eloop_ctx, void *sock_ctx)
612 {
613 	struct test_eloop *t = eloop_ctx;
614 	ssize_t res;
615 	char buf[10];
616 
617 	wpa_printf(MSG_INFO, "%s: sock=%d", __func__, sock);
618 
619 	if (t->magic != 0x12345678) {
620 		wpa_printf(MSG_INFO, "%s: unexpected magic 0x%x",
621 			   __func__, t->magic);
622 	}
623 
624 	if (t->pipefd2[0] != sock) {
625 		wpa_printf(MSG_INFO, "%s: unexpected sock %d != %d",
626 			   __func__, sock, t->pipefd2[0]);
627 	}
628 
629 	res = read(sock, buf, sizeof(buf));
630 	wpa_printf(MSG_INFO, "%s: sock=%d --> res=%d",
631 		   __func__, sock, (int) res);
632 }
633 
634 
eloop_test_read_2_wrong(int sock,void * eloop_ctx,void * sock_ctx)635 static void eloop_test_read_2_wrong(int sock, void *eloop_ctx, void *sock_ctx)
636 {
637 	struct test_eloop *t = eloop_ctx;
638 
639 	wpa_printf(MSG_INFO, "%s: sock=%d", __func__, sock);
640 
641 	if (t->magic != 0x12345678) {
642 		wpa_printf(MSG_INFO, "%s: unexpected magic 0x%x",
643 			   __func__, t->magic);
644 	}
645 
646 	if (t->pipefd2[0] != sock) {
647 		wpa_printf(MSG_INFO, "%s: unexpected sock %d != %d",
648 			   __func__, sock, t->pipefd2[0]);
649 	}
650 
651 	/*
652 	 * This is expected to block due to the original socket with data having
653 	 * been closed and no new data having been written to the new socket
654 	 * with the same fd. To avoid blocking the process during test, skip the
655 	 * read here.
656 	 */
657 	wpa_printf(MSG_ERROR, "%s: FAIL - should not have called this function",
658 		   __func__);
659 }
660 
661 
reopen_pipefd2(struct test_eloop * t)662 static void reopen_pipefd2(struct test_eloop *t)
663 {
664 	if (t->pipefd2[0] < 0) {
665 		wpa_printf(MSG_INFO, "pipefd2 had been closed");
666 	} else {
667 		int res;
668 
669 		wpa_printf(MSG_INFO, "close pipefd2");
670 		eloop_unregister_read_sock(t->pipefd2[0]);
671 		close(t->pipefd2[0]);
672 		t->pipefd2[0] = -1;
673 		close(t->pipefd2[1]);
674 		t->pipefd2[1] = -1;
675 
676 		res = pipe(t->pipefd2);
677 		if (res < 0) {
678 			wpa_printf(MSG_INFO, "pipe: %s", strerror(errno));
679 			t->pipefd2[0] = -1;
680 			t->pipefd2[1] = -1;
681 			return;
682 		}
683 
684 		wpa_printf(MSG_INFO,
685 			   "re-register pipefd2 with new sockets %d,%d",
686 			   t->pipefd2[0], t->pipefd2[1]);
687 		eloop_register_read_sock(t->pipefd2[0], eloop_test_read_2_wrong,
688 					 t, NULL);
689 	}
690 }
691 
692 
eloop_test_read_1(int sock,void * eloop_ctx,void * sock_ctx)693 static void eloop_test_read_1(int sock, void *eloop_ctx, void *sock_ctx)
694 {
695 	struct test_eloop *t = eloop_ctx;
696 	ssize_t res;
697 	char buf[10];
698 
699 	wpa_printf(MSG_INFO, "%s: sock=%d", __func__, sock);
700 
701 	if (t->magic != 0x12345678) {
702 		wpa_printf(MSG_INFO, "%s: unexpected magic 0x%x",
703 			   __func__, t->magic);
704 	}
705 
706 	if (t->pipefd1[0] != sock) {
707 		wpa_printf(MSG_INFO, "%s: unexpected sock %d != %d",
708 			   __func__, sock, t->pipefd1[0]);
709 	}
710 
711 	res = read(sock, buf, sizeof(buf));
712 	wpa_printf(MSG_INFO, "%s: sock=%d --> res=%d",
713 		   __func__, sock, (int) res);
714 
715 	if (!t->close_in_timeout)
716 		reopen_pipefd2(t);
717 }
718 
719 
eloop_test_cb(void * eloop_data,void * user_ctx)720 static void eloop_test_cb(void *eloop_data, void *user_ctx)
721 {
722 	struct test_eloop *t = eloop_data;
723 
724 	wpa_printf(MSG_INFO, "%s", __func__);
725 
726 	if (t->magic != 0x12345678) {
727 		wpa_printf(MSG_INFO, "%s: unexpected magic 0x%x",
728 			   __func__, t->magic);
729 	}
730 
731 	if (t->close_in_timeout)
732 		reopen_pipefd2(t);
733 }
734 
735 
eloop_test_timeout(void * eloop_data,void * user_ctx)736 static void eloop_test_timeout(void *eloop_data, void *user_ctx)
737 {
738 	struct test_eloop *t = eloop_data;
739 	int next_run = 0;
740 
741 	wpa_printf(MSG_INFO, "%s", __func__);
742 
743 	if (t->magic != 0x12345678) {
744 		wpa_printf(MSG_INFO, "%s: unexpected magic 0x%x",
745 			   __func__, t->magic);
746 	}
747 
748 	if (t->pipefd1[0] >= 0) {
749 		wpa_printf(MSG_INFO, "pipefd1 had not been closed");
750 		eloop_unregister_read_sock(t->pipefd1[0]);
751 		close(t->pipefd1[0]);
752 		t->pipefd1[0] = -1;
753 		close(t->pipefd1[1]);
754 		t->pipefd1[1] = -1;
755 	}
756 
757 	if (t->pipefd2[0] >= 0) {
758 		wpa_printf(MSG_INFO, "pipefd2 had not been closed");
759 		eloop_unregister_read_sock(t->pipefd2[0]);
760 		close(t->pipefd2[0]);
761 		t->pipefd2[0] = -1;
762 		close(t->pipefd2[1]);
763 		t->pipefd2[1] = -1;
764 	}
765 
766 	next_run = t->close_in_timeout;
767 	t->magic = 0;
768 	wpa_printf(MSG_INFO, "%s - free(%p)", __func__, t);
769 	os_free(t);
770 
771 	if (next_run)
772 		eloop_tests_start(0);
773 }
774 
775 
eloop_tests_start(int close_in_timeout)776 static void eloop_tests_start(int close_in_timeout)
777 {
778 	struct test_eloop *t;
779 	int res;
780 
781 	t = os_zalloc(sizeof(*t));
782 	if (!t)
783 		return;
784 	t->magic = 0x12345678;
785 	t->close_in_timeout = close_in_timeout;
786 
787 	wpa_printf(MSG_INFO, "starting eloop tests (%p) (close_in_timeout=%d)",
788 		   t, close_in_timeout);
789 
790 	res = pipe(t->pipefd1);
791 	if (res < 0) {
792 		wpa_printf(MSG_INFO, "pipe: %s", strerror(errno));
793 		os_free(t);
794 		return;
795 	}
796 
797 	res = pipe(t->pipefd2);
798 	if (res < 0) {
799 		wpa_printf(MSG_INFO, "pipe: %s", strerror(errno));
800 		close(t->pipefd1[0]);
801 		close(t->pipefd1[1]);
802 		os_free(t);
803 		return;
804 	}
805 
806 	wpa_printf(MSG_INFO, "pipe fds: %d,%d %d,%d",
807 		   t->pipefd1[0], t->pipefd1[1],
808 		   t->pipefd2[0], t->pipefd2[1]);
809 
810 	eloop_register_read_sock(t->pipefd1[0], eloop_test_read_1, t, NULL);
811 	eloop_register_read_sock(t->pipefd2[0], eloop_test_read_2, t, NULL);
812 	eloop_register_timeout(0, 0, eloop_test_cb, t, NULL);
813 	eloop_register_timeout(0, 200000, eloop_test_timeout, t, NULL);
814 
815 	if (write(t->pipefd1[1], "HELLO", 5) < 0)
816 		wpa_printf(MSG_INFO, "write: %s", strerror(errno));
817 	if (write(t->pipefd2[1], "TEST", 4) < 0)
818 		wpa_printf(MSG_INFO, "write: %s", strerror(errno));
819 	os_sleep(0, 50000);
820 	wpa_printf(MSG_INFO, "waiting for eloop callbacks");
821 }
822 
823 
eloop_tests_run(void * eloop_data,void * user_ctx)824 static void eloop_tests_run(void *eloop_data, void *user_ctx)
825 {
826 	eloop_tests_start(1);
827 }
828 
829 
eloop_tests(void)830 static int eloop_tests(void)
831 {
832 	wpa_printf(MSG_INFO, "schedule eloop tests to be run");
833 
834 	/*
835 	 * Cannot return error from these without a significant design change,
836 	 * so for now, run the tests from a scheduled timeout and require
837 	 * separate verification of the results from the debug log.
838 	 */
839 	eloop_register_timeout(0, 0, eloop_tests_run, NULL, NULL);
840 
841 	return 0;
842 }
843 
844 
845 #ifdef CONFIG_JSON
846 struct json_test_data {
847 	const char *json;
848 	const char *tree;
849 };
850 
851 static const struct json_test_data json_test_cases[] = {
852 	{ "{}", "[1:OBJECT:]" },
853 	{ "[]", "[1:ARRAY:]" },
854 	{ "{", NULL },
855 	{ "[", NULL },
856 	{ "}", NULL },
857 	{ "]", NULL },
858 	{ "[[]]", "[1:ARRAY:][2:ARRAY:]" },
859 	{ "{\"t\":\"test\"}", "[1:OBJECT:][2:STRING:t]" },
860 	{ "{\"t\":123}", "[1:OBJECT:][2:NUMBER:t]" },
861 	{ "{\"t\":true}", "[1:OBJECT:][2:BOOLEAN:t]" },
862 	{ "{\"t\":false}", "[1:OBJECT:][2:BOOLEAN:t]" },
863 	{ "{\"t\":null}", "[1:OBJECT:][2:NULL:t]" },
864 	{ "{\"t\":truetrue}", NULL },
865 	{ "\"test\"", "[1:STRING:]" },
866 	{ "123", "[1:NUMBER:]" },
867 	{ "true", "[1:BOOLEAN:]" },
868 	{ "false", "[1:BOOLEAN:]" },
869 	{ "null", "[1:NULL:]" },
870 	{ "truetrue", NULL },
871 	{ " {\t\n\r\"a\"\n:\r1\n,\n\"b\":3\n}\n",
872 	  "[1:OBJECT:][2:NUMBER:a][2:NUMBER:b]" },
873 	{ ",", NULL },
874 	{ "{,}", NULL },
875 	{ "[,]", NULL },
876 	{ ":", NULL },
877 	{ "{:}", NULL },
878 	{ "[:]", NULL },
879 	{ "{ \"\\u005c\" : \"\\u005c\" }", "[1:OBJECT:][2:STRING:\\]" },
880 	{ "[{},{}]", "[1:ARRAY:][2:OBJECT:][2:OBJECT:]" },
881 	{ "[1,2]", "[1:ARRAY:][2:NUMBER:][2:NUMBER:]" },
882 	{ "[\"1\",\"2\"]", "[1:ARRAY:][2:STRING:][2:STRING:]" },
883 	{ "[true,false]", "[1:ARRAY:][2:BOOLEAN:][2:BOOLEAN:]" },
884 };
885 #endif /* CONFIG_JSON */
886 
887 
json_tests(void)888 static int json_tests(void)
889 {
890 #ifdef CONFIG_JSON
891 	unsigned int i;
892 	struct json_token *root;
893 	char buf[1000];
894 
895 	wpa_printf(MSG_INFO, "JSON tests");
896 
897 	for (i = 0; i < ARRAY_SIZE(json_test_cases); i++) {
898 		const struct json_test_data *test = &json_test_cases[i];
899 		int res = 0;
900 
901 		root = json_parse(test->json, os_strlen(test->json));
902 		if ((root && !test->tree) || (!root && test->tree)) {
903 			wpa_printf(MSG_INFO, "JSON test %u failed", i);
904 			res = -1;
905 		} else if (root) {
906 			json_print_tree(root, buf, sizeof(buf));
907 			if (os_strcmp(buf, test->tree) != 0) {
908 				wpa_printf(MSG_INFO,
909 					   "JSON test %u tree mismatch: %s %s",
910 					   i, buf, test->tree);
911 				res = -1;
912 			}
913 		}
914 		json_free(root);
915 		if (res < 0)
916 			return -1;
917 
918 	}
919 #endif /* CONFIG_JSON */
920 	return 0;
921 }
922 
923 
const_time_tests(void)924 static int const_time_tests(void)
925 {
926 	struct const_time_fill_msb_test {
927 		unsigned int val;
928 		unsigned int expected;
929 	} const_time_fill_msb_tests[] = {
930 		{ 0, 0 },
931 		{ 1, 0 },
932 		{ 2, 0 },
933 		{ 1U << (sizeof(unsigned int) * 8 - 1), ~0 },
934 		{ ~0 - 1, ~0 },
935 		{ ~0, ~0 }
936 	};
937 	struct const_time_is_zero_test {
938 		unsigned int val;
939 		unsigned int expected;
940 	} const_time_is_zero_tests[] = {
941 		{ 0, ~0 },
942 		{ 1, 0 },
943 		{ 2, 0 },
944 		{ 1U << (sizeof(unsigned int) * 8 - 1), 0 },
945 		{ ~0 - 1, 0 },
946 		{ ~0, 0 }
947 	};
948 	struct const_time_eq_test {
949 		unsigned int a;
950 		unsigned int b;
951 		unsigned int expected;
952 		unsigned int expected_u8;
953 	} const_time_eq_tests[] = {
954 		{ 0, 1, 0, 0 },
955 		{ 1, 2, 0, 0 },
956 		{ 1, 1, ~0, 0xff },
957 		{ ~0, ~0, ~0, 0xff },
958 		{ ~0, ~0 - 1, 0, 0 },
959 		{ 0, 0, ~0, 0xff }
960 	};
961 	struct const_time_eq_bin_test {
962 		u8 *a;
963 		u8 *b;
964 		size_t len;
965 		unsigned int expected;
966 	} const_time_eq_bin_tests[] = {
967 		{ (u8 *) "", (u8 *) "", 0, ~0 },
968 		{ (u8 *) "abcde", (u8 *) "abcde", 5, ~0 },
969 		{ (u8 *) "abcde", (u8 *) "Abcde", 5, 0 },
970 		{ (u8 *) "abcde", (u8 *) "aBcde", 5, 0 },
971 		{ (u8 *) "abcde", (u8 *) "abCde", 5, 0 },
972 		{ (u8 *) "abcde", (u8 *) "abcDe", 5, 0 },
973 		{ (u8 *) "abcde", (u8 *) "abcdE", 5, 0 },
974 		{ (u8 *) "\x00", (u8 *) "\x01", 1, 0 },
975 		{ (u8 *) "\x00", (u8 *) "\x80", 1, 0 },
976 		{ (u8 *) "\x00", (u8 *) "\x00", 1, ~0 }
977 	};
978 	struct const_time_select_test {
979 		unsigned int mask;
980 		unsigned int true_val;
981 		unsigned int false_val;
982 		unsigned int expected;
983 	} const_time_select_tests[] = {
984 		{ ~0, ~0, ~0, ~0 },
985 		{ 0, ~0, ~0, ~0 },
986 		{ ~0, ~0, 0, ~0 },
987 		{ 0, ~0, 0, 0 },
988 		{ ~0, 0xaaaaaaaa, 0x55555555, 0xaaaaaaaa },
989 		{ 0, 0xaaaaaaaa, 0x55555555, 0x55555555 },
990 		{ ~0, 3, 3, 3 },
991 		{ 0, 3, 3, 3 },
992 		{ ~0, 1, 2, 1 },
993 		{ 0, 1, 2, 2 }
994 	};
995 	struct const_time_select_int_test {
996 		unsigned int mask;
997 		int true_val;
998 		int false_val;
999 		int expected;
1000 	} const_time_select_int_tests[] = {
1001 		{ ~0, -128, 127, -128 },
1002 		{ 0, -128, 127, 127 },
1003 		{ ~0, -2147483648, 2147483647, -2147483648 },
1004 		{ 0, -2147483648, 2147483647, 2147483647 },
1005 		{ ~0, 0, 0, 0 },
1006 		{ 0, 0, 0, 0 },
1007 		{ ~0, -1, 1, -1 },
1008 		{ 0, -1, 1, 1 }
1009 	};
1010 	struct const_time_select_u8_test {
1011 		u8 mask;
1012 		u8 true_val;
1013 		u8 false_val;
1014 		u8 expected;
1015 	} const_time_select_u8_tests[] = {
1016 		{ ~0, ~0, ~0, ~0 },
1017 		{ 0, ~0, ~0, ~0 },
1018 		{ ~0, ~0, 0, ~0 },
1019 		{ 0, ~0, 0, 0 },
1020 		{ ~0, 0xaa, 0x55, 0xaa },
1021 		{ 0, 0xaa, 0x55, 0x55 },
1022 		{ ~0, 1, 2, 1 },
1023 		{ 0, 1, 2, 2 }
1024 	};
1025 	struct const_time_select_s8_test {
1026 		u8 mask;
1027 		s8 true_val;
1028 		s8 false_val;
1029 		s8 expected;
1030 	} const_time_select_s8_tests[] = {
1031 		{ ~0, -128, 127, -128 },
1032 		{ 0, -128, 127, 127 },
1033 		{ ~0, 0, 0, 0 },
1034 		{ 0, 0, 0, 0 },
1035 		{ ~0, -1, 1, -1 },
1036 		{ 0, -1, 1, 1 }
1037 	};
1038 	struct const_time_select_bin_test {
1039 		u8 mask;
1040 		u8 *true_val;
1041 		u8 *false_val;
1042 		size_t len;
1043 		u8 *expected;
1044 	} const_time_select_bin_tests[] = {
1045 		{ ~0, (u8 *) "abcde", (u8 *) "ABCDE", 5, (u8 *) "abcde" },
1046 		{ 0, (u8 *) "abcde", (u8 *) "ABCDE", 5, (u8 *) "ABCDE" },
1047 		{ ~0, (u8 *) "", (u8 *) "", 0, (u8 *) "" },
1048 		{ 0, (u8 *) "", (u8 *) "", 0, (u8 *) "" }
1049 	};
1050 	struct const_time_memcmp_test {
1051 		char *a;
1052 		char *b;
1053 		size_t len;
1054 		int expected;
1055 	} const_time_memcmp_tests[] = {
1056 		{ "abcde", "abcde", 5, 0 },
1057 		{ "abcde", "bbcde", 5, -1 },
1058 		{ "bbcde", "abcde", 5, 1 },
1059 		{ "accde", "abcde", 5, 1 },
1060 		{ "abcee", "abcde", 5, 1 },
1061 		{ "abcdf", "abcde", 5, 1 },
1062 		{ "cbcde", "aXXXX", 5, 2 },
1063 		{ "a", "d", 1, -3 },
1064 		{ "", "", 0, 0 }
1065 	};
1066 	unsigned int i;
1067 	int ret = 0;
1068 
1069 	wpa_printf(MSG_INFO, "constant time tests");
1070 
1071 	for (i = 0; i < ARRAY_SIZE(const_time_fill_msb_tests); i++) {
1072 		struct const_time_fill_msb_test *test;
1073 
1074 		test = &const_time_fill_msb_tests[i];
1075 		if (const_time_fill_msb(test->val) != test->expected) {
1076 			wpa_printf(MSG_ERROR,
1077 				   "const_time_fill_msb(0x%x) test failed",
1078 				   test->val);
1079 			ret = -1;
1080 		}
1081 	}
1082 
1083 	for (i = 0; i < ARRAY_SIZE(const_time_is_zero_tests); i++) {
1084 		struct const_time_is_zero_test *test;
1085 
1086 		test = &const_time_is_zero_tests[i];
1087 		if (const_time_is_zero(test->val) != test->expected) {
1088 			wpa_printf(MSG_ERROR,
1089 				   "const_time_is_zero(0x%x) test failed",
1090 				   test->val);
1091 			ret = -1;
1092 		}
1093 	}
1094 
1095 	for (i = 0; i < ARRAY_SIZE(const_time_eq_tests); i++) {
1096 		struct const_time_eq_test *test;
1097 
1098 		test = &const_time_eq_tests[i];
1099 		if (const_time_eq(test->a, test->b) != test->expected) {
1100 			wpa_printf(MSG_ERROR,
1101 				   "const_time_eq(0x%x,0x%x) test failed",
1102 				   test->a, test->b);
1103 			ret = -1;
1104 		}
1105 		if (const_time_eq_u8(test->a, test->b) != test->expected_u8) {
1106 			wpa_printf(MSG_ERROR,
1107 				   "const_time_eq_u8(0x%x,0x%x) test failed",
1108 				   test->a, test->b);
1109 			ret = -1;
1110 		}
1111 	}
1112 
1113 	for (i = 0; i < ARRAY_SIZE(const_time_eq_bin_tests); i++) {
1114 		struct const_time_eq_bin_test *test;
1115 
1116 		test = &const_time_eq_bin_tests[i];
1117 		if (const_time_eq_bin(test->a, test->b, test->len) !=
1118 		    test->expected) {
1119 			wpa_printf(MSG_ERROR,
1120 				   "const_time_eq_bin(len=%u) test failed",
1121 				   (unsigned int) test->len);
1122 			ret = -1;
1123 		}
1124 	}
1125 
1126 	for (i = 0; i < ARRAY_SIZE(const_time_select_tests); i++) {
1127 		struct const_time_select_test *test;
1128 
1129 		test = &const_time_select_tests[i];
1130 		if (const_time_select(test->mask, test->true_val,
1131 				      test->false_val) != test->expected) {
1132 			wpa_printf(MSG_ERROR,
1133 				   "const_time_select(0x%x,0x%x,0x%x) test failed",
1134 				   test->mask, test->true_val, test->false_val);
1135 			ret = -1;
1136 		}
1137 	}
1138 
1139 	for (i = 0; i < ARRAY_SIZE(const_time_select_int_tests); i++) {
1140 		struct const_time_select_int_test *test;
1141 
1142 		test = &const_time_select_int_tests[i];
1143 		if (const_time_select_int(test->mask, test->true_val,
1144 					  test->false_val) != test->expected) {
1145 			wpa_printf(MSG_ERROR,
1146 				   "const_time_select_int(0x%x,%d,%d) test failed",
1147 				   test->mask, test->true_val, test->false_val);
1148 			ret = -1;
1149 		}
1150 	}
1151 
1152 	for (i = 0; i < ARRAY_SIZE(const_time_select_u8_tests); i++) {
1153 		struct const_time_select_u8_test *test;
1154 
1155 		test = &const_time_select_u8_tests[i];
1156 		if (const_time_select_u8(test->mask, test->true_val,
1157 					 test->false_val) != test->expected) {
1158 			wpa_printf(MSG_ERROR,
1159 				   "const_time_select_u8(0x%x,0x%x,0x%x) test failed",
1160 				   test->mask, test->true_val, test->false_val);
1161 			ret = -1;
1162 		}
1163 	}
1164 
1165 	for (i = 0; i < ARRAY_SIZE(const_time_select_s8_tests); i++) {
1166 		struct const_time_select_s8_test *test;
1167 
1168 		test = &const_time_select_s8_tests[i];
1169 		if (const_time_select_s8(test->mask, test->true_val,
1170 					 test->false_val) != test->expected) {
1171 			wpa_printf(MSG_ERROR,
1172 				   "const_time_select_s8(0x%x,0x%x,0x%x) test failed",
1173 				   test->mask, test->true_val, test->false_val);
1174 			ret = -1;
1175 		}
1176 	}
1177 
1178 	for (i = 0; i < ARRAY_SIZE(const_time_select_bin_tests); i++) {
1179 		struct const_time_select_bin_test *test;
1180 		u8 dst[100];
1181 
1182 		test = &const_time_select_bin_tests[i];
1183 		const_time_select_bin(test->mask, test->true_val,
1184 				      test->false_val, test->len, dst);
1185 		if (os_memcmp(dst, test->expected, test->len) != 0) {
1186 			wpa_printf(MSG_ERROR,
1187 				   "const_time_select_bin(0x%x,%u) test failed",
1188 				   test->mask, (unsigned int) test->len);
1189 			ret = -1;
1190 		}
1191 	}
1192 
1193 	for (i = 0; i < ARRAY_SIZE(const_time_memcmp_tests); i++) {
1194 		struct const_time_memcmp_test *test;
1195 		int res;
1196 
1197 		test = &const_time_memcmp_tests[i];
1198 		res = const_time_memcmp(test->a, test->b, test->len);
1199 		if (res != test->expected) {
1200 			wpa_printf(MSG_ERROR,
1201 				   "const_time_memcmp(%s,%s,%d) test failed (%d != %d)",
1202 				   test->a, test->b, (int) test->len,
1203 				   res, test->expected);
1204 			ret = -1;
1205 		}
1206 	}
1207 
1208 	return ret;
1209 }
1210 
1211 
utils_module_tests(void)1212 int utils_module_tests(void)
1213 {
1214 	int ret = 0;
1215 
1216 	wpa_printf(MSG_INFO, "utils module tests");
1217 
1218 	if (printf_encode_decode_tests() < 0 ||
1219 	    ext_password_tests() < 0 ||
1220 	    trace_tests() < 0 ||
1221 	    bitfield_tests() < 0 ||
1222 	    base64_tests() < 0 ||
1223 	    common_tests() < 0 ||
1224 	    os_tests() < 0 ||
1225 	    wpabuf_tests() < 0 ||
1226 	    ip_addr_tests() < 0 ||
1227 	    eloop_tests() < 0 ||
1228 	    json_tests() < 0 ||
1229 	    const_time_tests() < 0 ||
1230 	    int_array_tests() < 0)
1231 		ret = -1;
1232 
1233 	return ret;
1234 }
1235