blob: 67f9a4809f6437ce1eba11ff2b459ce4ec299225 [file] [log] [blame]
robert.swiecki3bb518c2010-10-14 00:48:24 +00001/*
robert.swiecki@gmail.com3b630b42015-02-16 10:53:53 +00002 *
robert.swiecki@gmail.com97c77332015-02-14 23:06:58 +00003 * honggfuzz - utilities
4 * -----------------------------------------
robert.swiecki@gmail.com3b630b42015-02-16 10:53:53 +00005 *
robert.swiecki@gmail.com772b33d2015-02-14 20:35:00 +00006 * Author: Robert Swiecki <swiecki@google.com>
robert.swiecki@gmail.com3b630b42015-02-16 10:53:53 +00007 *
robert.swiecki@gmail.com772b33d2015-02-14 20:35:00 +00008 * Copyright 2010-2015 by Google Inc. All Rights Reserved.
robert.swiecki@gmail.com3b630b42015-02-16 10:53:53 +00009 *
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
robert.swiecki@gmail.com772b33d2015-02-14 20:35:00 +000012 * a copy of the License at
robert.swiecki@gmail.com3b630b42015-02-16 10:53:53 +000013 *
robert.swiecki@gmail.com772b33d2015-02-14 20:35:00 +000014 * http://www.apache.org/licenses/LICENSE-2.0
robert.swiecki@gmail.com3b630b42015-02-16 10:53:53 +000015 *
robert.swiecki@gmail.com772b33d2015-02-14 20:35:00 +000016 * 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.
robert.swiecki@gmail.com3b630b42015-02-16 10:53:53 +000021 *
robert.swiecki@gmail.com772b33d2015-02-14 20:35:00 +000022 */
robert.swiecki3bb518c2010-10-14 00:48:24 +000023
robert.swiecki3bb518c2010-10-14 00:48:24 +000024#include <fcntl.h>
Robert Swieckic8c32db2015-10-09 18:06:22 +020025#include <inttypes.h>
robert.swiecki3bb518c2010-10-14 00:48:24 +000026#include <math.h>
robert.swiecki@gmail.come7190b92015-02-14 23:05:42 +000027#include <stdarg.h>
robert.swiecki@gmail.comba85c3e2015-02-02 14:55:16 +000028#include <stdint.h>
robert.swiecki@gmail.come7190b92015-02-14 23:05:42 +000029#include <stdio.h>
robert.swiecki@gmail.comba85c3e2015-02-02 14:55:16 +000030#include <stdlib.h>
robert.swiecki@gmail.come7190b92015-02-14 23:05:42 +000031#include <string.h>
Robert Swieckiac56a502016-03-17 18:59:46 +010032#include <sys/mman.h>
robert.swiecki@gmail.comba85c3e2015-02-02 14:55:16 +000033#include <sys/stat.h>
34#include <sys/time.h>
35#include <sys/types.h>
robert.swiecki3bb518c2010-10-14 00:48:24 +000036#include <time.h>
robert.swiecki@gmail.comba85c3e2015-02-02 14:55:16 +000037#include <unistd.h>
Anestis Bechtsoudis413cb132016-02-07 12:59:00 +020038#include <ctype.h>
robert.swiecki3bb518c2010-10-14 00:48:24 +000039
40#include "common.h"
robert.swiecki@gmail.com26a9ab72015-02-22 13:41:18 +000041#include "files.h"
robert.swiecki3bb518c2010-10-14 00:48:24 +000042#include "log.h"
43
Robert Swiecki3bfc33c2016-03-14 18:12:41 +010044void *util_Malloc(size_t sz)
45{
46 void *p = malloc(sz);
47 if (p == NULL) {
48 LOG_F("malloc(size='%zu')", sz);
49 }
50 return p;
51}
52
Robert Swieckiac56a502016-03-17 18:59:46 +010053void *util_Calloc(size_t sz)
54{
55 void *p = util_Malloc(sz);
56 memset(p, '\0', sz);
57 return p;
58}
59
Jaggerf49962d2016-07-21 22:49:54 +020060extern void *util_Realloc(void *ptr, size_t sz)
61{
62 void *ret = realloc(ptr, sz);
63 if (ret == NULL) {
Robert Swieckibc7532e2016-08-20 00:34:17 +020064 PLOG_W("realloc(%p, %zu)", ptr, sz);
Jaggerf49962d2016-07-21 22:49:54 +020065 free(ptr);
66 return NULL;
67 }
68 return ret;
69}
70
Robert Swieckiac56a502016-03-17 18:59:46 +010071void *util_MMap(size_t sz)
72{
73 void *p = mmap(NULL, sz, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE | MAP_NORESERVE, -1, 0);
74 if (p == MAP_FAILED) {
75 LOG_F("mmap(size='%zu')", sz);
76 }
77 return p;
78}
79
Jagger6539b3a2016-04-06 02:32:50 +020080char *util_StrDup(const char *s)
81{
82 char *ret = strdup(s);
83 if (ret == NULL) {
84 LOG_F("strdup(size=%zu)", strlen(s));
85 }
86 return ret;
87}
88
robert.swiecki@gmail.com26a9ab72015-02-22 13:41:18 +000089static int util_urandomFd = -1;
Jagger2e518b52015-09-24 04:01:16 +020090static __thread uint64_t rndX;
91static __thread uint64_t rndIni = false;
robert.swiecki@gmail.com180263f2015-02-13 13:57:15 +000092
robert.swiecki@gmail.com90e99112015-02-15 02:05:14 +000093uint64_t util_rndGet(uint64_t min, uint64_t max)
robert.swiecki3bb518c2010-10-14 00:48:24 +000094{
Jagger2e518b52015-09-24 04:01:16 +020095 if (min > max) {
Anestis Bechtsoudis07e14ce2015-12-30 14:15:42 +020096 LOG_F("min:%" PRIu64 " > max:%" PRIu64, min, max);
Jagger2e518b52015-09-24 04:01:16 +020097 }
98
robert.swiecki@gmail.com26a9ab72015-02-22 13:41:18 +000099 if (util_urandomFd == -1) {
Jagger5a3c4c32016-04-16 19:27:47 +0200100 if ((util_urandomFd = open("/dev/urandom", O_RDONLY | O_CLOEXEC)) == -1) {
Robert Swieckic8c32db2015-10-09 18:06:22 +0200101 PLOG_F("Couldn't open /dev/urandom for writing");
robert.swiecki@gmail.com26a9ab72015-02-22 13:41:18 +0000102 }
robert.swiecki@gmail.com180263f2015-02-13 13:57:15 +0000103 }
robert.swiecki3bb518c2010-10-14 00:48:24 +0000104
Jagger2e518b52015-09-24 04:01:16 +0200105 if (rndIni == false) {
Jagger4d109852016-02-04 02:28:44 +0100106 if (files_readFromFd(util_urandomFd, (uint8_t *) & rndX, sizeof(rndX)) != sizeof(rndX)) {
Robert Swieckic8c32db2015-10-09 18:06:22 +0200107 PLOG_F("Couldn't read '%zu' bytes from /dev/urandom", sizeof(rndX));
Jagger2e518b52015-09-24 04:01:16 +0200108 }
109 rndIni = true;
robert.swiecki@gmail.com4be12dc2015-02-13 14:03:53 +0000110 }
robert.swiecki@gmail.com180263f2015-02-13 13:57:15 +0000111
Jagger2e518b52015-09-24 04:01:16 +0200112 /* MMIX LCG PRNG */
113 static const uint64_t a = 6364136223846793005ULL;
114 static const uint64_t c = 1442695040888963407ULL;
robert.swiecki@gmail.combce825a2015-02-13 23:26:07 +0000115
Jagger2e518b52015-09-24 04:01:16 +0200116 rndX = (a * rndX + c);
117
118 return ((rndX % (max - min + 1)) + min);
robert.swiecki3bb518c2010-10-14 00:48:24 +0000119}
120
robert.swiecki@gmail.com89cc38c2015-02-23 02:52:08 +0000121void util_rndBuf(uint8_t * buf, size_t sz)
122{
robert.swiecki@gmail.comace40862015-03-08 07:09:56 +0000123 /* MMIX LCG PRNG */
Jagger89085f92015-09-24 04:45:53 +0200124 static const uint64_t a = 6364136223846793005ULL;
125 static const uint64_t c = 1442695040888963407ULL;
126 uint64_t x = util_rndGet(0, 1ULL << 62);
robert.swiecki@gmail.com89cc38c2015-02-23 02:52:08 +0000127
robert.swiecki@gmail.com08174c72015-02-28 14:38:06 +0000128 for (size_t i = 0; i < sz; i++) {
robert.swiecki@gmail.comace40862015-03-08 07:09:56 +0000129 x = (a * x + c);
Robert Swiecki2ec203d2016-03-17 19:14:04 +0100130 buf[i] = (uint8_t) ((x & 0xFF0000) > 16);
robert.swiecki@gmail.com89cc38c2015-02-23 02:52:08 +0000131 }
robert.swiecki@gmail.com89cc38c2015-02-23 02:52:08 +0000132}
133
Robert Swiecki23ec02a2016-01-19 18:47:45 +0100134/*
Anestis Bechtsoudisbe0ac7b2015-12-26 15:38:47 +0200135 * Function has variable length stack size, although already we know it's invoked
136 * with relatively small sizes (max is _HF_REPORT_SIZE), thus safe to silent warning.
137 */
138#pragma GCC diagnostic push
Anestis Bechtsoudis539dbc52015-12-26 20:11:46 +0200139#pragma GCC diagnostic ignored "-Wframe-larger-than="
robert.swiecki@gmail.com9e2d43d2015-02-16 12:17:39 +0000140int util_vssnprintf(char *str, size_t size, const char *format, va_list ap)
141{
142 char buf1[size];
143 char buf2[size];
144
145 strncpy(buf1, str, size);
146
147 vsnprintf(buf2, size, format, ap);
148
149 return snprintf(str, size, "%s%s", buf1, buf2);
150}
151
152int util_ssnprintf(char *str, size_t size, const char *format, ...)
robert.swiecki@gmail.come7190b92015-02-14 23:05:42 +0000153{
154 char buf1[size];
155 char buf2[size];
156
157 strncpy(buf1, str, size);
158
159 va_list args;
160 va_start(args, format);
161 vsnprintf(buf2, size, format, args);
162 va_end(args);
163
robert.swiecki@gmail.com9e2d43d2015-02-16 12:17:39 +0000164 return snprintf(str, size, "%s%s", buf1, buf2);
robert.swiecki@gmail.come7190b92015-02-14 23:05:42 +0000165}
166
Anestis Bechtsoudisbe0ac7b2015-12-26 15:38:47 +0200167#pragma GCC diagnostic pop /* EOF diagnostic ignored "-Wstack-usage=" */
168
Robert Swiecki81c6a0d2015-09-08 15:43:20 +0200169void util_getLocalTime(const char *fmt, char *buf, size_t len, time_t tm)
robert.swiecki3bb518c2010-10-14 00:48:24 +0000170{
171 struct tm ltime;
Robert Swiecki81c6a0d2015-09-08 15:43:20 +0200172 localtime_r(&tm, &ltime);
173 if (strftime(buf, len, fmt, &ltime) < 1) {
174 snprintf(buf, len, "[date fetch error]");
175 }
robert.swiecki3bb518c2010-10-14 00:48:24 +0000176}
177
robert.swiecki40499ff2010-12-13 19:47:08 +0000178void util_nullifyStdio(void)
robert.swiecki3bb518c2010-10-14 00:48:24 +0000179{
180 int fd = open("/dev/null", O_RDWR);
181
182 if (fd == -1) {
Robert Swieckic8c32db2015-10-09 18:06:22 +0200183 PLOG_E("Couldn't open '/dev/null'");
robert.swiecki3bb518c2010-10-14 00:48:24 +0000184 return;
185 }
186
187 dup2(fd, 0);
188 dup2(fd, 1);
189 dup2(fd, 2);
190
191 if (fd > 2) {
192 close(fd);
193 }
robert.swiecki3bb518c2010-10-14 00:48:24 +0000194}
195
Robert Swiecki1e1b3532016-03-10 18:43:28 +0100196bool util_redirectStdin(const char *inputFile)
robert.swiecki3bb518c2010-10-14 00:48:24 +0000197{
198 int fd = open(inputFile, O_RDONLY);
199
200 if (fd == -1) {
Robert Swieckibc7532e2016-08-20 00:34:17 +0200201 PLOG_W("Couldn't open '%s'", inputFile);
robert.swiecki3bb518c2010-10-14 00:48:24 +0000202 return false;
203 }
204
205 dup2(fd, 0);
206 if (fd != 0) {
207 close(fd);
208 }
209
210 return true;
211}
212
robert.swiecki@gmail.com772b33d2015-02-14 20:35:00 +0000213/*
robert.swiecki@gmail.com3b630b42015-02-16 10:53:53 +0000214 * This is not a cryptographically secure hash
robert.swiecki@gmail.com772b33d2015-02-14 20:35:00 +0000215 */
Anestis Bechtsoudis38572552016-02-07 12:55:55 +0200216uint64_t util_hash(const char *buf, size_t len)
groebert@google.com1bd4c212013-06-19 11:13:56 +0000217{
218 uint64_t ret = 0;
219
220 for (size_t i = 0; i < len; i++) {
221 ret += buf[i];
222 ret += (ret << 10);
223 ret ^= (ret >> 6);
224 }
225
226 return ret;
227}
robert.swiecki@gmail.com549ff182015-02-28 22:38:00 +0000228
Anestis Bechtsoudis38572552016-02-07 12:55:55 +0200229int64_t util_timeNowMillis(void)
robert.swiecki@gmail.com3213a112015-03-12 01:42:02 +0000230{
231 struct timeval tv;
232 if (gettimeofday(&tv, NULL) == -1) {
Robert Swieckic8c32db2015-10-09 18:06:22 +0200233 PLOG_F("gettimeofday()");
robert.swiecki@gmail.com3213a112015-03-12 01:42:02 +0000234 }
235
236 return (((int64_t) tv.tv_sec * 1000LL) + ((int64_t) tv.tv_usec / 1000LL));
237}
238
Anestis Bechtsoudis38572552016-02-07 12:55:55 +0200239uint64_t util_getUINT32(const uint8_t * buf)
Anestis Bechtsoudisbe0ac7b2015-12-26 15:38:47 +0200240{
Jagger26569d92016-03-17 02:22:15 +0100241 uint32_t r;
Jaggerc54b8932016-03-17 03:12:06 +0100242 memcpy(&r, buf, sizeof(r));
Jagger26569d92016-03-17 02:22:15 +0100243 return (uint64_t) r;
Anestis Bechtsoudisbe0ac7b2015-12-26 15:38:47 +0200244}
245
Anestis Bechtsoudis38572552016-02-07 12:55:55 +0200246uint64_t util_getUINT64(const uint8_t * buf)
Anestis Bechtsoudisbe0ac7b2015-12-26 15:38:47 +0200247{
Jagger26569d92016-03-17 02:22:15 +0100248 uint64_t r;
Jaggerc54b8932016-03-17 03:12:06 +0100249 memcpy(&r, buf, sizeof(r));
Jagger26569d92016-03-17 02:22:15 +0100250 return r;
robert.swiecki@gmail.com549ff182015-02-28 22:38:00 +0000251}
Jagger421aca82015-09-05 14:09:47 +0200252
Jagger6caced32016-03-10 21:42:23 +0100253void util_mutexLock(pthread_mutex_t * mutex, const char *func, int line)
Jagger421aca82015-09-05 14:09:47 +0200254{
255 if (pthread_mutex_lock(mutex)) {
Anestis Bechtsoudis5a401c42016-04-22 07:50:19 +0300256 PLOG_F("%s():%d pthread_mutex_lock(%p)", func, line, (void *)mutex);
Jagger421aca82015-09-05 14:09:47 +0200257 }
258}
259
Jagger6caced32016-03-10 21:42:23 +0100260void util_mutexUnlock(pthread_mutex_t * mutex, const char *func, int line)
Jagger421aca82015-09-05 14:09:47 +0200261{
262 if (pthread_mutex_unlock(mutex)) {
Anestis Bechtsoudis5a401c42016-04-22 07:50:19 +0300263 PLOG_F("%s():%d pthread_mutex_unlock(%p)", func, line, (void *)mutex);
Jagger421aca82015-09-05 14:09:47 +0200264 }
265}
Anestis Bechtsoudisd59af692015-09-21 15:15:05 +0300266
Anestis Bechtsoudis38572552016-02-07 12:55:55 +0200267int64_t fastArray64Search(uint64_t * array, size_t arraySz, uint64_t key)
Anestis Bechtsoudisd59af692015-09-21 15:15:05 +0300268{
269 size_t low = 0;
270 size_t high = arraySz - 1;
271 size_t mid;
272
273 while (array[high] != array[low] && key >= array[low] && key <= array[high]) {
274 mid = low + (key - array[low]) * ((high - low) / (array[high] - array[low]));
275
276 if (array[mid] < key) {
277 low = mid + 1;
278 } else if (key < array[mid]) {
279 high = mid - 1;
280 } else {
281 return mid;
282 }
283 }
284
285 if (key == array[low]) {
286 return low;
287 } else {
288 return -1;
289 }
290}
Anestis Bechtsoudis413cb132016-02-07 12:59:00 +0200291
292bool util_isANumber(const char *s)
293{
294 if (!isdigit(s[0])) {
295 return false;
296 }
297 for (int i = 0; s[i]; s++) {
298 if (!isdigit(s[i]) && s[i] != 'x') {
299 return false;
300 }
301 }
302 return true;
303}