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