1 /* 2 * OS specific functions for UNIX/POSIX systems 3 * Copyright (c) 2005-2009, 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 "includes.h" 10 11 #include <time.h> 12 #include <sys/wait.h> 13 14 #ifdef ANDROID 15 #include <sys/capability.h> 16 #include <sys/prctl.h> 17 #include <private/android_filesystem_config.h> 18 #endif /* ANDROID */ 19 20 #ifdef __MACH__ 21 #include <CoreServices/CoreServices.h> 22 #include <mach/mach.h> 23 #include <mach/mach_time.h> 24 #endif /* __MACH__ */ 25 26 #include "os.h" 27 #include "common.h" 28 29 #ifdef WPA_TRACE 30 31 #include "wpa_debug.h" 32 #include "trace.h" 33 #include "list.h" 34 35 static struct dl_list alloc_list = DL_LIST_HEAD_INIT(alloc_list); 36 37 #define ALLOC_MAGIC 0xa84ef1b2 38 #define FREED_MAGIC 0x67fd487a 39 40 struct os_alloc_trace { 41 unsigned int magic; 42 struct dl_list list; 43 size_t len; 44 WPA_TRACE_INFO 45 } __attribute__((aligned(16))); 46 47 #endif /* WPA_TRACE */ 48 49 50 void os_sleep(os_time_t sec, os_time_t usec) 51 { 52 if (sec) 53 sleep(sec); 54 if (usec) 55 usleep(usec); 56 } 57 58 59 int os_get_time(struct os_time *t) 60 { 61 int res; 62 struct timeval tv; 63 res = gettimeofday(&tv, NULL); 64 t->sec = tv.tv_sec; 65 t->usec = tv.tv_usec; 66 return res; 67 } 68 69 70 int os_get_reltime(struct os_reltime *t) 71 { 72 #ifndef __MACH__ 73 #if defined(CLOCK_BOOTTIME) 74 static clockid_t clock_id = CLOCK_BOOTTIME; 75 #elif defined(CLOCK_MONOTONIC) 76 static clockid_t clock_id = CLOCK_MONOTONIC; 77 #else 78 static clockid_t clock_id = CLOCK_REALTIME; 79 #endif 80 struct timespec ts; 81 int res; 82 83 while (1) { 84 res = clock_gettime(clock_id, &ts); 85 if (res == 0) { 86 t->sec = ts.tv_sec; 87 t->usec = ts.tv_nsec / 1000; 88 return 0; 89 } 90 switch (clock_id) { 91 #ifdef CLOCK_BOOTTIME 92 case CLOCK_BOOTTIME: 93 clock_id = CLOCK_MONOTONIC; 94 break; 95 #endif 96 #ifdef CLOCK_MONOTONIC 97 case CLOCK_MONOTONIC: 98 clock_id = CLOCK_REALTIME; 99 break; 100 #endif 101 case CLOCK_REALTIME: 102 return -1; 103 } 104 } 105 #else /* __MACH__ */ 106 uint64_t abstime, nano; 107 static mach_timebase_info_data_t info = { 0, 0 }; 108 109 if (!info.denom) { 110 if (mach_timebase_info(&info) != KERN_SUCCESS) 111 return -1; 112 } 113 114 abstime = mach_absolute_time(); 115 nano = (abstime * info.numer) / info.denom; 116 117 t->sec = nano / NSEC_PER_SEC; 118 t->usec = (nano - (((uint64_t) t->sec) * NSEC_PER_SEC)) / NSEC_PER_USEC; 119 120 return 0; 121 #endif /* __MACH__ */ 122 } 123 124 125 int os_mktime(int year, int month, int day, int hour, int min, int sec, 126 os_time_t *t) 127 { 128 struct tm tm, *tm1; 129 time_t t_local, t1, t2; 130 os_time_t tz_offset; 131 132 if (year < 1970 || month < 1 || month > 12 || day < 1 || day > 31 || 133 hour < 0 || hour > 23 || min < 0 || min > 59 || sec < 0 || 134 sec > 60) 135 return -1; 136 137 memset(&tm, 0, sizeof(tm)); 138 tm.tm_year = year - 1900; 139 tm.tm_mon = month - 1; 140 tm.tm_mday = day; 141 tm.tm_hour = hour; 142 tm.tm_min = min; 143 tm.tm_sec = sec; 144 145 t_local = mktime(&tm); 146 147 /* figure out offset to UTC */ 148 tm1 = localtime(&t_local); 149 if (tm1) { 150 t1 = mktime(tm1); 151 tm1 = gmtime(&t_local); 152 if (tm1) { 153 t2 = mktime(tm1); 154 tz_offset = t2 - t1; 155 } else 156 tz_offset = 0; 157 } else 158 tz_offset = 0; 159 160 *t = (os_time_t) t_local - tz_offset; 161 return 0; 162 } 163 164 165 int os_gmtime(os_time_t t, struct os_tm *tm) 166 { 167 struct tm *tm2; 168 time_t t2 = t; 169 170 tm2 = gmtime(&t2); 171 if (tm2 == NULL) 172 return -1; 173 tm->sec = tm2->tm_sec; 174 tm->min = tm2->tm_min; 175 tm->hour = tm2->tm_hour; 176 tm->day = tm2->tm_mday; 177 tm->month = tm2->tm_mon + 1; 178 tm->year = tm2->tm_year + 1900; 179 return 0; 180 } 181 182 183 #ifdef __APPLE__ 184 #include <fcntl.h> 185 static int os_daemon(int nochdir, int noclose) 186 { 187 int devnull; 188 189 if (chdir("/") < 0) 190 return -1; 191 192 devnull = open("/dev/null", O_RDWR); 193 if (devnull < 0) 194 return -1; 195 196 if (dup2(devnull, STDIN_FILENO) < 0) { 197 close(devnull); 198 return -1; 199 } 200 201 if (dup2(devnull, STDOUT_FILENO) < 0) { 202 close(devnull); 203 return -1; 204 } 205 206 if (dup2(devnull, STDERR_FILENO) < 0) { 207 close(devnull); 208 return -1; 209 } 210 211 return 0; 212 } 213 #else /* __APPLE__ */ 214 #define os_daemon daemon 215 #endif /* __APPLE__ */ 216 217 218 #ifdef __FreeBSD__ 219 #include <err.h> 220 #include <libutil.h> 221 #include <stdint.h> 222 #endif /* __FreeBSD__ */ 223 224 int os_daemonize(const char *pid_file) 225 { 226 #if defined(__uClinux__) || defined(__sun__) 227 return -1; 228 #else /* defined(__uClinux__) || defined(__sun__) */ 229 #ifdef __FreeBSD__ 230 pid_t otherpid; 231 struct pidfh *pfh; 232 233 pfh = pidfile_open(pid_file, 0600, &otherpid); 234 if (pfh == NULL) { 235 if (errno == EEXIST) { 236 errx(1, "Daemon already running, pid: %jd.", 237 (intmax_t)otherpid); 238 } 239 warn("Cannot open or create pidfile."); 240 } 241 #endif /* __FreeBSD__ */ 242 243 if (os_daemon(0, 0)) { 244 perror("daemon"); 245 #ifdef __FreeBSD__ 246 pidfile_remove(pfh); 247 #endif /* __FreeBSD__ */ 248 return -1; 249 } 250 251 #ifndef __FreeBSD__ 252 if (pid_file) { 253 FILE *f = fopen(pid_file, "w"); 254 if (f) { 255 fprintf(f, "%u\n", getpid()); 256 fclose(f); 257 } 258 } 259 #else /* __FreeBSD__ */ 260 pidfile_write(pfh); 261 #endif /* __FreeBSD__ */ 262 263 return -0; 264 #endif /* defined(__uClinux__) || defined(__sun__) */ 265 } 266 267 268 void os_daemonize_terminate(const char *pid_file) 269 { 270 if (pid_file) 271 unlink(pid_file); 272 } 273 274 275 int os_get_random(unsigned char *buf, size_t len) 276 { 277 FILE *f; 278 size_t rc; 279 280 if (TEST_FAIL()) 281 return -1; 282 283 f = fopen("/dev/urandom", "rb"); 284 if (f == NULL) { 285 printf("Could not open /dev/urandom.\n"); 286 return -1; 287 } 288 289 rc = fread(buf, 1, len, f); 290 fclose(f); 291 292 return rc != len ? -1 : 0; 293 } 294 295 296 unsigned long os_random(void) 297 { 298 return random(); 299 } 300 301 302 char * os_rel2abs_path(const char *rel_path) 303 { 304 char *buf = NULL, *cwd, *ret; 305 size_t len = 128, cwd_len, rel_len, ret_len; 306 int last_errno; 307 308 if (!rel_path) 309 return NULL; 310 311 if (rel_path[0] == '/') 312 return os_strdup(rel_path); 313 314 for (;;) { 315 buf = os_malloc(len); 316 if (buf == NULL) 317 return NULL; 318 cwd = getcwd(buf, len); 319 if (cwd == NULL) { 320 last_errno = errno; 321 os_free(buf); 322 if (last_errno != ERANGE) 323 return NULL; 324 len *= 2; 325 if (len > 2000) 326 return NULL; 327 } else { 328 buf[len - 1] = '\0'; 329 break; 330 } 331 } 332 333 cwd_len = os_strlen(cwd); 334 rel_len = os_strlen(rel_path); 335 ret_len = cwd_len + 1 + rel_len + 1; 336 ret = os_malloc(ret_len); 337 if (ret) { 338 os_memcpy(ret, cwd, cwd_len); 339 ret[cwd_len] = '/'; 340 os_memcpy(ret + cwd_len + 1, rel_path, rel_len); 341 ret[ret_len - 1] = '\0'; 342 } 343 os_free(buf); 344 return ret; 345 } 346 347 348 int os_program_init(void) 349 { 350 #ifdef ANDROID 351 /* 352 * We ignore errors here since errors are normal if we 353 * are already running as non-root. 354 */ 355 #ifdef ANDROID_SETGROUPS_OVERRIDE 356 gid_t groups[] = { ANDROID_SETGROUPS_OVERRIDE }; 357 #else /* ANDROID_SETGROUPS_OVERRIDE */ 358 gid_t groups[] = { AID_INET, AID_WIFI, AID_KEYSTORE }; 359 #endif /* ANDROID_SETGROUPS_OVERRIDE */ 360 struct __user_cap_header_struct header; 361 struct __user_cap_data_struct cap; 362 363 setgroups(ARRAY_SIZE(groups), groups); 364 365 prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0); 366 367 setgid(AID_WIFI); 368 setuid(AID_WIFI); 369 370 header.version = _LINUX_CAPABILITY_VERSION; 371 header.pid = 0; 372 cap.effective = cap.permitted = 373 (1 << CAP_NET_ADMIN) | (1 << CAP_NET_RAW); 374 cap.inheritable = 0; 375 capset(&header, &cap); 376 #endif /* ANDROID */ 377 378 return 0; 379 } 380 381 382 void os_program_deinit(void) 383 { 384 #ifdef WPA_TRACE 385 struct os_alloc_trace *a; 386 unsigned long total = 0; 387 dl_list_for_each(a, &alloc_list, struct os_alloc_trace, list) { 388 total += a->len; 389 if (a->magic != ALLOC_MAGIC) { 390 wpa_printf(MSG_INFO, "MEMLEAK[%p]: invalid magic 0x%x " 391 "len %lu", 392 a, a->magic, (unsigned long) a->len); 393 continue; 394 } 395 wpa_printf(MSG_INFO, "MEMLEAK[%p]: len %lu", 396 a, (unsigned long) a->len); 397 wpa_trace_dump("memleak", a); 398 } 399 if (total) 400 wpa_printf(MSG_INFO, "MEMLEAK: total %lu bytes", 401 (unsigned long) total); 402 wpa_trace_deinit(); 403 #endif /* WPA_TRACE */ 404 } 405 406 407 int os_setenv(const char *name, const char *value, int overwrite) 408 { 409 return setenv(name, value, overwrite); 410 } 411 412 413 int os_unsetenv(const char *name) 414 { 415 #if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__APPLE__) || \ 416 defined(__OpenBSD__) 417 unsetenv(name); 418 return 0; 419 #else 420 return unsetenv(name); 421 #endif 422 } 423 424 425 char * os_readfile(const char *name, size_t *len) 426 { 427 FILE *f; 428 char *buf; 429 long pos; 430 431 f = fopen(name, "rb"); 432 if (f == NULL) 433 return NULL; 434 435 if (fseek(f, 0, SEEK_END) < 0 || (pos = ftell(f)) < 0) { 436 fclose(f); 437 return NULL; 438 } 439 *len = pos; 440 if (fseek(f, 0, SEEK_SET) < 0) { 441 fclose(f); 442 return NULL; 443 } 444 445 buf = os_malloc(*len); 446 if (buf == NULL) { 447 fclose(f); 448 return NULL; 449 } 450 451 if (fread(buf, 1, *len, f) != *len) { 452 fclose(f); 453 os_free(buf); 454 return NULL; 455 } 456 457 fclose(f); 458 459 return buf; 460 } 461 462 463 int os_file_exists(const char *fname) 464 { 465 return access(fname, F_OK) == 0; 466 } 467 468 469 int os_fdatasync(FILE *stream) 470 { 471 if (!fflush(stream)) { 472 #ifdef __linux__ 473 return fdatasync(fileno(stream)); 474 #else /* !__linux__ */ 475 #ifdef F_FULLFSYNC 476 /* OS X does not implement fdatasync(). */ 477 return fcntl(fileno(stream), F_FULLFSYNC); 478 #else /* F_FULLFSYNC */ 479 return fsync(fileno(stream)); 480 #endif /* F_FULLFSYNC */ 481 #endif /* __linux__ */ 482 } 483 484 return -1; 485 } 486 487 488 #ifndef WPA_TRACE 489 void * os_zalloc(size_t size) 490 { 491 return calloc(1, size); 492 } 493 #endif /* WPA_TRACE */ 494 495 496 size_t os_strlcpy(char *dest, const char *src, size_t siz) 497 { 498 const char *s = src; 499 size_t left = siz; 500 501 if (left) { 502 /* Copy string up to the maximum size of the dest buffer */ 503 while (--left != 0) { 504 if ((*dest++ = *s++) == '\0') 505 break; 506 } 507 } 508 509 if (left == 0) { 510 /* Not enough room for the string; force NUL-termination */ 511 if (siz != 0) 512 *dest = '\0'; 513 while (*s++) 514 ; /* determine total src string length */ 515 } 516 517 return s - src - 1; 518 } 519 520 521 int os_memcmp_const(const void *a, const void *b, size_t len) 522 { 523 const u8 *aa = a; 524 const u8 *bb = b; 525 size_t i; 526 u8 res; 527 528 for (res = 0, i = 0; i < len; i++) 529 res |= aa[i] ^ bb[i]; 530 531 return res; 532 } 533 534 535 #ifdef WPA_TRACE 536 537 #if defined(WPA_TRACE_BFD) && defined(CONFIG_TESTING_OPTIONS) 538 char wpa_trace_fail_func[256] = { 0 }; 539 unsigned int wpa_trace_fail_after; 540 541 static int testing_fail_alloc(void) 542 { 543 const char *func[WPA_TRACE_LEN]; 544 size_t i, res, len; 545 char *pos, *next; 546 int match; 547 548 if (!wpa_trace_fail_after) 549 return 0; 550 551 res = wpa_trace_calling_func(func, WPA_TRACE_LEN); 552 i = 0; 553 if (i < res && os_strcmp(func[i], __func__) == 0) 554 i++; 555 if (i < res && os_strcmp(func[i], "os_malloc") == 0) 556 i++; 557 if (i < res && os_strcmp(func[i], "os_zalloc") == 0) 558 i++; 559 if (i < res && os_strcmp(func[i], "os_calloc") == 0) 560 i++; 561 if (i < res && os_strcmp(func[i], "os_realloc") == 0) 562 i++; 563 if (i < res && os_strcmp(func[i], "os_realloc_array") == 0) 564 i++; 565 if (i < res && os_strcmp(func[i], "os_strdup") == 0) 566 i++; 567 568 pos = wpa_trace_fail_func; 569 570 match = 0; 571 while (i < res) { 572 int allow_skip = 1; 573 int maybe = 0; 574 575 if (*pos == '=') { 576 allow_skip = 0; 577 pos++; 578 } else if (*pos == '?') { 579 maybe = 1; 580 pos++; 581 } 582 next = os_strchr(pos, ';'); 583 if (next) 584 len = next - pos; 585 else 586 len = os_strlen(pos); 587 if (os_memcmp(pos, func[i], len) != 0) { 588 if (maybe && next) { 589 pos = next + 1; 590 continue; 591 } 592 if (allow_skip) { 593 i++; 594 continue; 595 } 596 return 0; 597 } 598 if (!next) { 599 match = 1; 600 break; 601 } 602 pos = next + 1; 603 i++; 604 } 605 if (!match) 606 return 0; 607 608 wpa_trace_fail_after--; 609 if (wpa_trace_fail_after == 0) { 610 wpa_printf(MSG_INFO, "TESTING: fail allocation at %s", 611 wpa_trace_fail_func); 612 for (i = 0; i < res; i++) 613 wpa_printf(MSG_INFO, "backtrace[%d] = %s", 614 (int) i, func[i]); 615 return 1; 616 } 617 618 return 0; 619 } 620 621 622 char wpa_trace_test_fail_func[256] = { 0 }; 623 unsigned int wpa_trace_test_fail_after; 624 625 int testing_test_fail(void) 626 { 627 const char *func[WPA_TRACE_LEN]; 628 size_t i, res, len; 629 char *pos, *next; 630 int match; 631 632 if (!wpa_trace_test_fail_after) 633 return 0; 634 635 res = wpa_trace_calling_func(func, WPA_TRACE_LEN); 636 i = 0; 637 if (i < res && os_strcmp(func[i], __func__) == 0) 638 i++; 639 640 pos = wpa_trace_test_fail_func; 641 642 match = 0; 643 while (i < res) { 644 int allow_skip = 1; 645 int maybe = 0; 646 647 if (*pos == '=') { 648 allow_skip = 0; 649 pos++; 650 } else if (*pos == '?') { 651 maybe = 1; 652 pos++; 653 } 654 next = os_strchr(pos, ';'); 655 if (next) 656 len = next - pos; 657 else 658 len = os_strlen(pos); 659 if (os_memcmp(pos, func[i], len) != 0) { 660 if (maybe && next) { 661 pos = next + 1; 662 continue; 663 } 664 if (allow_skip) { 665 i++; 666 continue; 667 } 668 return 0; 669 } 670 if (!next) { 671 match = 1; 672 break; 673 } 674 pos = next + 1; 675 i++; 676 } 677 if (!match) 678 return 0; 679 680 wpa_trace_test_fail_after--; 681 if (wpa_trace_test_fail_after == 0) { 682 wpa_printf(MSG_INFO, "TESTING: fail at %s", 683 wpa_trace_test_fail_func); 684 for (i = 0; i < res; i++) 685 wpa_printf(MSG_INFO, "backtrace[%d] = %s", 686 (int) i, func[i]); 687 return 1; 688 } 689 690 return 0; 691 } 692 693 #else 694 695 static inline int testing_fail_alloc(void) 696 { 697 return 0; 698 } 699 #endif 700 701 void * os_malloc(size_t size) 702 { 703 struct os_alloc_trace *a; 704 705 if (testing_fail_alloc()) 706 return NULL; 707 708 a = malloc(sizeof(*a) + size); 709 if (a == NULL) 710 return NULL; 711 a->magic = ALLOC_MAGIC; 712 dl_list_add(&alloc_list, &a->list); 713 a->len = size; 714 wpa_trace_record(a); 715 return a + 1; 716 } 717 718 719 void * os_realloc(void *ptr, size_t size) 720 { 721 struct os_alloc_trace *a; 722 size_t copy_len; 723 void *n; 724 725 if (ptr == NULL) 726 return os_malloc(size); 727 728 a = (struct os_alloc_trace *) ptr - 1; 729 if (a->magic != ALLOC_MAGIC) { 730 wpa_printf(MSG_INFO, "REALLOC[%p]: invalid magic 0x%x%s", 731 a, a->magic, 732 a->magic == FREED_MAGIC ? " (already freed)" : ""); 733 wpa_trace_show("Invalid os_realloc() call"); 734 abort(); 735 } 736 n = os_malloc(size); 737 if (n == NULL) 738 return NULL; 739 copy_len = a->len; 740 if (copy_len > size) 741 copy_len = size; 742 os_memcpy(n, a + 1, copy_len); 743 os_free(ptr); 744 return n; 745 } 746 747 748 void os_free(void *ptr) 749 { 750 struct os_alloc_trace *a; 751 752 if (ptr == NULL) 753 return; 754 a = (struct os_alloc_trace *) ptr - 1; 755 if (a->magic != ALLOC_MAGIC) { 756 wpa_printf(MSG_INFO, "FREE[%p]: invalid magic 0x%x%s", 757 a, a->magic, 758 a->magic == FREED_MAGIC ? " (already freed)" : ""); 759 wpa_trace_show("Invalid os_free() call"); 760 abort(); 761 } 762 dl_list_del(&a->list); 763 a->magic = FREED_MAGIC; 764 765 wpa_trace_check_ref(ptr); 766 free(a); 767 } 768 769 770 void * os_zalloc(size_t size) 771 { 772 void *ptr = os_malloc(size); 773 if (ptr) 774 os_memset(ptr, 0, size); 775 return ptr; 776 } 777 778 779 char * os_strdup(const char *s) 780 { 781 size_t len; 782 char *d; 783 len = os_strlen(s); 784 d = os_malloc(len + 1); 785 if (d == NULL) 786 return NULL; 787 os_memcpy(d, s, len); 788 d[len] = '\0'; 789 return d; 790 } 791 792 #endif /* WPA_TRACE */ 793 794 795 int os_exec(const char *program, const char *arg, int wait_completion) 796 { 797 pid_t pid; 798 int pid_status; 799 800 pid = fork(); 801 if (pid < 0) { 802 perror("fork"); 803 return -1; 804 } 805 806 if (pid == 0) { 807 /* run the external command in the child process */ 808 const int MAX_ARG = 30; 809 char *_program, *_arg, *pos; 810 char *argv[MAX_ARG + 1]; 811 int i; 812 813 _program = os_strdup(program); 814 _arg = os_strdup(arg); 815 816 argv[0] = _program; 817 818 i = 1; 819 pos = _arg; 820 while (i < MAX_ARG && pos && *pos) { 821 while (*pos == ' ') 822 pos++; 823 if (*pos == '\0') 824 break; 825 argv[i++] = pos; 826 pos = os_strchr(pos, ' '); 827 if (pos) 828 *pos++ = '\0'; 829 } 830 argv[i] = NULL; 831 832 execv(program, argv); 833 perror("execv"); 834 os_free(_program); 835 os_free(_arg); 836 exit(0); 837 return -1; 838 } 839 840 if (wait_completion) { 841 /* wait for the child process to complete in the parent */ 842 waitpid(pid, &pid_status, 0); 843 } 844 845 return 0; 846 } 847