• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 	int 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 	size_t res_len;
300 
301 	wpa_printf(MSG_INFO, "base64 tests");
302 
303 	res = base64_encode((const unsigned char *) "", ~0, &res_len);
304 	if (res) {
305 		errors++;
306 		os_free(res);
307 	}
308 
309 	res = base64_encode((const unsigned char *) "=", 1, &res_len);
310 	if (!res || res_len != 5 || res[0] != 'P' || res[1] != 'Q' ||
311 	    res[2] != '=' || res[3] != '=' || res[4] != '\n')
312 		errors++;
313 	os_free(res);
314 
315 	res = base64_encode((const unsigned char *) "=", 1, NULL);
316 	if (!res || res[0] != 'P' || res[1] != 'Q' ||
317 	    res[2] != '=' || res[3] != '=' || res[4] != '\n')
318 		errors++;
319 	os_free(res);
320 
321 	res = base64_decode((const unsigned char *) "", 0, &res_len);
322 	if (res) {
323 		errors++;
324 		os_free(res);
325 	}
326 
327 	res = base64_decode((const unsigned char *) "a", 1, &res_len);
328 	if (res) {
329 		errors++;
330 		os_free(res);
331 	}
332 
333 	res = base64_decode((const unsigned char *) "====", 4, &res_len);
334 	if (res) {
335 		errors++;
336 		os_free(res);
337 	}
338 
339 	res = base64_decode((const unsigned char *) "PQ==", 4, &res_len);
340 	if (!res || res_len != 1 || res[0] != '=')
341 		errors++;
342 	os_free(res);
343 
344 	res = base64_decode((const unsigned char *) "P.Q-=!=*", 8, &res_len);
345 	if (!res || res_len != 1 || res[0] != '=')
346 		errors++;
347 	os_free(res);
348 
349 	if (errors) {
350 		wpa_printf(MSG_ERROR, "%d base64 test(s) failed", errors);
351 		return -1;
352 	}
353 
354 	return 0;
355 }
356 
357 
common_tests(void)358 static int common_tests(void)
359 {
360 	char buf[3], longbuf[100];
361 	u8 addr[ETH_ALEN] = { 1, 2, 3, 4, 5, 6 };
362 	u8 bin[3];
363 	int errors = 0;
364 	struct wpa_freq_range_list ranges;
365 	size_t len;
366 	const char *txt;
367 	u8 ssid[255];
368 
369 	wpa_printf(MSG_INFO, "common tests");
370 
371 	if (hwaddr_mask_txt(buf, 3, addr, addr) != -1)
372 		errors++;
373 
374 	if (wpa_scnprintf(buf, 0, "hello") != 0 ||
375 	    wpa_scnprintf(buf, 3, "hello") != 2)
376 		errors++;
377 
378 	if (wpa_snprintf_hex(buf, 0, addr, ETH_ALEN) != 0 ||
379 	    wpa_snprintf_hex(buf, 3, addr, ETH_ALEN) != 2)
380 		errors++;
381 
382 	if (merge_byte_arrays(bin, 3, addr, ETH_ALEN, NULL, 0) != 3 ||
383 	    merge_byte_arrays(bin, 3, NULL, 0, addr, ETH_ALEN) != 3)
384 		errors++;
385 
386 	if (dup_binstr(NULL, 0) != NULL)
387 		errors++;
388 
389 	if (freq_range_list_includes(NULL, 0) != 0)
390 		errors++;
391 
392 	os_memset(&ranges, 0, sizeof(ranges));
393 	if (freq_range_list_parse(&ranges, "") != 0 ||
394 	    freq_range_list_includes(&ranges, 0) != 0 ||
395 	    freq_range_list_str(&ranges) != NULL)
396 		errors++;
397 
398 	if (utf8_unescape(NULL, 0, buf, sizeof(buf)) != 0 ||
399 	    utf8_unescape("a", 1, NULL, 0) != 0 ||
400 	    utf8_unescape("a\\", 2, buf, sizeof(buf)) != 0 ||
401 	    utf8_unescape("abcde", 5, buf, sizeof(buf)) != 0 ||
402 	    utf8_unescape("abc", 3, buf, 3) != 3)
403 		errors++;
404 
405 	if (utf8_unescape("a", 0, buf, sizeof(buf)) != 1 || buf[0] != 'a')
406 		errors++;
407 
408 	if (utf8_unescape("\\b", 2, buf, sizeof(buf)) != 1 || buf[0] != 'b')
409 		errors++;
410 
411 	if (utf8_escape(NULL, 0, buf, sizeof(buf)) != 0 ||
412 	    utf8_escape("a", 1, NULL, 0) != 0 ||
413 	    utf8_escape("abcde", 5, buf, sizeof(buf)) != 0 ||
414 	    utf8_escape("a\\bcde", 6, buf, sizeof(buf)) != 0 ||
415 	    utf8_escape("ab\\cde", 6, buf, sizeof(buf)) != 0 ||
416 	    utf8_escape("abc\\de", 6, buf, sizeof(buf)) != 0 ||
417 	    utf8_escape("abc", 3, buf, 3) != 3)
418 		errors++;
419 
420 	if (utf8_escape("a", 0, buf, sizeof(buf)) != 1 || buf[0] != 'a')
421 		errors++;
422 
423 	os_memset(ssid, 0, sizeof(ssid));
424 	txt = wpa_ssid_txt(ssid, sizeof(ssid));
425 	len = os_strlen(txt);
426 	/* Verify that SSID_MAX_LEN * 4 buffer limit is enforced. */
427 	if (len != SSID_MAX_LEN * 4) {
428 		wpa_printf(MSG_ERROR,
429 			   "Unexpected wpa_ssid_txt() result with too long SSID");
430 		errors++;
431 	}
432 
433 	if (wpa_snprintf_hex_sep(longbuf, 0, addr, ETH_ALEN, '-') != 0 ||
434 	    wpa_snprintf_hex_sep(longbuf, 5, addr, ETH_ALEN, '-') != 3 ||
435 	    os_strcmp(longbuf, "01-0") != 0)
436 		errors++;
437 
438 	if (errors) {
439 		wpa_printf(MSG_ERROR, "%d common test(s) failed", errors);
440 		return -1;
441 	}
442 
443 	return 0;
444 }
445 
446 
os_tests(void)447 static int os_tests(void)
448 {
449 	int errors = 0;
450 	void *ptr;
451 	os_time_t t;
452 
453 	wpa_printf(MSG_INFO, "os tests");
454 
455 	ptr = os_calloc((size_t) -1, (size_t) -1);
456 	if (ptr) {
457 		errors++;
458 		os_free(ptr);
459 	}
460 	ptr = os_calloc((size_t) 2, (size_t) -1);
461 	if (ptr) {
462 		errors++;
463 		os_free(ptr);
464 	}
465 	ptr = os_calloc((size_t) -1, (size_t) 2);
466 	if (ptr) {
467 		errors++;
468 		os_free(ptr);
469 	}
470 
471 	ptr = os_realloc_array(NULL, (size_t) -1, (size_t) -1);
472 	if (ptr) {
473 		errors++;
474 		os_free(ptr);
475 	}
476 
477 	os_sleep(1, 1);
478 
479 	if (os_mktime(1969, 1, 1, 1, 1, 1, &t) == 0 ||
480 	    os_mktime(1971, 0, 1, 1, 1, 1, &t) == 0 ||
481 	    os_mktime(1971, 13, 1, 1, 1, 1, &t) == 0 ||
482 	    os_mktime(1971, 1, 0, 1, 1, 1, &t) == 0 ||
483 	    os_mktime(1971, 1, 32, 1, 1, 1, &t) == 0 ||
484 	    os_mktime(1971, 1, 1, -1, 1, 1, &t) == 0 ||
485 	    os_mktime(1971, 1, 1, 24, 1, 1, &t) == 0 ||
486 	    os_mktime(1971, 1, 1, 1, -1, 1, &t) == 0 ||
487 	    os_mktime(1971, 1, 1, 1, 60, 1, &t) == 0 ||
488 	    os_mktime(1971, 1, 1, 1, 1, -1, &t) == 0 ||
489 	    os_mktime(1971, 1, 1, 1, 1, 61, &t) == 0 ||
490 	    os_mktime(1971, 1, 1, 1, 1, 1, &t) != 0 ||
491 	    os_mktime(2020, 1, 2, 3, 4, 5, &t) != 0 ||
492 	    os_mktime(2015, 12, 31, 23, 59, 59, &t) != 0)
493 		errors++;
494 
495 	if (os_setenv("hwsim_test_env", "test value", 0) != 0 ||
496 	    os_setenv("hwsim_test_env", "test value 2", 1) != 0 ||
497 	    os_unsetenv("hwsim_test_env") != 0)
498 		errors++;
499 
500 	if (os_file_exists("/this-file-does-not-exists-hwsim") != 0)
501 		errors++;
502 
503 	if (errors) {
504 		wpa_printf(MSG_ERROR, "%d os test(s) failed", errors);
505 		return -1;
506 	}
507 
508 	return 0;
509 }
510 
511 
wpabuf_tests(void)512 static int wpabuf_tests(void)
513 {
514 	int errors = 0;
515 	void *ptr;
516 	struct wpabuf *buf;
517 
518 	wpa_printf(MSG_INFO, "wpabuf tests");
519 
520 	ptr = os_malloc(100);
521 	if (ptr) {
522 		buf = wpabuf_alloc_ext_data(ptr, 100);
523 		if (buf) {
524 			if (wpabuf_resize(&buf, 100) < 0)
525 				errors++;
526 			else
527 				wpabuf_put(buf, 100);
528 			wpabuf_free(buf);
529 		} else {
530 			errors++;
531 			os_free(ptr);
532 		}
533 	} else {
534 		errors++;
535 	}
536 
537 	buf = wpabuf_alloc(100);
538 	if (buf) {
539 		struct wpabuf *buf2;
540 
541 		wpabuf_put(buf, 100);
542 		if (wpabuf_resize(&buf, 100) < 0)
543 			errors++;
544 		else
545 			wpabuf_put(buf, 100);
546 		buf2 = wpabuf_concat(buf, NULL);
547 		if (buf2 != buf)
548 			errors++;
549 		wpabuf_free(buf2);
550 	} else {
551 		errors++;
552 	}
553 
554 	buf = NULL;
555 	buf = wpabuf_zeropad(buf, 10);
556 	if (buf != NULL)
557 		errors++;
558 
559 	if (errors) {
560 		wpa_printf(MSG_ERROR, "%d wpabuf test(s) failed", errors);
561 		return -1;
562 	}
563 
564 	return 0;
565 }
566 
567 
ip_addr_tests(void)568 static int ip_addr_tests(void)
569 {
570 	int errors = 0;
571 	struct hostapd_ip_addr addr;
572 	char buf[100];
573 
574 	wpa_printf(MSG_INFO, "ip_addr tests");
575 
576 	if (hostapd_parse_ip_addr("1.2.3.4", &addr) != 0 ||
577 	    addr.af != AF_INET ||
578 	    hostapd_ip_txt(NULL, buf, sizeof(buf)) != NULL ||
579 	    hostapd_ip_txt(&addr, buf, 1) != buf || buf[0] != '\0' ||
580 	    hostapd_ip_txt(&addr, buf, 0) != NULL ||
581 	    hostapd_ip_txt(&addr, buf, sizeof(buf)) != buf)
582 		errors++;
583 
584 	if (hostapd_parse_ip_addr("::", &addr) != 0 ||
585 	    addr.af != AF_INET6 ||
586 	    hostapd_ip_txt(&addr, buf, 1) != buf || buf[0] != '\0' ||
587 	    hostapd_ip_txt(&addr, buf, sizeof(buf)) != buf)
588 		errors++;
589 
590 	if (errors) {
591 		wpa_printf(MSG_ERROR, "%d ip_addr test(s) failed", errors);
592 		return -1;
593 	}
594 
595 	return 0;
596 }
597 
598 
599 struct test_eloop {
600 	unsigned int magic;
601 	int close_in_timeout;
602 	int pipefd1[2];
603 	int pipefd2[2];
604 };
605 
606 
607 static void eloop_tests_start(int close_in_timeout);
608 
609 
eloop_test_read_2(int sock,void * eloop_ctx,void * sock_ctx)610 static void eloop_test_read_2(int sock, void *eloop_ctx, void *sock_ctx)
611 {
612 	struct test_eloop *t = eloop_ctx;
613 	ssize_t res;
614 	char buf[10];
615 
616 	wpa_printf(MSG_INFO, "%s: sock=%d", __func__, sock);
617 
618 	if (t->magic != 0x12345678) {
619 		wpa_printf(MSG_INFO, "%s: unexpected magic 0x%x",
620 			   __func__, t->magic);
621 	}
622 
623 	if (t->pipefd2[0] != sock) {
624 		wpa_printf(MSG_INFO, "%s: unexpected sock %d != %d",
625 			   __func__, sock, t->pipefd2[0]);
626 	}
627 
628 	res = read(sock, buf, sizeof(buf));
629 	wpa_printf(MSG_INFO, "%s: sock=%d --> res=%d",
630 		   __func__, sock, (int) res);
631 }
632 
633 
eloop_test_read_2_wrong(int sock,void * eloop_ctx,void * sock_ctx)634 static void eloop_test_read_2_wrong(int sock, void *eloop_ctx, void *sock_ctx)
635 {
636 	struct test_eloop *t = eloop_ctx;
637 
638 	wpa_printf(MSG_INFO, "%s: sock=%d", __func__, sock);
639 
640 	if (t->magic != 0x12345678) {
641 		wpa_printf(MSG_INFO, "%s: unexpected magic 0x%x",
642 			   __func__, t->magic);
643 	}
644 
645 	if (t->pipefd2[0] != sock) {
646 		wpa_printf(MSG_INFO, "%s: unexpected sock %d != %d",
647 			   __func__, sock, t->pipefd2[0]);
648 	}
649 
650 	/*
651 	 * This is expected to block due to the original socket with data having
652 	 * been closed and no new data having been written to the new socket
653 	 * with the same fd. To avoid blocking the process during test, skip the
654 	 * read here.
655 	 */
656 	wpa_printf(MSG_ERROR, "%s: FAIL - should not have called this function",
657 		   __func__);
658 }
659 
660 
reopen_pipefd2(struct test_eloop * t)661 static void reopen_pipefd2(struct test_eloop *t)
662 {
663 	if (t->pipefd2[0] < 0) {
664 		wpa_printf(MSG_INFO, "pipefd2 had been closed");
665 	} else {
666 		int res;
667 
668 		wpa_printf(MSG_INFO, "close pipefd2");
669 		eloop_unregister_read_sock(t->pipefd2[0]);
670 		close(t->pipefd2[0]);
671 		t->pipefd2[0] = -1;
672 		close(t->pipefd2[1]);
673 		t->pipefd2[1] = -1;
674 
675 		res = pipe(t->pipefd2);
676 		if (res < 0) {
677 			wpa_printf(MSG_INFO, "pipe: %s", strerror(errno));
678 			t->pipefd2[0] = -1;
679 			t->pipefd2[1] = -1;
680 			return;
681 		}
682 
683 		wpa_printf(MSG_INFO,
684 			   "re-register pipefd2 with new sockets %d,%d",
685 			   t->pipefd2[0], t->pipefd2[1]);
686 		eloop_register_read_sock(t->pipefd2[0], eloop_test_read_2_wrong,
687 					 t, NULL);
688 	}
689 }
690 
691 
eloop_test_read_1(int sock,void * eloop_ctx,void * sock_ctx)692 static void eloop_test_read_1(int sock, void *eloop_ctx, void *sock_ctx)
693 {
694 	struct test_eloop *t = eloop_ctx;
695 	ssize_t res;
696 	char buf[10];
697 
698 	wpa_printf(MSG_INFO, "%s: sock=%d", __func__, sock);
699 
700 	if (t->magic != 0x12345678) {
701 		wpa_printf(MSG_INFO, "%s: unexpected magic 0x%x",
702 			   __func__, t->magic);
703 	}
704 
705 	if (t->pipefd1[0] != sock) {
706 		wpa_printf(MSG_INFO, "%s: unexpected sock %d != %d",
707 			   __func__, sock, t->pipefd1[0]);
708 	}
709 
710 	res = read(sock, buf, sizeof(buf));
711 	wpa_printf(MSG_INFO, "%s: sock=%d --> res=%d",
712 		   __func__, sock, (int) res);
713 
714 	if (!t->close_in_timeout)
715 		reopen_pipefd2(t);
716 }
717 
718 
eloop_test_cb(void * eloop_data,void * user_ctx)719 static void eloop_test_cb(void *eloop_data, void *user_ctx)
720 {
721 	struct test_eloop *t = eloop_data;
722 
723 	wpa_printf(MSG_INFO, "%s", __func__);
724 
725 	if (t->magic != 0x12345678) {
726 		wpa_printf(MSG_INFO, "%s: unexpected magic 0x%x",
727 			   __func__, t->magic);
728 	}
729 
730 	if (t->close_in_timeout)
731 		reopen_pipefd2(t);
732 }
733 
734 
eloop_test_timeout(void * eloop_data,void * user_ctx)735 static void eloop_test_timeout(void *eloop_data, void *user_ctx)
736 {
737 	struct test_eloop *t = eloop_data;
738 	int next_run = 0;
739 
740 	wpa_printf(MSG_INFO, "%s", __func__);
741 
742 	if (t->magic != 0x12345678) {
743 		wpa_printf(MSG_INFO, "%s: unexpected magic 0x%x",
744 			   __func__, t->magic);
745 	}
746 
747 	if (t->pipefd1[0] >= 0) {
748 		wpa_printf(MSG_INFO, "pipefd1 had not been closed");
749 		eloop_unregister_read_sock(t->pipefd1[0]);
750 		close(t->pipefd1[0]);
751 		t->pipefd1[0] = -1;
752 		close(t->pipefd1[1]);
753 		t->pipefd1[1] = -1;
754 	}
755 
756 	if (t->pipefd2[0] >= 0) {
757 		wpa_printf(MSG_INFO, "pipefd2 had not been closed");
758 		eloop_unregister_read_sock(t->pipefd2[0]);
759 		close(t->pipefd2[0]);
760 		t->pipefd2[0] = -1;
761 		close(t->pipefd2[1]);
762 		t->pipefd2[1] = -1;
763 	}
764 
765 	next_run = t->close_in_timeout;
766 	t->magic = 0;
767 	wpa_printf(MSG_INFO, "%s - free(%p)", __func__, t);
768 	os_free(t);
769 
770 	if (next_run)
771 		eloop_tests_start(0);
772 }
773 
774 
eloop_tests_start(int close_in_timeout)775 static void eloop_tests_start(int close_in_timeout)
776 {
777 	struct test_eloop *t;
778 	int res;
779 
780 	t = os_zalloc(sizeof(*t));
781 	if (!t)
782 		return;
783 	t->magic = 0x12345678;
784 	t->close_in_timeout = close_in_timeout;
785 
786 	wpa_printf(MSG_INFO, "starting eloop tests (%p) (close_in_timeout=%d)",
787 		   t, close_in_timeout);
788 
789 	res = pipe(t->pipefd1);
790 	if (res < 0) {
791 		wpa_printf(MSG_INFO, "pipe: %s", strerror(errno));
792 		os_free(t);
793 		return;
794 	}
795 
796 	res = pipe(t->pipefd2);
797 	if (res < 0) {
798 		wpa_printf(MSG_INFO, "pipe: %s", strerror(errno));
799 		close(t->pipefd1[0]);
800 		close(t->pipefd1[1]);
801 		os_free(t);
802 		return;
803 	}
804 
805 	wpa_printf(MSG_INFO, "pipe fds: %d,%d %d,%d",
806 		   t->pipefd1[0], t->pipefd1[1],
807 		   t->pipefd2[0], t->pipefd2[1]);
808 
809 	eloop_register_read_sock(t->pipefd1[0], eloop_test_read_1, t, NULL);
810 	eloop_register_read_sock(t->pipefd2[0], eloop_test_read_2, t, NULL);
811 	eloop_register_timeout(0, 0, eloop_test_cb, t, NULL);
812 	eloop_register_timeout(0, 200000, eloop_test_timeout, t, NULL);
813 
814 	if (write(t->pipefd1[1], "HELLO", 5) < 0)
815 		wpa_printf(MSG_INFO, "write: %s", strerror(errno));
816 	if (write(t->pipefd2[1], "TEST", 4) < 0)
817 		wpa_printf(MSG_INFO, "write: %s", strerror(errno));
818 	os_sleep(0, 50000);
819 	wpa_printf(MSG_INFO, "waiting for eloop callbacks");
820 }
821 
822 
eloop_tests_run(void * eloop_data,void * user_ctx)823 static void eloop_tests_run(void *eloop_data, void *user_ctx)
824 {
825 	eloop_tests_start(1);
826 }
827 
828 
eloop_tests(void)829 static int eloop_tests(void)
830 {
831 	wpa_printf(MSG_INFO, "schedule eloop tests to be run");
832 
833 	/*
834 	 * Cannot return error from these without a significant design change,
835 	 * so for now, run the tests from a scheduled timeout and require
836 	 * separate verification of the results from the debug log.
837 	 */
838 	eloop_register_timeout(0, 0, eloop_tests_run, NULL, NULL);
839 
840 	return 0;
841 }
842 
843 
844 #ifdef CONFIG_JSON
845 struct json_test_data {
846 	const char *json;
847 	const char *tree;
848 };
849 
850 static const struct json_test_data json_test_cases[] = {
851 	{ "{}", "[1:OBJECT:]" },
852 	{ "[]", "[1:ARRAY:]" },
853 	{ "{", NULL },
854 	{ "[", NULL },
855 	{ "}", NULL },
856 	{ "]", NULL },
857 	{ "[[]]", "[1:ARRAY:][2:ARRAY:]" },
858 	{ "{\"t\":\"test\"}", "[1:OBJECT:][2:STRING:t]" },
859 	{ "{\"t\":123}", "[1:OBJECT:][2:NUMBER:t]" },
860 	{ "{\"t\":true}", "[1:OBJECT:][2:BOOLEAN:t]" },
861 	{ "{\"t\":false}", "[1:OBJECT:][2:BOOLEAN:t]" },
862 	{ "{\"t\":null}", "[1:OBJECT:][2:NULL:t]" },
863 	{ "{\"t\":truetrue}", NULL },
864 	{ "\"test\"", "[1:STRING:]" },
865 	{ "123", "[1:NUMBER:]" },
866 	{ "true", "[1:BOOLEAN:]" },
867 	{ "false", "[1:BOOLEAN:]" },
868 	{ "null", "[1:NULL:]" },
869 	{ "truetrue", NULL },
870 	{ " {\t\n\r\"a\"\n:\r1\n,\n\"b\":3\n}\n",
871 	  "[1:OBJECT:][2:NUMBER:a][2:NUMBER:b]" },
872 	{ ",", NULL },
873 	{ "{,}", NULL },
874 	{ "[,]", NULL },
875 	{ ":", NULL },
876 	{ "{:}", NULL },
877 	{ "[:]", NULL },
878 	{ "{ \"\\u005c\" : \"\\u005c\" }", "[1:OBJECT:][2:STRING:\\]" },
879 	{ "[{},{}]", "[1:ARRAY:][2:OBJECT:][2:OBJECT:]" },
880 	{ "[1,2]", "[1:ARRAY:][2:NUMBER:][2:NUMBER:]" },
881 	{ "[\"1\",\"2\"]", "[1:ARRAY:][2:STRING:][2:STRING:]" },
882 	{ "[true,false]", "[1:ARRAY:][2:BOOLEAN:][2:BOOLEAN:]" },
883 };
884 #endif /* CONFIG_JSON */
885 
886 
json_tests(void)887 static int json_tests(void)
888 {
889 #ifdef CONFIG_JSON
890 	unsigned int i;
891 	struct json_token *root;
892 	char buf[1000];
893 
894 	wpa_printf(MSG_INFO, "JSON tests");
895 
896 	for (i = 0; i < ARRAY_SIZE(json_test_cases); i++) {
897 		const struct json_test_data *test = &json_test_cases[i];
898 		int res = 0;
899 
900 		root = json_parse(test->json, os_strlen(test->json));
901 		if ((root && !test->tree) || (!root && test->tree)) {
902 			wpa_printf(MSG_INFO, "JSON test %u failed", i);
903 			res = -1;
904 		} else if (root) {
905 			json_print_tree(root, buf, sizeof(buf));
906 			if (os_strcmp(buf, test->tree) != 0) {
907 				wpa_printf(MSG_INFO,
908 					   "JSON test %u tree mismatch: %s %s",
909 					   i, buf, test->tree);
910 				res = -1;
911 			}
912 		}
913 		json_free(root);
914 		if (res < 0)
915 			return -1;
916 
917 	}
918 #endif /* CONFIG_JSON */
919 	return 0;
920 }
921 
922 
const_time_tests(void)923 static int const_time_tests(void)
924 {
925 	struct const_time_fill_msb_test {
926 		unsigned int val;
927 		unsigned int expected;
928 	} const_time_fill_msb_tests[] = {
929 		{ 0, 0 },
930 		{ 1, 0 },
931 		{ 2, 0 },
932 		{ 1 << (sizeof(unsigned int) * 8 - 1), ~0 },
933 		{ ~0 - 1, ~0 },
934 		{ ~0, ~0 }
935 	};
936 	struct const_time_is_zero_test {
937 		unsigned int val;
938 		unsigned int expected;
939 	} const_time_is_zero_tests[] = {
940 		{ 0, ~0 },
941 		{ 1, 0 },
942 		{ 2, 0 },
943 		{ 1 << (sizeof(unsigned int) * 8 - 1), 0 },
944 		{ ~0 - 1, 0 },
945 		{ ~0, 0 }
946 	};
947 	struct const_time_eq_test {
948 		unsigned int a;
949 		unsigned int b;
950 		unsigned int expected;
951 		unsigned int expected_u8;
952 	} const_time_eq_tests[] = {
953 		{ 0, 1, 0, 0 },
954 		{ 1, 2, 0, 0 },
955 		{ 1, 1, ~0, 0xff },
956 		{ ~0, ~0, ~0, 0xff },
957 		{ ~0, ~0 - 1, 0, 0 },
958 		{ 0, 0, ~0, 0xff }
959 	};
960 	struct const_time_eq_bin_test {
961 		u8 *a;
962 		u8 *b;
963 		size_t len;
964 		unsigned int expected;
965 	} const_time_eq_bin_tests[] = {
966 		{ (u8 *) "", (u8 *) "", 0, ~0 },
967 		{ (u8 *) "abcde", (u8 *) "abcde", 5, ~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 *) "\x00", (u8 *) "\x01", 1, 0 },
974 		{ (u8 *) "\x00", (u8 *) "\x80", 1, 0 },
975 		{ (u8 *) "\x00", (u8 *) "\x00", 1, ~0 }
976 	};
977 	struct const_time_select_test {
978 		unsigned int mask;
979 		unsigned int true_val;
980 		unsigned int false_val;
981 		unsigned int expected;
982 	} const_time_select_tests[] = {
983 		{ ~0, ~0, ~0, ~0 },
984 		{ 0, ~0, ~0, ~0 },
985 		{ ~0, ~0, 0, ~0 },
986 		{ 0, ~0, 0, 0 },
987 		{ ~0, 0xaaaaaaaa, 0x55555555, 0xaaaaaaaa },
988 		{ 0, 0xaaaaaaaa, 0x55555555, 0x55555555 },
989 		{ ~0, 3, 3, 3 },
990 		{ 0, 3, 3, 3 },
991 		{ ~0, 1, 2, 1 },
992 		{ 0, 1, 2, 2 }
993 	};
994 	struct const_time_select_int_test {
995 		unsigned int mask;
996 		int true_val;
997 		int false_val;
998 		int expected;
999 	} const_time_select_int_tests[] = {
1000 		{ ~0, -128, 127, -128 },
1001 		{ 0, -128, 127, 127 },
1002 		{ ~0, -2147483648, 2147483647, -2147483648 },
1003 		{ 0, -2147483648, 2147483647, 2147483647 },
1004 		{ ~0, 0, 0, 0 },
1005 		{ 0, 0, 0, 0 },
1006 		{ ~0, -1, 1, -1 },
1007 		{ 0, -1, 1, 1 }
1008 	};
1009 	struct const_time_select_u8_test {
1010 		u8 mask;
1011 		u8 true_val;
1012 		u8 false_val;
1013 		u8 expected;
1014 	} const_time_select_u8_tests[] = {
1015 		{ ~0, ~0, ~0, ~0 },
1016 		{ 0, ~0, ~0, ~0 },
1017 		{ ~0, ~0, 0, ~0 },
1018 		{ 0, ~0, 0, 0 },
1019 		{ ~0, 0xaa, 0x55, 0xaa },
1020 		{ 0, 0xaa, 0x55, 0x55 },
1021 		{ ~0, 1, 2, 1 },
1022 		{ 0, 1, 2, 2 }
1023 	};
1024 	struct const_time_select_s8_test {
1025 		u8 mask;
1026 		s8 true_val;
1027 		s8 false_val;
1028 		s8 expected;
1029 	} const_time_select_s8_tests[] = {
1030 		{ ~0, -128, 127, -128 },
1031 		{ 0, -128, 127, 127 },
1032 		{ ~0, 0, 0, 0 },
1033 		{ 0, 0, 0, 0 },
1034 		{ ~0, -1, 1, -1 },
1035 		{ 0, -1, 1, 1 }
1036 	};
1037 	struct const_time_select_bin_test {
1038 		u8 mask;
1039 		u8 *true_val;
1040 		u8 *false_val;
1041 		size_t len;
1042 		u8 *expected;
1043 	} const_time_select_bin_tests[] = {
1044 		{ ~0, (u8 *) "abcde", (u8 *) "ABCDE", 5, (u8 *) "abcde" },
1045 		{ 0, (u8 *) "abcde", (u8 *) "ABCDE", 5, (u8 *) "ABCDE" },
1046 		{ ~0, (u8 *) "", (u8 *) "", 0, (u8 *) "" },
1047 		{ 0, (u8 *) "", (u8 *) "", 0, (u8 *) "" }
1048 	};
1049 	struct const_time_memcmp_test {
1050 		char *a;
1051 		char *b;
1052 		size_t len;
1053 		int expected;
1054 	} const_time_memcmp_tests[] = {
1055 		{ "abcde", "abcde", 5, 0 },
1056 		{ "abcde", "bbcde", 5, -1 },
1057 		{ "bbcde", "abcde", 5, 1 },
1058 		{ "accde", "abcde", 5, 1 },
1059 		{ "abcee", "abcde", 5, 1 },
1060 		{ "abcdf", "abcde", 5, 1 },
1061 		{ "cbcde", "aXXXX", 5, 2 },
1062 		{ "a", "d", 1, -3 },
1063 		{ "", "", 0, 0 }
1064 	};
1065 	unsigned int i;
1066 	int ret = 0;
1067 
1068 	wpa_printf(MSG_INFO, "constant time tests");
1069 
1070 	for (i = 0; i < ARRAY_SIZE(const_time_fill_msb_tests); i++) {
1071 		struct const_time_fill_msb_test *test;
1072 
1073 		test = &const_time_fill_msb_tests[i];
1074 		if (const_time_fill_msb(test->val) != test->expected) {
1075 			wpa_printf(MSG_ERROR,
1076 				   "const_time_fill_msb(0x%x) test failed",
1077 				   test->val);
1078 			ret = -1;
1079 		}
1080 	}
1081 
1082 	for (i = 0; i < ARRAY_SIZE(const_time_is_zero_tests); i++) {
1083 		struct const_time_is_zero_test *test;
1084 
1085 		test = &const_time_is_zero_tests[i];
1086 		if (const_time_is_zero(test->val) != test->expected) {
1087 			wpa_printf(MSG_ERROR,
1088 				   "const_time_is_zero(0x%x) test failed",
1089 				   test->val);
1090 			ret = -1;
1091 		}
1092 	}
1093 
1094 	for (i = 0; i < ARRAY_SIZE(const_time_eq_tests); i++) {
1095 		struct const_time_eq_test *test;
1096 
1097 		test = &const_time_eq_tests[i];
1098 		if (const_time_eq(test->a, test->b) != test->expected) {
1099 			wpa_printf(MSG_ERROR,
1100 				   "const_time_eq(0x%x,0x%x) test failed",
1101 				   test->a, test->b);
1102 			ret = -1;
1103 		}
1104 		if (const_time_eq_u8(test->a, test->b) != test->expected_u8) {
1105 			wpa_printf(MSG_ERROR,
1106 				   "const_time_eq_u8(0x%x,0x%x) test failed",
1107 				   test->a, test->b);
1108 			ret = -1;
1109 		}
1110 	}
1111 
1112 	for (i = 0; i < ARRAY_SIZE(const_time_eq_bin_tests); i++) {
1113 		struct const_time_eq_bin_test *test;
1114 
1115 		test = &const_time_eq_bin_tests[i];
1116 		if (const_time_eq_bin(test->a, test->b, test->len) !=
1117 		    test->expected) {
1118 			wpa_printf(MSG_ERROR,
1119 				   "const_time_eq_bin(len=%u) test failed",
1120 				   (unsigned int) test->len);
1121 			ret = -1;
1122 		}
1123 	}
1124 
1125 	for (i = 0; i < ARRAY_SIZE(const_time_select_tests); i++) {
1126 		struct const_time_select_test *test;
1127 
1128 		test = &const_time_select_tests[i];
1129 		if (const_time_select(test->mask, test->true_val,
1130 				      test->false_val) != test->expected) {
1131 			wpa_printf(MSG_ERROR,
1132 				   "const_time_select(0x%x,0x%x,0x%x) test failed",
1133 				   test->mask, test->true_val, test->false_val);
1134 			ret = -1;
1135 		}
1136 	}
1137 
1138 	for (i = 0; i < ARRAY_SIZE(const_time_select_int_tests); i++) {
1139 		struct const_time_select_int_test *test;
1140 
1141 		test = &const_time_select_int_tests[i];
1142 		if (const_time_select_int(test->mask, test->true_val,
1143 					  test->false_val) != test->expected) {
1144 			wpa_printf(MSG_ERROR,
1145 				   "const_time_select_int(0x%x,%d,%d) test failed",
1146 				   test->mask, test->true_val, test->false_val);
1147 			ret = -1;
1148 		}
1149 	}
1150 
1151 	for (i = 0; i < ARRAY_SIZE(const_time_select_u8_tests); i++) {
1152 		struct const_time_select_u8_test *test;
1153 
1154 		test = &const_time_select_u8_tests[i];
1155 		if (const_time_select_u8(test->mask, test->true_val,
1156 					 test->false_val) != test->expected) {
1157 			wpa_printf(MSG_ERROR,
1158 				   "const_time_select_u8(0x%x,0x%x,0x%x) test failed",
1159 				   test->mask, test->true_val, test->false_val);
1160 			ret = -1;
1161 		}
1162 	}
1163 
1164 	for (i = 0; i < ARRAY_SIZE(const_time_select_s8_tests); i++) {
1165 		struct const_time_select_s8_test *test;
1166 
1167 		test = &const_time_select_s8_tests[i];
1168 		if (const_time_select_s8(test->mask, test->true_val,
1169 					 test->false_val) != test->expected) {
1170 			wpa_printf(MSG_ERROR,
1171 				   "const_time_select_s8(0x%x,0x%x,0x%x) test failed",
1172 				   test->mask, test->true_val, test->false_val);
1173 			ret = -1;
1174 		}
1175 	}
1176 
1177 	for (i = 0; i < ARRAY_SIZE(const_time_select_bin_tests); i++) {
1178 		struct const_time_select_bin_test *test;
1179 		u8 dst[100];
1180 
1181 		test = &const_time_select_bin_tests[i];
1182 		const_time_select_bin(test->mask, test->true_val,
1183 				      test->false_val, test->len, dst);
1184 		if (os_memcmp(dst, test->expected, test->len) != 0) {
1185 			wpa_printf(MSG_ERROR,
1186 				   "const_time_select_bin(0x%x,%u) test failed",
1187 				   test->mask, (unsigned int) test->len);
1188 			ret = -1;
1189 		}
1190 	}
1191 
1192 	for (i = 0; i < ARRAY_SIZE(const_time_memcmp_tests); i++) {
1193 		struct const_time_memcmp_test *test;
1194 		int res;
1195 
1196 		test = &const_time_memcmp_tests[i];
1197 		res = const_time_memcmp(test->a, test->b, test->len);
1198 		if (res != test->expected) {
1199 			wpa_printf(MSG_ERROR,
1200 				   "const_time_memcmp(%s,%s,%d) test failed (%d != %d)",
1201 				   test->a, test->b, (int) test->len,
1202 				   res, test->expected);
1203 			ret = -1;
1204 		}
1205 	}
1206 
1207 	return ret;
1208 }
1209 
1210 
utils_module_tests(void)1211 int utils_module_tests(void)
1212 {
1213 	int ret = 0;
1214 
1215 	wpa_printf(MSG_INFO, "utils module tests");
1216 
1217 	if (printf_encode_decode_tests() < 0 ||
1218 	    ext_password_tests() < 0 ||
1219 	    trace_tests() < 0 ||
1220 	    bitfield_tests() < 0 ||
1221 	    base64_tests() < 0 ||
1222 	    common_tests() < 0 ||
1223 	    os_tests() < 0 ||
1224 	    wpabuf_tests() < 0 ||
1225 	    ip_addr_tests() < 0 ||
1226 	    eloop_tests() < 0 ||
1227 	    json_tests() < 0 ||
1228 	    const_time_tests() < 0 ||
1229 	    int_array_tests() < 0)
1230 		ret = -1;
1231 
1232 	return ret;
1233 }
1234