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