blob: 7adae559ec620d0663984f706df3083e99155147 [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
Jaggerc8b6eda2016-09-01 03:52:35 +020024#include "common.h"
25#include "util.h"
26
robert.swiecki3bb518c2010-10-14 00:48:24 +000027#include <fcntl.h>
Robert Swieckic8c32db2015-10-09 18:06:22 +020028#include <inttypes.h>
robert.swiecki3bb518c2010-10-14 00:48:24 +000029#include <math.h>
robert.swiecki@gmail.come7190b92015-02-14 23:05:42 +000030#include <stdarg.h>
robert.swiecki@gmail.comba85c3e2015-02-02 14:55:16 +000031#include <stdint.h>
robert.swiecki@gmail.come7190b92015-02-14 23:05:42 +000032#include <stdio.h>
robert.swiecki@gmail.comba85c3e2015-02-02 14:55:16 +000033#include <stdlib.h>
robert.swiecki@gmail.come7190b92015-02-14 23:05:42 +000034#include <string.h>
Robert Swieckiac56a502016-03-17 18:59:46 +010035#include <sys/mman.h>
robert.swiecki@gmail.comba85c3e2015-02-02 14:55:16 +000036#include <sys/stat.h>
37#include <sys/time.h>
38#include <sys/types.h>
robert.swiecki3bb518c2010-10-14 00:48:24 +000039#include <time.h>
robert.swiecki@gmail.comba85c3e2015-02-02 14:55:16 +000040#include <unistd.h>
Anestis Bechtsoudis413cb132016-02-07 12:59:00 +020041#include <ctype.h>
robert.swiecki3bb518c2010-10-14 00:48:24 +000042
robert.swiecki@gmail.com26a9ab72015-02-22 13:41:18 +000043#include "files.h"
robert.swiecki3bb518c2010-10-14 00:48:24 +000044#include "log.h"
45
Robert Swiecki3bfc33c2016-03-14 18:12:41 +010046void *util_Malloc(size_t sz)
47{
48 void *p = malloc(sz);
49 if (p == NULL) {
50 LOG_F("malloc(size='%zu')", sz);
51 }
52 return p;
53}
54
Robert Swieckiac56a502016-03-17 18:59:46 +010055void *util_Calloc(size_t sz)
56{
57 void *p = util_Malloc(sz);
58 memset(p, '\0', sz);
59 return p;
60}
61
Jaggerf49962d2016-07-21 22:49:54 +020062extern void *util_Realloc(void *ptr, size_t sz)
63{
64 void *ret = realloc(ptr, sz);
65 if (ret == NULL) {
Robert Swieckibc7532e2016-08-20 00:34:17 +020066 PLOG_W("realloc(%p, %zu)", ptr, sz);
Jaggerf49962d2016-07-21 22:49:54 +020067 free(ptr);
68 return NULL;
69 }
70 return ret;
71}
72
Robert Swieckiac56a502016-03-17 18:59:46 +010073void *util_MMap(size_t sz)
74{
75 void *p = mmap(NULL, sz, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE | MAP_NORESERVE, -1, 0);
76 if (p == MAP_FAILED) {
77 LOG_F("mmap(size='%zu')", sz);
78 }
79 return p;
80}
81
Jagger6539b3a2016-04-06 02:32:50 +020082char *util_StrDup(const char *s)
83{
84 char *ret = strdup(s);
85 if (ret == NULL) {
86 LOG_F("strdup(size=%zu)", strlen(s));
87 }
88 return ret;
89}
90
robert.swiecki@gmail.com26a9ab72015-02-22 13:41:18 +000091static int util_urandomFd = -1;
Jagger2e518b52015-09-24 04:01:16 +020092static __thread uint64_t rndX;
93static __thread uint64_t rndIni = false;
robert.swiecki@gmail.com180263f2015-02-13 13:57:15 +000094
Jaggerc44a89a2016-09-25 16:42:44 +020095uint64_t util_rnd64(void)
robert.swiecki3bb518c2010-10-14 00:48:24 +000096{
robert.swiecki@gmail.com26a9ab72015-02-22 13:41:18 +000097 if (util_urandomFd == -1) {
Jagger5a3c4c32016-04-16 19:27:47 +020098 if ((util_urandomFd = open("/dev/urandom", O_RDONLY | O_CLOEXEC)) == -1) {
Robert Swieckic8c32db2015-10-09 18:06:22 +020099 PLOG_F("Couldn't open /dev/urandom for writing");
robert.swiecki@gmail.com26a9ab72015-02-22 13:41:18 +0000100 }
robert.swiecki@gmail.com180263f2015-02-13 13:57:15 +0000101 }
robert.swiecki3bb518c2010-10-14 00:48:24 +0000102
Jagger2e518b52015-09-24 04:01:16 +0200103 if (rndIni == false) {
Jagger4d109852016-02-04 02:28:44 +0100104 if (files_readFromFd(util_urandomFd, (uint8_t *) & rndX, sizeof(rndX)) != sizeof(rndX)) {
Robert Swieckic8c32db2015-10-09 18:06:22 +0200105 PLOG_F("Couldn't read '%zu' bytes from /dev/urandom", sizeof(rndX));
Jagger2e518b52015-09-24 04:01:16 +0200106 }
107 rndIni = true;
robert.swiecki@gmail.com4be12dc2015-02-13 14:03:53 +0000108 }
robert.swiecki@gmail.com180263f2015-02-13 13:57:15 +0000109
Jagger2e518b52015-09-24 04:01:16 +0200110 /* MMIX LCG PRNG */
111 static const uint64_t a = 6364136223846793005ULL;
112 static const uint64_t c = 1442695040888963407ULL;
robert.swiecki@gmail.combce825a2015-02-13 23:26:07 +0000113
Jagger2e518b52015-09-24 04:01:16 +0200114 rndX = (a * rndX + c);
Jaggerc44a89a2016-09-25 16:42:44 +0200115 return rndX;
116}
Jagger2e518b52015-09-24 04:01:16 +0200117
Jaggerc44a89a2016-09-25 16:42:44 +0200118uint64_t util_rndGet(uint64_t min, uint64_t max)
119{
120 if (min > max) {
121 LOG_F("min:%" PRIu64 " > max:%" PRIu64, min, max);
122 }
123
124 return ((util_rnd64() % (max - min + 1)) + min);
robert.swiecki3bb518c2010-10-14 00:48:24 +0000125}
126
robert.swiecki@gmail.com89cc38c2015-02-23 02:52:08 +0000127void util_rndBuf(uint8_t * buf, size_t sz)
128{
robert.swiecki@gmail.com08174c72015-02-28 14:38:06 +0000129 for (size_t i = 0; i < sz; i++) {
Jaggerc44a89a2016-09-25 16:42:44 +0200130 buf[i] = (uint8_t) ((util_rnd64() & 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}
Robert Swieckife8d2892016-09-13 17:57:27 +0200304
Jaggerd619ed12016-09-22 04:08:49 +0200305size_t util_decodeCString(char *s)
Robert Swieckife8d2892016-09-13 17:57:27 +0200306{
307 size_t len = strlen(s);
308 size_t o = 0;
309 for (size_t i = 0; s[i] != '\0' && i < len; i++, o++) {
310 switch (s[i]) {
311 case '\\':{
312 i++;
313 switch (s[i]) {
314 case 'a':
315 s[o] = '\a';
316 break;
317 case 'r':
318 s[o] = '\r';
319 break;
320 case 'n':
321 s[o] = '\n';
322 break;
323 case 't':
324 s[o] = '\t';
325 break;
326 case '0':
327 s[o] = '\0';
328 break;
329 case 'x':{
330 /* Yup, this can overflow */
331 char hex[] = { s[i + 1], s[i + 2], 0 };
332 s[o] = strtoul(hex, NULL, 16);
333 i += 2;
334 break;
335 }
336 default:
337 s[o] = ' ';
338 break;
339 }
340 break;
341 }
342 default:{
343 s[o] = s[i];
344 break;
345 }
346 }
347 }
348 s[o] = '\0';
Jaggerd619ed12016-09-22 04:08:49 +0200349 return o;
Robert Swieckife8d2892016-09-13 17:57:27 +0200350}