1 /*
2 *
3 * honggfuzz - utilities
4 * -----------------------------------------
5 *
6 * Author: Robert Swiecki <swiecki@google.com>
7 *
8 * Copyright 2010-2018 by Google Inc. All Rights Reserved.
9 *
10 * Licensed under the Apache License, Version 2.0 (the "License"); you may
11 * not use this file except in compliance with the License. You may obtain
12 * a copy of the License at
13 *
14 * http://www.apache.org/licenses/LICENSE-2.0
15 *
16 * Unless required by applicable law or agreed to in writing, software
17 * distributed under the License is distributed on an "AS IS" BASIS,
18 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
19 * implied. See the License for the specific language governing
20 * permissions and limitations under the License.
21 *
22 */
23
24 #include "libhfcommon/util.h"
25
26 #include <ctype.h>
27 #include <errno.h>
28 #include <fcntl.h>
29 #include <inttypes.h>
30 #include <math.h>
31 #include <pthread.h>
32 #include <stdarg.h>
33 #include <stdint.h>
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <string.h>
37 #include <sys/mman.h>
38 #include <sys/stat.h>
39 #include <sys/time.h>
40 #include <sys/types.h>
41 #include <time.h>
42 #include <unistd.h>
43
44 #include "libhfcommon/common.h"
45 #include "libhfcommon/files.h"
46 #include "libhfcommon/log.h"
47
util_Malloc(size_t sz)48 void* util_Malloc(size_t sz) {
49 void* p = malloc(sz);
50 if (p == NULL) {
51 LOG_F("malloc(size='%zu')", sz);
52 }
53 return p;
54 }
55
util_Calloc(size_t sz)56 void* util_Calloc(size_t sz) {
57 void* p = util_Malloc(sz);
58 memset(p, '\0', sz);
59 return p;
60 }
61
util_Realloc(void * ptr,size_t sz)62 extern void* util_Realloc(void* ptr, size_t sz) {
63 void* ret = realloc(ptr, sz);
64 if (ret == NULL) {
65 PLOG_W("realloc(%p, %zu)", ptr, sz);
66 free(ptr);
67 return NULL;
68 }
69 return ret;
70 }
71
util_MMap(size_t sz)72 void* util_MMap(size_t sz) {
73 void* p = mmap(NULL, sz, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0);
74 if (p == MAP_FAILED) {
75 LOG_F("mmap(size='%zu')", sz);
76 }
77 return p;
78 }
79
util_StrDup(const char * s)80 char* util_StrDup(const char* s) {
81 char* ret = strdup(s);
82 if (ret == NULL) {
83 LOG_F("strdup(size=%zu)", strlen(s));
84 }
85 return ret;
86 }
87
88 static __thread pthread_once_t rndThreadOnce = PTHREAD_ONCE_INIT;
89 static __thread uint64_t rndState[2];
90
util_rndInitThread(void)91 static void util_rndInitThread(void) {
92 int fd = open("/dev/urandom", O_RDONLY | O_CLOEXEC);
93 if (fd == -1) {
94 PLOG_F("Couldn't open /dev/urandom for reading");
95 }
96 if (files_readFromFd(fd, (uint8_t*)rndState, sizeof(rndState)) != sizeof(rndState)) {
97 PLOG_F("Couldn't read '%zu' bytes from /dev/urandom", sizeof(rndState));
98 }
99 close(fd);
100 }
101
102 /*
103 * xoroshiro128plus by David Blackman and Sebastiano Vigna
104 */
util_RotL(const uint64_t x,int k)105 static inline uint64_t util_RotL(const uint64_t x, int k) {
106 return (x << k) | (x >> (64 - k));
107 }
108
util_InternalRnd64(void)109 static inline uint64_t util_InternalRnd64(void) {
110 const uint64_t s0 = rndState[0];
111 uint64_t s1 = rndState[1];
112 const uint64_t result = s0 + s1;
113 s1 ^= s0;
114 rndState[0] = util_RotL(s0, 55) ^ s1 ^ (s1 << 14);
115 rndState[1] = util_RotL(s1, 36);
116
117 return result;
118 }
119
util_rnd64(void)120 uint64_t util_rnd64(void) {
121 pthread_once(&rndThreadOnce, util_rndInitThread);
122 return util_InternalRnd64();
123 }
124
util_rndGet(uint64_t min,uint64_t max)125 uint64_t util_rndGet(uint64_t min, uint64_t max) {
126 if (min > max) {
127 LOG_F("min:%" PRIu64 " > max:%" PRIu64, min, max);
128 }
129
130 if (max == UINT64_MAX) {
131 return util_rnd64();
132 }
133
134 return ((util_rnd64() % (max - min + 1)) + min);
135 }
136
137 /* Generate random printable ASCII */
util_rndPrintable(void)138 uint8_t util_rndPrintable(void) {
139 return util_rndGet(32, 126);
140 }
141
142 /* Turn one byte to a printable ASCII */
util_turnToPrintable(uint8_t * buf,size_t sz)143 void util_turnToPrintable(uint8_t* buf, size_t sz) {
144 for (size_t i = 0; i < sz; i++) {
145 buf[i] = buf[i] % 95 + 32;
146 }
147 }
148
util_rndBufPrintable(uint8_t * buf,size_t sz)149 void util_rndBufPrintable(uint8_t* buf, size_t sz) {
150 for (size_t i = 0; i < sz; i++) {
151 buf[i] = util_rndPrintable();
152 }
153 }
154
util_rndBuf(uint8_t * buf,size_t sz)155 void util_rndBuf(uint8_t* buf, size_t sz) {
156 pthread_once(&rndThreadOnce, util_rndInitThread);
157 if (sz == 0) {
158 return;
159 }
160 for (size_t i = 0; i < sz; i++) {
161 buf[i] = (uint8_t)util_InternalRnd64();
162 }
163 }
164
util_vssnprintf(char * str,size_t size,const char * format,va_list ap)165 int util_vssnprintf(char* str, size_t size, const char* format, va_list ap) {
166 size_t len = strlen(str);
167 if (len >= size) {
168 return len;
169 }
170
171 size_t left = size - len;
172 return vsnprintf(&str[len], left, format, ap);
173 }
174
util_ssnprintf(char * str,size_t size,const char * format,...)175 int util_ssnprintf(char* str, size_t size, const char* format, ...) {
176 va_list args;
177 va_start(args, format);
178 int ret = util_vssnprintf(str, size, format, args);
179 va_end(args);
180
181 return ret;
182 }
183
util_strStartsWith(const char * str,const char * tofind)184 bool util_strStartsWith(const char* str, const char* tofind) {
185 if (strncmp(str, tofind, strlen(tofind)) == 0) {
186 return true;
187 }
188 return false;
189 }
190
util_getLocalTime(const char * fmt,char * buf,size_t len,time_t tm)191 void util_getLocalTime(const char* fmt, char* buf, size_t len, time_t tm) {
192 struct tm ltime;
193 localtime_r(&tm, <ime);
194 if (strftime(buf, len, fmt, <ime) < 1) {
195 snprintf(buf, len, "[date fetch error]");
196 }
197 }
198
util_closeStdio(bool close_stdin,bool close_stdout,bool close_stderr)199 void util_closeStdio(bool close_stdin, bool close_stdout, bool close_stderr) {
200 int fd = open("/dev/null", O_RDWR);
201
202 if (fd == -1) {
203 PLOG_E("Couldn't open '/dev/null'");
204 return;
205 }
206
207 if (close_stdin) {
208 TEMP_FAILURE_RETRY(dup2(fd, STDIN_FILENO));
209 }
210 if (close_stdout) {
211 TEMP_FAILURE_RETRY(dup2(fd, STDOUT_FILENO));
212 }
213 if (close_stderr) {
214 TEMP_FAILURE_RETRY(dup2(fd, STDERR_FILENO));
215 }
216
217 if (fd > STDERR_FILENO) {
218 close(fd);
219 }
220 }
221
222 /*
223 * This is not a cryptographically secure hash
224 */
util_hash(const char * buf,size_t len)225 uint64_t util_hash(const char* buf, size_t len) {
226 uint64_t ret = 0;
227
228 for (size_t i = 0; i < len; i++) {
229 ret += buf[i];
230 ret += (ret << 10);
231 ret ^= (ret >> 6);
232 }
233
234 return ret;
235 }
236
util_timeNowMillis(void)237 int64_t util_timeNowMillis(void) {
238 struct timeval tv;
239 if (gettimeofday(&tv, NULL) == -1) {
240 PLOG_F("gettimeofday()");
241 }
242
243 return (((int64_t)tv.tv_sec * 1000LL) + ((int64_t)tv.tv_usec / 1000LL));
244 }
245
util_sleepForMSec(uint64_t msec)246 void util_sleepForMSec(uint64_t msec) {
247 if (msec == 0) {
248 return;
249 }
250 struct timespec ts = {
251 .tv_sec = msec / 1000U,
252 .tv_nsec = (msec % 1000U) * 1000000U,
253 };
254 TEMP_FAILURE_RETRY(nanosleep(&ts, &ts));
255 }
256
util_getUINT32(const uint8_t * buf)257 uint64_t util_getUINT32(const uint8_t* buf) {
258 uint32_t r;
259 memcpy(&r, buf, sizeof(r));
260 return (uint64_t)r;
261 }
262
util_getUINT64(const uint8_t * buf)263 uint64_t util_getUINT64(const uint8_t* buf) {
264 uint64_t r;
265 memcpy(&r, buf, sizeof(r));
266 return r;
267 }
268
util_mutexLock(pthread_mutex_t * mutex,const char * func,int line)269 void util_mutexLock(pthread_mutex_t* mutex, const char* func, int line) {
270 if (pthread_mutex_lock(mutex)) {
271 PLOG_F("%s():%d pthread_mutex_lock(%p)", func, line, (void*)mutex);
272 }
273 }
274
util_mutexUnlock(pthread_mutex_t * mutex,const char * func,int line)275 void util_mutexUnlock(pthread_mutex_t* mutex, const char* func, int line) {
276 if (pthread_mutex_unlock(mutex)) {
277 PLOG_F("%s():%d pthread_mutex_unlock(%p)", func, line, (void*)mutex);
278 }
279 }
280
util_mutexRWLockRead(pthread_rwlock_t * mutex,const char * func,int line)281 void util_mutexRWLockRead(pthread_rwlock_t* mutex, const char* func, int line) {
282 if (pthread_rwlock_rdlock(mutex)) {
283 PLOG_F("%s():%d pthread_rwlock_rdlock(%p)", func, line, (void*)mutex);
284 }
285 }
286
util_mutexRWLockWrite(pthread_rwlock_t * mutex,const char * func,int line)287 void util_mutexRWLockWrite(pthread_rwlock_t* mutex, const char* func, int line) {
288 if (pthread_rwlock_wrlock(mutex)) {
289 PLOG_F("%s():%d pthread_rwlock_wrlock(%p)", func, line, (void*)mutex);
290 }
291 }
292
util_mutexRWUnlock(pthread_rwlock_t * mutex,const char * func,int line)293 void util_mutexRWUnlock(pthread_rwlock_t* mutex, const char* func, int line) {
294 if (pthread_rwlock_unlock(mutex)) {
295 PLOG_F("%s():%d pthread_rwlock_unlock(%p)", func, line, (void*)mutex);
296 }
297 }
298
fastArray64Search(uint64_t * array,size_t arraySz,uint64_t key)299 int64_t fastArray64Search(uint64_t* array, size_t arraySz, uint64_t key) {
300 size_t low = 0;
301 size_t high = arraySz - 1;
302 size_t mid;
303
304 while (array[high] != array[low] && key >= array[low] && key <= array[high]) {
305 mid = low + (key - array[low]) * ((high - low) / (array[high] - array[low]));
306
307 if (array[mid] < key) {
308 low = mid + 1;
309 } else if (key < array[mid]) {
310 high = mid - 1;
311 } else {
312 return mid;
313 }
314 }
315
316 if (key == array[low]) {
317 return low;
318 } else {
319 return -1;
320 }
321 }
322
util_isANumber(const char * s)323 bool util_isANumber(const char* s) {
324 if (!isdigit((unsigned char)s[0])) {
325 return false;
326 }
327 for (int i = 0; s[i]; s++) {
328 if (!isdigit((unsigned char)s[i]) && s[i] != 'x') {
329 return false;
330 }
331 }
332 return true;
333 }
334
util_decodeCString(char * s)335 size_t util_decodeCString(char* s) {
336 size_t o = 0;
337 for (size_t i = 0; s[i] != '\0' && s[i] != '"'; i++, o++) {
338 switch (s[i]) {
339 case '\\': {
340 i++;
341 if (!s[i]) {
342 continue;
343 }
344 switch (s[i]) {
345 case 'a':
346 s[o] = '\a';
347 break;
348 case 'r':
349 s[o] = '\r';
350 break;
351 case 'n':
352 s[o] = '\n';
353 break;
354 case 't':
355 s[o] = '\t';
356 break;
357 case '0':
358 s[o] = '\0';
359 break;
360 case 'x': {
361 if (s[i + 1] && s[i + 2]) {
362 char hex[] = {s[i + 1], s[i + 2], 0};
363 s[o] = strtoul(hex, NULL, 16);
364 i += 2;
365 } else {
366 s[o] = s[i];
367 }
368 break;
369 }
370 default:
371 s[o] = s[i];
372 break;
373 }
374 break;
375 }
376 default: {
377 s[o] = s[i];
378 break;
379 }
380 }
381 }
382 s[o] = '\0';
383 return o;
384 }
385
386 /* ISO 3309 CRC-64 Poly table */
387 static const uint64_t util_CRC64ISOPoly[] = {
388 0x0000000000000000ULL,
389 0x01B0000000000000ULL,
390 0x0360000000000000ULL,
391 0x02D0000000000000ULL,
392 0x06C0000000000000ULL,
393 0x0770000000000000ULL,
394 0x05A0000000000000ULL,
395 0x0410000000000000ULL,
396 0x0D80000000000000ULL,
397 0x0C30000000000000ULL,
398 0x0EE0000000000000ULL,
399 0x0F50000000000000ULL,
400 0x0B40000000000000ULL,
401 0x0AF0000000000000ULL,
402 0x0820000000000000ULL,
403 0x0990000000000000ULL,
404 0x1B00000000000000ULL,
405 0x1AB0000000000000ULL,
406 0x1860000000000000ULL,
407 0x19D0000000000000ULL,
408 0x1DC0000000000000ULL,
409 0x1C70000000000000ULL,
410 0x1EA0000000000000ULL,
411 0x1F10000000000000ULL,
412 0x1680000000000000ULL,
413 0x1730000000000000ULL,
414 0x15E0000000000000ULL,
415 0x1450000000000000ULL,
416 0x1040000000000000ULL,
417 0x11F0000000000000ULL,
418 0x1320000000000000ULL,
419 0x1290000000000000ULL,
420 0x3600000000000000ULL,
421 0x37B0000000000000ULL,
422 0x3560000000000000ULL,
423 0x34D0000000000000ULL,
424 0x30C0000000000000ULL,
425 0x3170000000000000ULL,
426 0x33A0000000000000ULL,
427 0x3210000000000000ULL,
428 0x3B80000000000000ULL,
429 0x3A30000000000000ULL,
430 0x38E0000000000000ULL,
431 0x3950000000000000ULL,
432 0x3D40000000000000ULL,
433 0x3CF0000000000000ULL,
434 0x3E20000000000000ULL,
435 0x3F90000000000000ULL,
436 0x2D00000000000000ULL,
437 0x2CB0000000000000ULL,
438 0x2E60000000000000ULL,
439 0x2FD0000000000000ULL,
440 0x2BC0000000000000ULL,
441 0x2A70000000000000ULL,
442 0x28A0000000000000ULL,
443 0x2910000000000000ULL,
444 0x2080000000000000ULL,
445 0x2130000000000000ULL,
446 0x23E0000000000000ULL,
447 0x2250000000000000ULL,
448 0x2640000000000000ULL,
449 0x27F0000000000000ULL,
450 0x2520000000000000ULL,
451 0x2490000000000000ULL,
452 0x6C00000000000000ULL,
453 0x6DB0000000000000ULL,
454 0x6F60000000000000ULL,
455 0x6ED0000000000000ULL,
456 0x6AC0000000000000ULL,
457 0x6B70000000000000ULL,
458 0x69A0000000000000ULL,
459 0x6810000000000000ULL,
460 0x6180000000000000ULL,
461 0x6030000000000000ULL,
462 0x62E0000000000000ULL,
463 0x6350000000000000ULL,
464 0x6740000000000000ULL,
465 0x66F0000000000000ULL,
466 0x6420000000000000ULL,
467 0x6590000000000000ULL,
468 0x7700000000000000ULL,
469 0x76B0000000000000ULL,
470 0x7460000000000000ULL,
471 0x75D0000000000000ULL,
472 0x71C0000000000000ULL,
473 0x7070000000000000ULL,
474 0x72A0000000000000ULL,
475 0x7310000000000000ULL,
476 0x7A80000000000000ULL,
477 0x7B30000000000000ULL,
478 0x79E0000000000000ULL,
479 0x7850000000000000ULL,
480 0x7C40000000000000ULL,
481 0x7DF0000000000000ULL,
482 0x7F20000000000000ULL,
483 0x7E90000000000000ULL,
484 0x5A00000000000000ULL,
485 0x5BB0000000000000ULL,
486 0x5960000000000000ULL,
487 0x58D0000000000000ULL,
488 0x5CC0000000000000ULL,
489 0x5D70000000000000ULL,
490 0x5FA0000000000000ULL,
491 0x5E10000000000000ULL,
492 0x5780000000000000ULL,
493 0x5630000000000000ULL,
494 0x54E0000000000000ULL,
495 0x5550000000000000ULL,
496 0x5140000000000000ULL,
497 0x50F0000000000000ULL,
498 0x5220000000000000ULL,
499 0x5390000000000000ULL,
500 0x4100000000000000ULL,
501 0x40B0000000000000ULL,
502 0x4260000000000000ULL,
503 0x43D0000000000000ULL,
504 0x47C0000000000000ULL,
505 0x4670000000000000ULL,
506 0x44A0000000000000ULL,
507 0x4510000000000000ULL,
508 0x4C80000000000000ULL,
509 0x4D30000000000000ULL,
510 0x4FE0000000000000ULL,
511 0x4E50000000000000ULL,
512 0x4A40000000000000ULL,
513 0x4BF0000000000000ULL,
514 0x4920000000000000ULL,
515 0x4890000000000000ULL,
516 0xD800000000000000ULL,
517 0xD9B0000000000000ULL,
518 0xDB60000000000000ULL,
519 0xDAD0000000000000ULL,
520 0xDEC0000000000000ULL,
521 0xDF70000000000000ULL,
522 0xDDA0000000000000ULL,
523 0xDC10000000000000ULL,
524 0xD580000000000000ULL,
525 0xD430000000000000ULL,
526 0xD6E0000000000000ULL,
527 0xD750000000000000ULL,
528 0xD340000000000000ULL,
529 0xD2F0000000000000ULL,
530 0xD020000000000000ULL,
531 0xD190000000000000ULL,
532 0xC300000000000000ULL,
533 0xC2B0000000000000ULL,
534 0xC060000000000000ULL,
535 0xC1D0000000000000ULL,
536 0xC5C0000000000000ULL,
537 0xC470000000000000ULL,
538 0xC6A0000000000000ULL,
539 0xC710000000000000ULL,
540 0xCE80000000000000ULL,
541 0xCF30000000000000ULL,
542 0xCDE0000000000000ULL,
543 0xCC50000000000000ULL,
544 0xC840000000000000ULL,
545 0xC9F0000000000000ULL,
546 0xCB20000000000000ULL,
547 0xCA90000000000000ULL,
548 0xEE00000000000000ULL,
549 0xEFB0000000000000ULL,
550 0xED60000000000000ULL,
551 0xECD0000000000000ULL,
552 0xE8C0000000000000ULL,
553 0xE970000000000000ULL,
554 0xEBA0000000000000ULL,
555 0xEA10000000000000ULL,
556 0xE380000000000000ULL,
557 0xE230000000000000ULL,
558 0xE0E0000000000000ULL,
559 0xE150000000000000ULL,
560 0xE540000000000000ULL,
561 0xE4F0000000000000ULL,
562 0xE620000000000000ULL,
563 0xE790000000000000ULL,
564 0xF500000000000000ULL,
565 0xF4B0000000000000ULL,
566 0xF660000000000000ULL,
567 0xF7D0000000000000ULL,
568 0xF3C0000000000000ULL,
569 0xF270000000000000ULL,
570 0xF0A0000000000000ULL,
571 0xF110000000000000ULL,
572 0xF880000000000000ULL,
573 0xF930000000000000ULL,
574 0xFBE0000000000000ULL,
575 0xFA50000000000000ULL,
576 0xFE40000000000000ULL,
577 0xFFF0000000000000ULL,
578 0xFD20000000000000ULL,
579 0xFC90000000000000ULL,
580 0xB400000000000000ULL,
581 0xB5B0000000000000ULL,
582 0xB760000000000000ULL,
583 0xB6D0000000000000ULL,
584 0xB2C0000000000000ULL,
585 0xB370000000000000ULL,
586 0xB1A0000000000000ULL,
587 0xB010000000000000ULL,
588 0xB980000000000000ULL,
589 0xB830000000000000ULL,
590 0xBAE0000000000000ULL,
591 0xBB50000000000000ULL,
592 0xBF40000000000000ULL,
593 0xBEF0000000000000ULL,
594 0xBC20000000000000ULL,
595 0xBD90000000000000ULL,
596 0xAF00000000000000ULL,
597 0xAEB0000000000000ULL,
598 0xAC60000000000000ULL,
599 0xADD0000000000000ULL,
600 0xA9C0000000000000ULL,
601 0xA870000000000000ULL,
602 0xAAA0000000000000ULL,
603 0xAB10000000000000ULL,
604 0xA280000000000000ULL,
605 0xA330000000000000ULL,
606 0xA1E0000000000000ULL,
607 0xA050000000000000ULL,
608 0xA440000000000000ULL,
609 0xA5F0000000000000ULL,
610 0xA720000000000000ULL,
611 0xA690000000000000ULL,
612 0x8200000000000000ULL,
613 0x83B0000000000000ULL,
614 0x8160000000000000ULL,
615 0x80D0000000000000ULL,
616 0x84C0000000000000ULL,
617 0x8570000000000000ULL,
618 0x87A0000000000000ULL,
619 0x8610000000000000ULL,
620 0x8F80000000000000ULL,
621 0x8E30000000000000ULL,
622 0x8CE0000000000000ULL,
623 0x8D50000000000000ULL,
624 0x8940000000000000ULL,
625 0x88F0000000000000ULL,
626 0x8A20000000000000ULL,
627 0x8B90000000000000ULL,
628 0x9900000000000000ULL,
629 0x98B0000000000000ULL,
630 0x9A60000000000000ULL,
631 0x9BD0000000000000ULL,
632 0x9FC0000000000000ULL,
633 0x9E70000000000000ULL,
634 0x9CA0000000000000ULL,
635 0x9D10000000000000ULL,
636 0x9480000000000000ULL,
637 0x9530000000000000ULL,
638 0x97E0000000000000ULL,
639 0x9650000000000000ULL,
640 0x9240000000000000ULL,
641 0x93F0000000000000ULL,
642 0x9120000000000000ULL,
643 0x9090000000000000ULL,
644 };
645
util_CRC64(const uint8_t * buf,size_t len)646 uint64_t util_CRC64(const uint8_t* buf, size_t len) {
647 uint64_t res = 0ULL;
648
649 for (size_t i = 0; i < len; i++) {
650 res = util_CRC64ISOPoly[(uint8_t)res ^ buf[i]] ^ (res >> 8);
651 }
652
653 return res;
654 }
655
util_CRC64Rev(const uint8_t * buf,size_t len)656 uint64_t util_CRC64Rev(const uint8_t* buf, size_t len) {
657 uint64_t res = 0ULL;
658
659 for (ssize_t i = (ssize_t)len - 1; i >= 0; i--) {
660 res = util_CRC64ISOPoly[(uint8_t)res ^ buf[i]] ^ (res >> 8);
661 }
662
663 return res;
664 }
665