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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 896 static void eloop_tests_run(void *eloop_data, void *user_ctx) 897 { 898 eloop_tests_start(1); 899 } 900 901 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 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 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 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