blob: 287c20960db5a70f090e324a9645e977fa0f94e5 [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.swiecki3bb518c2010-10-14 00:48:24 +000025#include <math.h>
robert.swiecki@gmail.come7190b92015-02-14 23:05:42 +000026#include <stdarg.h>
robert.swiecki@gmail.comba85c3e2015-02-02 14:55:16 +000027#include <stdint.h>
robert.swiecki@gmail.come7190b92015-02-14 23:05:42 +000028#include <stdio.h>
robert.swiecki@gmail.comba85c3e2015-02-02 14:55:16 +000029#include <stdlib.h>
robert.swiecki@gmail.come7190b92015-02-14 23:05:42 +000030#include <string.h>
robert.swiecki@gmail.comba85c3e2015-02-02 14:55:16 +000031#include <sys/stat.h>
32#include <sys/time.h>
33#include <sys/types.h>
robert.swiecki3bb518c2010-10-14 00:48:24 +000034#include <time.h>
robert.swiecki@gmail.comba85c3e2015-02-02 14:55:16 +000035#include <unistd.h>
robert.swiecki3bb518c2010-10-14 00:48:24 +000036
37#include "common.h"
robert.swiecki@gmail.com26a9ab72015-02-22 13:41:18 +000038#include "files.h"
robert.swiecki3bb518c2010-10-14 00:48:24 +000039#include "log.h"
40
robert.swiecki@gmail.com26a9ab72015-02-22 13:41:18 +000041static int util_urandomFd = -1;
robert.swiecki@gmail.com180263f2015-02-13 13:57:15 +000042
robert.swiecki@gmail.com90e99112015-02-15 02:05:14 +000043uint64_t util_rndGet(uint64_t min, uint64_t max)
robert.swiecki3bb518c2010-10-14 00:48:24 +000044{
robert.swiecki@gmail.com26a9ab72015-02-22 13:41:18 +000045 if (util_urandomFd == -1) {
46 if ((util_urandomFd = open("/dev/urandom", O_RDONLY)) == -1) {
47 LOGMSG_P(l_FATAL, "Couldn't open /dev/urandom for writing");
48 }
robert.swiecki@gmail.com180263f2015-02-13 13:57:15 +000049 }
robert.swiecki3bb518c2010-10-14 00:48:24 +000050
robert.swiecki@gmail.com90e99112015-02-15 02:05:14 +000051 uint64_t rnd;
robert.swiecki@gmail.com26a9ab72015-02-22 13:41:18 +000052 if (files_readFromFd(util_urandomFd, (uint8_t *) & rnd, sizeof(rnd)) == false) {
53 LOGMSG_P(l_FATAL, "Failed reading from /dev/urandom");
robert.swiecki@gmail.com4be12dc2015-02-13 14:03:53 +000054 }
robert.swiecki@gmail.com180263f2015-02-13 13:57:15 +000055
robert.swiecki@gmail.combce825a2015-02-13 23:26:07 +000056 if (min > max) {
57 LOGMSG(l_FATAL, "min:%d > max:%d", min, max);
58 }
59
robert.swiecki@gmail.comb0383372015-02-13 14:17:27 +000060 return ((rnd % (max - min + 1)) + min);
robert.swiecki3bb518c2010-10-14 00:48:24 +000061}
62
robert.swiecki@gmail.com89cc38c2015-02-23 02:52:08 +000063void util_rndBuf(uint8_t * buf, size_t sz)
64{
robert.swiecki@gmail.com08174c72015-02-28 14:38:06 +000065 /* ISO C99 LCG PRNG */
66 uint64_t m = (1ULL << 31);
67 uint64_t a = 1103515245;
68 uint64_t c = 12345;
69 uint64_t x = util_rndGet(0, 1ULL << 31);
robert.swiecki@gmail.com89cc38c2015-02-23 02:52:08 +000070
robert.swiecki@gmail.com08174c72015-02-28 14:38:06 +000071 for (size_t i = 0; i < sz; i++) {
72 buf[i] = (uint8_t) ((x >> 16) & 0xFF);
73 x = ((a * x + c) % m);
robert.swiecki@gmail.com89cc38c2015-02-23 02:52:08 +000074 }
75
76 return;
77}
78
robert.swiecki@gmail.com9e2d43d2015-02-16 12:17:39 +000079int util_vssnprintf(char *str, size_t size, const char *format, va_list ap)
80{
81 char buf1[size];
82 char buf2[size];
83
84 strncpy(buf1, str, size);
85
86 vsnprintf(buf2, size, format, ap);
87
88 return snprintf(str, size, "%s%s", buf1, buf2);
89}
90
91int util_ssnprintf(char *str, size_t size, const char *format, ...)
robert.swiecki@gmail.come7190b92015-02-14 23:05:42 +000092{
93 char buf1[size];
94 char buf2[size];
95
96 strncpy(buf1, str, size);
97
98 va_list args;
99 va_start(args, format);
100 vsnprintf(buf2, size, format, args);
101 va_end(args);
102
robert.swiecki@gmail.com9e2d43d2015-02-16 12:17:39 +0000103 return snprintf(str, size, "%s%s", buf1, buf2);
robert.swiecki@gmail.come7190b92015-02-14 23:05:42 +0000104}
105
robert.swiecki3bb518c2010-10-14 00:48:24 +0000106void util_getLocalTime(const char *fmt, char *buf, size_t len)
107{
108 struct tm ltime;
109
110 time_t t = time(NULL);
111
112 localtime_r(&t, &ltime);
113 strftime(buf, len, fmt, &ltime);
114}
115
robert.swiecki40499ff2010-12-13 19:47:08 +0000116void util_nullifyStdio(void)
robert.swiecki3bb518c2010-10-14 00:48:24 +0000117{
118 int fd = open("/dev/null", O_RDWR);
119
120 if (fd == -1) {
121 LOGMSG_P(l_ERROR, "Couldn't open '/dev/null'");
122 return;
123 }
124
125 dup2(fd, 0);
126 dup2(fd, 1);
127 dup2(fd, 2);
128
129 if (fd > 2) {
130 close(fd);
131 }
132
133 return;
134}
135
136bool util_redirectStdin(char *inputFile)
137{
138 int fd = open(inputFile, O_RDONLY);
139
140 if (fd == -1) {
141 LOGMSG_P(l_ERROR, "Couldn't open '%s'", inputFile);
142 return false;
143 }
144
145 dup2(fd, 0);
146 if (fd != 0) {
147 close(fd);
148 }
149
150 return true;
151}
152
robert.swiecki40499ff2010-12-13 19:47:08 +0000153void util_recoverStdio(void)
robert.swiecki3bb518c2010-10-14 00:48:24 +0000154{
155 int fd = open("/dev/tty", O_RDWR);
156
157 if (fd == -1) {
158 LOGMSG_P(l_ERROR, "Couldn't open '/dev/tty'");
159 return;
160 }
161
162 dup2(fd, 0);
163 dup2(fd, 1);
164 dup2(fd, 2);
165
166 if (fd > 2) {
167 close(fd);
168 }
169
170 return;
171}
groebert@google.com1bd4c212013-06-19 11:13:56 +0000172
robert.swiecki@gmail.com772b33d2015-02-14 20:35:00 +0000173/*
robert.swiecki@gmail.com3b630b42015-02-16 10:53:53 +0000174 * This is not a cryptographically secure hash
robert.swiecki@gmail.com772b33d2015-02-14 20:35:00 +0000175 */
groebert@google.com1bd4c212013-06-19 11:13:56 +0000176extern uint64_t util_hash(const char *buf, size_t len)
177{
178 uint64_t ret = 0;
179
180 for (size_t i = 0; i < len; i++) {
181 ret += buf[i];
182 ret += (ret << 10);
183 ret ^= (ret >> 6);
184 }
185
186 return ret;
187}
robert.swiecki@gmail.com549ff182015-02-28 22:38:00 +0000188
189static uint16_t util_Swap16(uint16_t val)
190{
191 return (((val & 0xFF00) >> 8) | ((val & 0x00FF) << 8));
192}
193
194static uint32_t util_Swap32(uint32_t val)
195{
196 return (((val & 0xFF000000) >> 24) |
197 ((val & 0x00FF0000) >> 8) | ((val & 0x0000FF00) << 8) | ((val & 0x000000FF) << 24));
198}
199
200extern uint16_t util_ToFromBE16(uint16_t val)
201{
202#if __BYTE_ORDER == __BIG_ENDIAN
203 return val;
204#elif __BYTE_ORDER == __LITTLE_ENDIAN
205 return util_Swap16(val);
206#else
207#error "Unknown ENDIANESS"
208#endif
209}
210
211extern uint16_t util_ToFromLE16(uint16_t val)
212{
213#if __BYTE_ORDER == __BIG_ENDIAN
214 return util_Swap16(val);
215#elif __BYTE_ORDER == __LITTLE_ENDIAN
216 return val;
217#else
218#error "Unknown ENDIANESS"
219#endif
220}
221
222extern uint32_t util_ToFromBE32(uint32_t val)
223{
224#if __BYTE_ORDER == __BIG_ENDIAN
225 return val;
226#elif __BYTE_ORDER == __LITTLE_ENDIAN
227 return util_Swap32(val);
228#else
229#error "Unknown ENDIANESS"
230#endif
231}
232
233extern uint32_t util_ToFromLE32(uint32_t val)
234{
235#if __BYTE_ORDER == __BIG_ENDIAN
236 return util_Swap32(val);
237#elif __BYTE_ORDER == __LITTLE_ENDIAN
238 return val;
239#else
240#error "Unknown ENDIANESS"
241#endif
242}