139beb93cSSam Leffler /* 2e28a4053SRui Paulo * OS specific functions for UNIX/POSIX systems 3e28a4053SRui Paulo * Copyright (c) 2005-2009, Jouni Malinen <j@w1.fi> 439beb93cSSam Leffler * 5*f05cddf9SRui Paulo * This software may be distributed under the terms of the BSD license. 6*f05cddf9SRui Paulo * See README for more details. 739beb93cSSam Leffler */ 839beb93cSSam Leffler 939beb93cSSam Leffler #include "includes.h" 1039beb93cSSam Leffler 11*f05cddf9SRui Paulo #include <time.h> 12*f05cddf9SRui Paulo 13*f05cddf9SRui Paulo #ifdef ANDROID 14*f05cddf9SRui Paulo #include <linux/capability.h> 15*f05cddf9SRui Paulo #include <linux/prctl.h> 16*f05cddf9SRui Paulo #include <private/android_filesystem_config.h> 17*f05cddf9SRui Paulo #endif /* ANDROID */ 18*f05cddf9SRui Paulo 1939beb93cSSam Leffler #include "os.h" 2039beb93cSSam Leffler 21e28a4053SRui Paulo #ifdef WPA_TRACE 22e28a4053SRui Paulo 23e28a4053SRui Paulo #include "common.h" 24e28a4053SRui Paulo #include "wpa_debug.h" 25e28a4053SRui Paulo #include "trace.h" 26*f05cddf9SRui Paulo #include "list.h" 27e28a4053SRui Paulo 28e28a4053SRui Paulo static struct dl_list alloc_list; 29e28a4053SRui Paulo 30e28a4053SRui Paulo #define ALLOC_MAGIC 0xa84ef1b2 31e28a4053SRui Paulo #define FREED_MAGIC 0x67fd487a 32e28a4053SRui Paulo 33e28a4053SRui Paulo struct os_alloc_trace { 34e28a4053SRui Paulo unsigned int magic; 35e28a4053SRui Paulo struct dl_list list; 36e28a4053SRui Paulo size_t len; 37e28a4053SRui Paulo WPA_TRACE_INFO 38e28a4053SRui Paulo }; 39e28a4053SRui Paulo 40e28a4053SRui Paulo #endif /* WPA_TRACE */ 41e28a4053SRui Paulo 42e28a4053SRui Paulo 4339beb93cSSam Leffler void os_sleep(os_time_t sec, os_time_t usec) 4439beb93cSSam Leffler { 4539beb93cSSam Leffler if (sec) 4639beb93cSSam Leffler sleep(sec); 4739beb93cSSam Leffler if (usec) 4839beb93cSSam Leffler usleep(usec); 4939beb93cSSam Leffler } 5039beb93cSSam Leffler 5139beb93cSSam Leffler 5239beb93cSSam Leffler int os_get_time(struct os_time *t) 5339beb93cSSam Leffler { 5439beb93cSSam Leffler int res; 5539beb93cSSam Leffler struct timeval tv; 5639beb93cSSam Leffler res = gettimeofday(&tv, NULL); 5739beb93cSSam Leffler t->sec = tv.tv_sec; 5839beb93cSSam Leffler t->usec = tv.tv_usec; 5939beb93cSSam Leffler return res; 6039beb93cSSam Leffler } 6139beb93cSSam Leffler 6239beb93cSSam Leffler 6339beb93cSSam Leffler int os_mktime(int year, int month, int day, int hour, int min, int sec, 6439beb93cSSam Leffler os_time_t *t) 6539beb93cSSam Leffler { 6639beb93cSSam Leffler struct tm tm, *tm1; 6739beb93cSSam Leffler time_t t_local, t1, t2; 6839beb93cSSam Leffler os_time_t tz_offset; 6939beb93cSSam Leffler 7039beb93cSSam Leffler if (year < 1970 || month < 1 || month > 12 || day < 1 || day > 31 || 7139beb93cSSam Leffler hour < 0 || hour > 23 || min < 0 || min > 59 || sec < 0 || 7239beb93cSSam Leffler sec > 60) 7339beb93cSSam Leffler return -1; 7439beb93cSSam Leffler 7539beb93cSSam Leffler memset(&tm, 0, sizeof(tm)); 7639beb93cSSam Leffler tm.tm_year = year - 1900; 7739beb93cSSam Leffler tm.tm_mon = month - 1; 7839beb93cSSam Leffler tm.tm_mday = day; 7939beb93cSSam Leffler tm.tm_hour = hour; 8039beb93cSSam Leffler tm.tm_min = min; 8139beb93cSSam Leffler tm.tm_sec = sec; 8239beb93cSSam Leffler 8339beb93cSSam Leffler t_local = mktime(&tm); 8439beb93cSSam Leffler 8539beb93cSSam Leffler /* figure out offset to UTC */ 8639beb93cSSam Leffler tm1 = localtime(&t_local); 8739beb93cSSam Leffler if (tm1) { 8839beb93cSSam Leffler t1 = mktime(tm1); 8939beb93cSSam Leffler tm1 = gmtime(&t_local); 9039beb93cSSam Leffler if (tm1) { 9139beb93cSSam Leffler t2 = mktime(tm1); 9239beb93cSSam Leffler tz_offset = t2 - t1; 9339beb93cSSam Leffler } else 9439beb93cSSam Leffler tz_offset = 0; 9539beb93cSSam Leffler } else 9639beb93cSSam Leffler tz_offset = 0; 9739beb93cSSam Leffler 9839beb93cSSam Leffler *t = (os_time_t) t_local - tz_offset; 9939beb93cSSam Leffler return 0; 10039beb93cSSam Leffler } 10139beb93cSSam Leffler 10239beb93cSSam Leffler 103*f05cddf9SRui Paulo int os_gmtime(os_time_t t, struct os_tm *tm) 104*f05cddf9SRui Paulo { 105*f05cddf9SRui Paulo struct tm *tm2; 106*f05cddf9SRui Paulo time_t t2 = t; 107*f05cddf9SRui Paulo 108*f05cddf9SRui Paulo tm2 = gmtime(&t2); 109*f05cddf9SRui Paulo if (tm2 == NULL) 110*f05cddf9SRui Paulo return -1; 111*f05cddf9SRui Paulo tm->sec = tm2->tm_sec; 112*f05cddf9SRui Paulo tm->min = tm2->tm_min; 113*f05cddf9SRui Paulo tm->hour = tm2->tm_hour; 114*f05cddf9SRui Paulo tm->day = tm2->tm_mday; 115*f05cddf9SRui Paulo tm->month = tm2->tm_mon + 1; 116*f05cddf9SRui Paulo tm->year = tm2->tm_year + 1900; 117*f05cddf9SRui Paulo return 0; 118*f05cddf9SRui Paulo } 119*f05cddf9SRui Paulo 120*f05cddf9SRui Paulo 12139beb93cSSam Leffler #ifdef __APPLE__ 12239beb93cSSam Leffler #include <fcntl.h> 12339beb93cSSam Leffler static int os_daemon(int nochdir, int noclose) 12439beb93cSSam Leffler { 12539beb93cSSam Leffler int devnull; 12639beb93cSSam Leffler 12739beb93cSSam Leffler if (chdir("/") < 0) 12839beb93cSSam Leffler return -1; 12939beb93cSSam Leffler 13039beb93cSSam Leffler devnull = open("/dev/null", O_RDWR); 13139beb93cSSam Leffler if (devnull < 0) 13239beb93cSSam Leffler return -1; 13339beb93cSSam Leffler 13439beb93cSSam Leffler if (dup2(devnull, STDIN_FILENO) < 0) { 13539beb93cSSam Leffler close(devnull); 13639beb93cSSam Leffler return -1; 13739beb93cSSam Leffler } 13839beb93cSSam Leffler 13939beb93cSSam Leffler if (dup2(devnull, STDOUT_FILENO) < 0) { 14039beb93cSSam Leffler close(devnull); 14139beb93cSSam Leffler return -1; 14239beb93cSSam Leffler } 14339beb93cSSam Leffler 14439beb93cSSam Leffler if (dup2(devnull, STDERR_FILENO) < 0) { 14539beb93cSSam Leffler close(devnull); 14639beb93cSSam Leffler return -1; 14739beb93cSSam Leffler } 14839beb93cSSam Leffler 14939beb93cSSam Leffler return 0; 15039beb93cSSam Leffler } 15139beb93cSSam Leffler #else /* __APPLE__ */ 15239beb93cSSam Leffler #define os_daemon daemon 15339beb93cSSam Leffler #endif /* __APPLE__ */ 15439beb93cSSam Leffler 15539beb93cSSam Leffler 15639beb93cSSam Leffler int os_daemonize(const char *pid_file) 15739beb93cSSam Leffler { 158*f05cddf9SRui Paulo #if defined(__uClinux__) || defined(__sun__) 15939beb93cSSam Leffler return -1; 160*f05cddf9SRui Paulo #else /* defined(__uClinux__) || defined(__sun__) */ 16139beb93cSSam Leffler if (os_daemon(0, 0)) { 16239beb93cSSam Leffler perror("daemon"); 16339beb93cSSam Leffler return -1; 16439beb93cSSam Leffler } 16539beb93cSSam Leffler 16639beb93cSSam Leffler if (pid_file) { 16739beb93cSSam Leffler FILE *f = fopen(pid_file, "w"); 16839beb93cSSam Leffler if (f) { 16939beb93cSSam Leffler fprintf(f, "%u\n", getpid()); 17039beb93cSSam Leffler fclose(f); 17139beb93cSSam Leffler } 17239beb93cSSam Leffler } 17339beb93cSSam Leffler 17439beb93cSSam Leffler return -0; 175*f05cddf9SRui Paulo #endif /* defined(__uClinux__) || defined(__sun__) */ 17639beb93cSSam Leffler } 17739beb93cSSam Leffler 17839beb93cSSam Leffler 17939beb93cSSam Leffler void os_daemonize_terminate(const char *pid_file) 18039beb93cSSam Leffler { 18139beb93cSSam Leffler if (pid_file) 18239beb93cSSam Leffler unlink(pid_file); 18339beb93cSSam Leffler } 18439beb93cSSam Leffler 18539beb93cSSam Leffler 18639beb93cSSam Leffler int os_get_random(unsigned char *buf, size_t len) 18739beb93cSSam Leffler { 18839beb93cSSam Leffler FILE *f; 18939beb93cSSam Leffler size_t rc; 19039beb93cSSam Leffler 19139beb93cSSam Leffler f = fopen("/dev/urandom", "rb"); 19239beb93cSSam Leffler if (f == NULL) { 19339beb93cSSam Leffler printf("Could not open /dev/urandom.\n"); 19439beb93cSSam Leffler return -1; 19539beb93cSSam Leffler } 19639beb93cSSam Leffler 19739beb93cSSam Leffler rc = fread(buf, 1, len, f); 19839beb93cSSam Leffler fclose(f); 19939beb93cSSam Leffler 20039beb93cSSam Leffler return rc != len ? -1 : 0; 20139beb93cSSam Leffler } 20239beb93cSSam Leffler 20339beb93cSSam Leffler 20439beb93cSSam Leffler unsigned long os_random(void) 20539beb93cSSam Leffler { 20639beb93cSSam Leffler return random(); 20739beb93cSSam Leffler } 20839beb93cSSam Leffler 20939beb93cSSam Leffler 21039beb93cSSam Leffler char * os_rel2abs_path(const char *rel_path) 21139beb93cSSam Leffler { 21239beb93cSSam Leffler char *buf = NULL, *cwd, *ret; 21339beb93cSSam Leffler size_t len = 128, cwd_len, rel_len, ret_len; 21439beb93cSSam Leffler int last_errno; 21539beb93cSSam Leffler 21639beb93cSSam Leffler if (rel_path[0] == '/') 217e28a4053SRui Paulo return os_strdup(rel_path); 21839beb93cSSam Leffler 21939beb93cSSam Leffler for (;;) { 220e28a4053SRui Paulo buf = os_malloc(len); 22139beb93cSSam Leffler if (buf == NULL) 22239beb93cSSam Leffler return NULL; 22339beb93cSSam Leffler cwd = getcwd(buf, len); 22439beb93cSSam Leffler if (cwd == NULL) { 22539beb93cSSam Leffler last_errno = errno; 226e28a4053SRui Paulo os_free(buf); 22739beb93cSSam Leffler if (last_errno != ERANGE) 22839beb93cSSam Leffler return NULL; 22939beb93cSSam Leffler len *= 2; 23039beb93cSSam Leffler if (len > 2000) 23139beb93cSSam Leffler return NULL; 23239beb93cSSam Leffler } else { 23339beb93cSSam Leffler buf[len - 1] = '\0'; 23439beb93cSSam Leffler break; 23539beb93cSSam Leffler } 23639beb93cSSam Leffler } 23739beb93cSSam Leffler 238e28a4053SRui Paulo cwd_len = os_strlen(cwd); 239e28a4053SRui Paulo rel_len = os_strlen(rel_path); 24039beb93cSSam Leffler ret_len = cwd_len + 1 + rel_len + 1; 241e28a4053SRui Paulo ret = os_malloc(ret_len); 24239beb93cSSam Leffler if (ret) { 243e28a4053SRui Paulo os_memcpy(ret, cwd, cwd_len); 24439beb93cSSam Leffler ret[cwd_len] = '/'; 245e28a4053SRui Paulo os_memcpy(ret + cwd_len + 1, rel_path, rel_len); 24639beb93cSSam Leffler ret[ret_len - 1] = '\0'; 24739beb93cSSam Leffler } 248e28a4053SRui Paulo os_free(buf); 24939beb93cSSam Leffler return ret; 25039beb93cSSam Leffler } 25139beb93cSSam Leffler 25239beb93cSSam Leffler 25339beb93cSSam Leffler int os_program_init(void) 25439beb93cSSam Leffler { 255*f05cddf9SRui Paulo #ifdef ANDROID 256*f05cddf9SRui Paulo /* 257*f05cddf9SRui Paulo * We ignore errors here since errors are normal if we 258*f05cddf9SRui Paulo * are already running as non-root. 259*f05cddf9SRui Paulo */ 260*f05cddf9SRui Paulo gid_t groups[] = { AID_INET, AID_WIFI, AID_KEYSTORE }; 261*f05cddf9SRui Paulo struct __user_cap_header_struct header; 262*f05cddf9SRui Paulo struct __user_cap_data_struct cap; 263*f05cddf9SRui Paulo 264*f05cddf9SRui Paulo setgroups(sizeof(groups)/sizeof(groups[0]), groups); 265*f05cddf9SRui Paulo 266*f05cddf9SRui Paulo prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0); 267*f05cddf9SRui Paulo 268*f05cddf9SRui Paulo setgid(AID_WIFI); 269*f05cddf9SRui Paulo setuid(AID_WIFI); 270*f05cddf9SRui Paulo 271*f05cddf9SRui Paulo header.version = _LINUX_CAPABILITY_VERSION; 272*f05cddf9SRui Paulo header.pid = 0; 273*f05cddf9SRui Paulo cap.effective = cap.permitted = 274*f05cddf9SRui Paulo (1 << CAP_NET_ADMIN) | (1 << CAP_NET_RAW); 275*f05cddf9SRui Paulo cap.inheritable = 0; 276*f05cddf9SRui Paulo capset(&header, &cap); 277*f05cddf9SRui Paulo #endif /* ANDROID */ 278*f05cddf9SRui Paulo 279e28a4053SRui Paulo #ifdef WPA_TRACE 280e28a4053SRui Paulo dl_list_init(&alloc_list); 281e28a4053SRui Paulo #endif /* WPA_TRACE */ 28239beb93cSSam Leffler return 0; 28339beb93cSSam Leffler } 28439beb93cSSam Leffler 28539beb93cSSam Leffler 28639beb93cSSam Leffler void os_program_deinit(void) 28739beb93cSSam Leffler { 288e28a4053SRui Paulo #ifdef WPA_TRACE 289e28a4053SRui Paulo struct os_alloc_trace *a; 290e28a4053SRui Paulo unsigned long total = 0; 291e28a4053SRui Paulo dl_list_for_each(a, &alloc_list, struct os_alloc_trace, list) { 292e28a4053SRui Paulo total += a->len; 293e28a4053SRui Paulo if (a->magic != ALLOC_MAGIC) { 294e28a4053SRui Paulo wpa_printf(MSG_INFO, "MEMLEAK[%p]: invalid magic 0x%x " 295e28a4053SRui Paulo "len %lu", 296e28a4053SRui Paulo a, a->magic, (unsigned long) a->len); 297e28a4053SRui Paulo continue; 298e28a4053SRui Paulo } 299e28a4053SRui Paulo wpa_printf(MSG_INFO, "MEMLEAK[%p]: len %lu", 300e28a4053SRui Paulo a, (unsigned long) a->len); 301e28a4053SRui Paulo wpa_trace_dump("memleak", a); 302e28a4053SRui Paulo } 303e28a4053SRui Paulo if (total) 304e28a4053SRui Paulo wpa_printf(MSG_INFO, "MEMLEAK: total %lu bytes", 305e28a4053SRui Paulo (unsigned long) total); 306e28a4053SRui Paulo #endif /* WPA_TRACE */ 30739beb93cSSam Leffler } 30839beb93cSSam Leffler 30939beb93cSSam Leffler 31039beb93cSSam Leffler int os_setenv(const char *name, const char *value, int overwrite) 31139beb93cSSam Leffler { 31239beb93cSSam Leffler return setenv(name, value, overwrite); 31339beb93cSSam Leffler } 31439beb93cSSam Leffler 31539beb93cSSam Leffler 31639beb93cSSam Leffler int os_unsetenv(const char *name) 31739beb93cSSam Leffler { 3183157ba21SRui Paulo #if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__APPLE__) || \ 3193157ba21SRui Paulo defined(__OpenBSD__) 32039beb93cSSam Leffler unsetenv(name); 32139beb93cSSam Leffler return 0; 32239beb93cSSam Leffler #else 32339beb93cSSam Leffler return unsetenv(name); 32439beb93cSSam Leffler #endif 32539beb93cSSam Leffler } 32639beb93cSSam Leffler 32739beb93cSSam Leffler 32839beb93cSSam Leffler char * os_readfile(const char *name, size_t *len) 32939beb93cSSam Leffler { 33039beb93cSSam Leffler FILE *f; 33139beb93cSSam Leffler char *buf; 332*f05cddf9SRui Paulo long pos; 33339beb93cSSam Leffler 33439beb93cSSam Leffler f = fopen(name, "rb"); 33539beb93cSSam Leffler if (f == NULL) 33639beb93cSSam Leffler return NULL; 33739beb93cSSam Leffler 338*f05cddf9SRui Paulo if (fseek(f, 0, SEEK_END) < 0 || (pos = ftell(f)) < 0) { 339*f05cddf9SRui Paulo fclose(f); 340*f05cddf9SRui Paulo return NULL; 341*f05cddf9SRui Paulo } 342*f05cddf9SRui Paulo *len = pos; 343*f05cddf9SRui Paulo if (fseek(f, 0, SEEK_SET) < 0) { 344*f05cddf9SRui Paulo fclose(f); 345*f05cddf9SRui Paulo return NULL; 346*f05cddf9SRui Paulo } 34739beb93cSSam Leffler 348e28a4053SRui Paulo buf = os_malloc(*len); 34939beb93cSSam Leffler if (buf == NULL) { 35039beb93cSSam Leffler fclose(f); 35139beb93cSSam Leffler return NULL; 35239beb93cSSam Leffler } 35339beb93cSSam Leffler 35439beb93cSSam Leffler if (fread(buf, 1, *len, f) != *len) { 35539beb93cSSam Leffler fclose(f); 356e28a4053SRui Paulo os_free(buf); 35739beb93cSSam Leffler return NULL; 35839beb93cSSam Leffler } 35939beb93cSSam Leffler 36039beb93cSSam Leffler fclose(f); 36139beb93cSSam Leffler 36239beb93cSSam Leffler return buf; 36339beb93cSSam Leffler } 36439beb93cSSam Leffler 36539beb93cSSam Leffler 366e28a4053SRui Paulo #ifndef WPA_TRACE 36739beb93cSSam Leffler void * os_zalloc(size_t size) 36839beb93cSSam Leffler { 36939beb93cSSam Leffler return calloc(1, size); 37039beb93cSSam Leffler } 371e28a4053SRui Paulo #endif /* WPA_TRACE */ 37239beb93cSSam Leffler 37339beb93cSSam Leffler 37439beb93cSSam Leffler size_t os_strlcpy(char *dest, const char *src, size_t siz) 37539beb93cSSam Leffler { 37639beb93cSSam Leffler const char *s = src; 37739beb93cSSam Leffler size_t left = siz; 37839beb93cSSam Leffler 37939beb93cSSam Leffler if (left) { 38039beb93cSSam Leffler /* Copy string up to the maximum size of the dest buffer */ 38139beb93cSSam Leffler while (--left != 0) { 38239beb93cSSam Leffler if ((*dest++ = *s++) == '\0') 38339beb93cSSam Leffler break; 38439beb93cSSam Leffler } 38539beb93cSSam Leffler } 38639beb93cSSam Leffler 38739beb93cSSam Leffler if (left == 0) { 38839beb93cSSam Leffler /* Not enough room for the string; force NUL-termination */ 38939beb93cSSam Leffler if (siz != 0) 39039beb93cSSam Leffler *dest = '\0'; 39139beb93cSSam Leffler while (*s++) 39239beb93cSSam Leffler ; /* determine total src string length */ 39339beb93cSSam Leffler } 39439beb93cSSam Leffler 39539beb93cSSam Leffler return s - src - 1; 39639beb93cSSam Leffler } 397e28a4053SRui Paulo 398e28a4053SRui Paulo 399e28a4053SRui Paulo #ifdef WPA_TRACE 400e28a4053SRui Paulo 401e28a4053SRui Paulo void * os_malloc(size_t size) 402e28a4053SRui Paulo { 403e28a4053SRui Paulo struct os_alloc_trace *a; 404e28a4053SRui Paulo a = malloc(sizeof(*a) + size); 405e28a4053SRui Paulo if (a == NULL) 406e28a4053SRui Paulo return NULL; 407e28a4053SRui Paulo a->magic = ALLOC_MAGIC; 408e28a4053SRui Paulo dl_list_add(&alloc_list, &a->list); 409e28a4053SRui Paulo a->len = size; 410e28a4053SRui Paulo wpa_trace_record(a); 411e28a4053SRui Paulo return a + 1; 412e28a4053SRui Paulo } 413e28a4053SRui Paulo 414e28a4053SRui Paulo 415e28a4053SRui Paulo void * os_realloc(void *ptr, size_t size) 416e28a4053SRui Paulo { 417e28a4053SRui Paulo struct os_alloc_trace *a; 418e28a4053SRui Paulo size_t copy_len; 419e28a4053SRui Paulo void *n; 420e28a4053SRui Paulo 421e28a4053SRui Paulo if (ptr == NULL) 422e28a4053SRui Paulo return os_malloc(size); 423e28a4053SRui Paulo 424e28a4053SRui Paulo a = (struct os_alloc_trace *) ptr - 1; 425e28a4053SRui Paulo if (a->magic != ALLOC_MAGIC) { 426e28a4053SRui Paulo wpa_printf(MSG_INFO, "REALLOC[%p]: invalid magic 0x%x%s", 427e28a4053SRui Paulo a, a->magic, 428e28a4053SRui Paulo a->magic == FREED_MAGIC ? " (already freed)" : ""); 429e28a4053SRui Paulo wpa_trace_show("Invalid os_realloc() call"); 430e28a4053SRui Paulo abort(); 431e28a4053SRui Paulo } 432e28a4053SRui Paulo n = os_malloc(size); 433e28a4053SRui Paulo if (n == NULL) 434e28a4053SRui Paulo return NULL; 435e28a4053SRui Paulo copy_len = a->len; 436e28a4053SRui Paulo if (copy_len > size) 437e28a4053SRui Paulo copy_len = size; 438e28a4053SRui Paulo os_memcpy(n, a + 1, copy_len); 439e28a4053SRui Paulo os_free(ptr); 440e28a4053SRui Paulo return n; 441e28a4053SRui Paulo } 442e28a4053SRui Paulo 443e28a4053SRui Paulo 444e28a4053SRui Paulo void os_free(void *ptr) 445e28a4053SRui Paulo { 446e28a4053SRui Paulo struct os_alloc_trace *a; 447e28a4053SRui Paulo 448e28a4053SRui Paulo if (ptr == NULL) 449e28a4053SRui Paulo return; 450e28a4053SRui Paulo a = (struct os_alloc_trace *) ptr - 1; 451e28a4053SRui Paulo if (a->magic != ALLOC_MAGIC) { 452e28a4053SRui Paulo wpa_printf(MSG_INFO, "FREE[%p]: invalid magic 0x%x%s", 453e28a4053SRui Paulo a, a->magic, 454e28a4053SRui Paulo a->magic == FREED_MAGIC ? " (already freed)" : ""); 455e28a4053SRui Paulo wpa_trace_show("Invalid os_free() call"); 456e28a4053SRui Paulo abort(); 457e28a4053SRui Paulo } 458e28a4053SRui Paulo dl_list_del(&a->list); 459e28a4053SRui Paulo a->magic = FREED_MAGIC; 460e28a4053SRui Paulo 461e28a4053SRui Paulo wpa_trace_check_ref(ptr); 462e28a4053SRui Paulo free(a); 463e28a4053SRui Paulo } 464e28a4053SRui Paulo 465e28a4053SRui Paulo 466e28a4053SRui Paulo void * os_zalloc(size_t size) 467e28a4053SRui Paulo { 468e28a4053SRui Paulo void *ptr = os_malloc(size); 469e28a4053SRui Paulo if (ptr) 470e28a4053SRui Paulo os_memset(ptr, 0, size); 471e28a4053SRui Paulo return ptr; 472e28a4053SRui Paulo } 473e28a4053SRui Paulo 474e28a4053SRui Paulo 475e28a4053SRui Paulo char * os_strdup(const char *s) 476e28a4053SRui Paulo { 477e28a4053SRui Paulo size_t len; 478e28a4053SRui Paulo char *d; 479e28a4053SRui Paulo len = os_strlen(s); 480e28a4053SRui Paulo d = os_malloc(len + 1); 481e28a4053SRui Paulo if (d == NULL) 482e28a4053SRui Paulo return NULL; 483e28a4053SRui Paulo os_memcpy(d, s, len); 484e28a4053SRui Paulo d[len] = '\0'; 485e28a4053SRui Paulo return d; 486e28a4053SRui Paulo } 487e28a4053SRui Paulo 488e28a4053SRui Paulo #endif /* WPA_TRACE */ 489