xref: /dragonfly/contrib/wpa_supplicant/src/utils/utils_module_tests.c (revision 3a84a4273475ed07d0ab1c2dfeffdfedef35d9cd)
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