• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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, &ltime);
180     if (strftime(buf, len, fmt, &ltime) < 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