blob: 70182162a9159dab4e651cca968e7b2289654d1c [file] [log] [blame]
Robert Swiecki47476f22017-09-28 15:45:02 +02001/*
2 *
3 * honggfuzz - file operations
4 * -----------------------------------------
5 *
6 * Author: Robert Swiecki <swiecki@google.com>
7 *
Robert Swiecki46288f72018-02-27 17:28:47 +01008 * Copyright 2010-2018 by Google Inc. All Rights Reserved.
Robert Swiecki47476f22017-09-28 15:45:02 +02009 *
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 "input.h"
25
26#include <dirent.h>
27#include <errno.h>
28#include <fcntl.h>
29#include <inttypes.h>
30#include <stdint.h>
31#include <stdio.h>
32#include <stdlib.h>
33#include <string.h>
34#include <sys/mman.h>
35#include <sys/socket.h>
36#include <sys/stat.h>
37#include <sys/types.h>
38#include <unistd.h>
39
Robert Swiecki246af3e2018-01-05 14:56:32 +010040#include "libhfcommon/common.h"
41#include "libhfcommon/files.h"
Robert Swiecki0f2c30a2018-01-13 14:03:39 +010042#include "mangle.h"
43#include "subproc.h"
Robert Swiecki47476f22017-09-28 15:45:02 +020044
45#if defined(_HF_ARCH_LINUX)
46#include <sys/syscall.h>
47#if defined(__NR_memfd_create)
48#include <linux/memfd.h>
Robert Swiecki4e595fb2017-10-11 17:26:51 +020049#endif /* defined(__NR_memfd_create) */
50#endif /* defined(_HF_ARCH_LINUX) */
Robert Swiecki47476f22017-09-28 15:45:02 +020051
Robert Swiecki246af3e2018-01-05 14:56:32 +010052#include "libhfcommon/log.h"
53#include "libhfcommon/util.h"
Robert Swiecki47476f22017-09-28 15:45:02 +020054
Robert Swiecki0f2c30a2018-01-13 14:03:39 +010055void input_setSize(run_t* run, size_t sz) {
Robert Swieckie9231d62018-03-02 03:35:11 +010056 if (sz > run->global->mutate.maxFileSz) {
57 PLOG_F("Too large size requested: %zu > maxSize: %zu", sz, run->global->mutate.maxFileSz);
Robert Swiecki0f2c30a2018-01-13 14:03:39 +010058 }
Robert Swiecki5d1b6dc2019-02-11 14:01:41 +010059 /* ftruncate of a mmaped file fails under CygWin */
Robert Swieckid1284342019-02-11 23:14:49 +010060#if !defined(__CYGWIN__)
61 /* ftruncate for each change of a dynamic file size might be expensive though */
Robert Swiecki106c2dd2019-02-11 00:28:16 +010062 if (TEMP_FAILURE_RETRY(ftruncate(run->dynamicFileFd, sz)) == -1) {
63 PLOG_W("ftruncate(run->dynamicFileFd=%d, sz=%zu)", run->dynamicFileFd, sz);
plusun98022492018-08-06 07:16:24 +000064 }
Robert Swiecki5d1b6dc2019-02-11 14:01:41 +010065#endif /* !defined(__CYGWIN__) */
Robert Swieckia31b60b2019-02-11 00:04:13 +010066 run->dynamicFileSz = sz;
Robert Swiecki0f2c30a2018-01-13 14:03:39 +010067}
68
Robert Swieckid50ed422017-11-13 23:32:26 +010069static bool input_getDirStatsAndRewind(honggfuzz_t* hfuzz) {
Robert Swieckia35d9d82017-12-15 22:00:41 +010070 rewinddir(hfuzz->io.inputDirPtr);
Robert Swiecki47476f22017-09-28 15:45:02 +020071
72 size_t maxSize = 0U;
73 size_t fileCnt = 0U;
74 for (;;) {
75 errno = 0;
Robert Swieckia35d9d82017-12-15 22:00:41 +010076 struct dirent* entry = readdir(hfuzz->io.inputDirPtr);
Robert Swiecki47476f22017-09-28 15:45:02 +020077 if (entry == NULL && errno == EINTR) {
78 continue;
79 }
80 if (entry == NULL && errno != 0) {
Robert Swiecki82c707c2017-11-14 16:36:23 +010081 PLOG_W("readdir('%s')", hfuzz->io.inputDir);
Robert Swiecki47476f22017-09-28 15:45:02 +020082 return false;
83 }
84 if (entry == NULL) {
85 break;
86 }
87
88 char fname[PATH_MAX];
Robert Swiecki82c707c2017-11-14 16:36:23 +010089 snprintf(fname, sizeof(fname), "%s/%s", hfuzz->io.inputDir, entry->d_name);
Robert Swiecki47476f22017-09-28 15:45:02 +020090 LOG_D("Analyzing file '%s'", fname);
91
92 struct stat st;
93 if (stat(fname, &st) == -1) {
94 LOG_W("Couldn't stat() the '%s' file", fname);
95 continue;
96 }
97 if (!S_ISREG(st.st_mode)) {
98 LOG_D("'%s' is not a regular file, skipping", fname);
99 continue;
100 }
Robert Swieckie9231d62018-03-02 03:35:11 +0100101 if (hfuzz->mutate.maxFileSz != 0UL && st.st_size > (off_t)hfuzz->mutate.maxFileSz) {
Robert Swiecki3b7ccf62018-01-25 20:16:52 +0100102 LOG_D("File '%s' is bigger than maximal defined file size (-F): %" PRId64 " > %" PRId64,
Robert Swieckie9231d62018-03-02 03:35:11 +0100103 fname, (int64_t)st.st_size, (int64_t)hfuzz->mutate.maxFileSz);
Robert Swiecki47476f22017-09-28 15:45:02 +0200104 }
Robert Swiecki4e595fb2017-10-11 17:26:51 +0200105 if ((size_t)st.st_size > maxSize) {
Robert Swiecki47476f22017-09-28 15:45:02 +0200106 maxSize = st.st_size;
107 }
108 fileCnt++;
109 }
110
Robert Swiecki82c707c2017-11-14 16:36:23 +0100111 ATOMIC_SET(hfuzz->io.fileCnt, fileCnt);
Robert Swieckie9231d62018-03-02 03:35:11 +0100112 if (hfuzz->mutate.maxFileSz == 0U) {
Robert Swiecki47476f22017-09-28 15:45:02 +0200113 if (maxSize < 8192) {
Robert Swieckie9231d62018-03-02 03:35:11 +0100114 hfuzz->mutate.maxFileSz = 8192;
Robert Swiecki0a01ea72018-01-11 01:50:18 +0100115 } else if (maxSize > _HF_INPUT_MAX_SIZE) {
Robert Swieckie9231d62018-03-02 03:35:11 +0100116 hfuzz->mutate.maxFileSz = _HF_INPUT_MAX_SIZE;
Robert Swiecki47476f22017-09-28 15:45:02 +0200117 } else {
Robert Swieckie9231d62018-03-02 03:35:11 +0100118 hfuzz->mutate.maxFileSz = maxSize;
Robert Swiecki47476f22017-09-28 15:45:02 +0200119 }
120 }
Robert Swiecki47476f22017-09-28 15:45:02 +0200121
Robert Swiecki82c707c2017-11-14 16:36:23 +0100122 if (hfuzz->io.fileCnt == 0U) {
123 LOG_W("No usable files in the input directory '%s'", hfuzz->io.inputDir);
Robert Swiecki47476f22017-09-28 15:45:02 +0200124 }
125
Robert Swiecki82c707c2017-11-14 16:36:23 +0100126 LOG_D("Re-read the '%s', maxFileSz:%zu, number of usable files:%zu", hfuzz->io.inputDir,
Robert Swieckie9231d62018-03-02 03:35:11 +0100127 hfuzz->mutate.maxFileSz, hfuzz->io.fileCnt);
Robert Swiecki47476f22017-09-28 15:45:02 +0200128
Robert Swieckia35d9d82017-12-15 22:00:41 +0100129 rewinddir(hfuzz->io.inputDirPtr);
Robert Swiecki47476f22017-09-28 15:45:02 +0200130
131 return true;
132}
133
Robert Swieckid50ed422017-11-13 23:32:26 +0100134bool input_getNext(run_t* run, char* fname, bool rewind) {
Robert Swiecki47476f22017-09-28 15:45:02 +0200135 static pthread_mutex_t input_mutex = PTHREAD_MUTEX_INITIALIZER;
136 MX_SCOPED_LOCK(&input_mutex);
137
Robert Swiecki82c707c2017-11-14 16:36:23 +0100138 if (run->global->io.fileCnt == 0U) {
Robert Swiecki40332e92018-01-14 16:50:35 +0100139 LOG_W("No useful files in the input directory");
Robert Swiecki47476f22017-09-28 15:45:02 +0200140 return false;
141 }
142
143 for (;;) {
144 errno = 0;
Robert Swieckia35d9d82017-12-15 22:00:41 +0100145 struct dirent* entry = readdir(run->global->io.inputDirPtr);
Robert Swiecki47476f22017-09-28 15:45:02 +0200146 if (entry == NULL && errno == EINTR) {
147 continue;
148 }
149 if (entry == NULL && errno != 0) {
Robert Swiecki82c707c2017-11-14 16:36:23 +0100150 PLOG_W("readdir_r('%s')", run->global->io.inputDir);
Robert Swiecki47476f22017-09-28 15:45:02 +0200151 return false;
152 }
153 if (entry == NULL && rewind == false) {
154 return false;
155 }
156 if (entry == NULL && rewind == true) {
Robert Swiecki78633d12017-11-13 23:24:55 +0100157 if (input_getDirStatsAndRewind(run->global) == false) {
Robert Swiecki82c707c2017-11-14 16:36:23 +0100158 LOG_E("input_getDirStatsAndRewind('%s')", run->global->io.inputDir);
Robert Swiecki47476f22017-09-28 15:45:02 +0200159 return false;
160 }
161 continue;
162 }
163
Robert Swiecki82c707c2017-11-14 16:36:23 +0100164 snprintf(fname, PATH_MAX, "%s/%s", run->global->io.inputDir, entry->d_name);
Robert Swiecki47476f22017-09-28 15:45:02 +0200165
166 struct stat st;
167 if (stat(fname, &st) == -1) {
168 LOG_W("Couldn't stat() the '%s' file", fname);
169 continue;
170 }
171 if (!S_ISREG(st.st_mode)) {
172 LOG_D("'%s' is not a regular file, skipping", fname);
173 continue;
174 }
Robert Swiecki47476f22017-09-28 15:45:02 +0200175 return true;
176 }
177}
178
Robert Swieckid50ed422017-11-13 23:32:26 +0100179bool input_init(honggfuzz_t* hfuzz) {
Robert Swiecki82c707c2017-11-14 16:36:23 +0100180 hfuzz->io.fileCnt = 0U;
Robert Swiecki47476f22017-09-28 15:45:02 +0200181
Robert Swiecki82c707c2017-11-14 16:36:23 +0100182 if (!hfuzz->io.inputDir) {
Robert Swiecki47476f22017-09-28 15:45:02 +0200183 LOG_W("No input file/dir specified");
184 return false;
185 }
186
Robert Swiecki82c707c2017-11-14 16:36:23 +0100187 int dir_fd = open(hfuzz->io.inputDir, O_DIRECTORY | O_RDONLY | O_CLOEXEC);
Robert Swiecki47476f22017-09-28 15:45:02 +0200188 if (dir_fd == -1) {
Robert Swiecki82c707c2017-11-14 16:36:23 +0100189 PLOG_W("open('%s', O_DIRECTORY|O_RDONLY|O_CLOEXEC)", hfuzz->io.inputDir);
Robert Swiecki47476f22017-09-28 15:45:02 +0200190 return false;
191 }
Robert Swieckia35d9d82017-12-15 22:00:41 +0100192 if ((hfuzz->io.inputDirPtr = fdopendir(dir_fd)) == NULL) {
Robert Swiecki47476f22017-09-28 15:45:02 +0200193 close(dir_fd);
Robert Swiecki82c707c2017-11-14 16:36:23 +0100194 PLOG_W("opendir('%s')", hfuzz->io.inputDir);
Robert Swiecki47476f22017-09-28 15:45:02 +0200195 return false;
196 }
197 if (input_getDirStatsAndRewind(hfuzz) == false) {
Robert Swiecki82c707c2017-11-14 16:36:23 +0100198 hfuzz->io.fileCnt = 0U;
199 LOG_W("input_getDirStatsAndRewind('%s')", hfuzz->io.inputDir);
Robert Swiecki47476f22017-09-28 15:45:02 +0200200 return false;
201 }
202
203 return true;
204}
205
Robert Swieckid50ed422017-11-13 23:32:26 +0100206bool input_parseDictionary(honggfuzz_t* hfuzz) {
Robert Swiecki04dcac32018-03-02 03:05:26 +0100207 FILE* fDict = fopen(hfuzz->mutate.dictionaryFile, "rb");
Robert Swiecki47476f22017-09-28 15:45:02 +0200208 if (fDict == NULL) {
Robert Swiecki04dcac32018-03-02 03:05:26 +0100209 PLOG_W("Couldn't open '%s' - R/O mode", hfuzz->mutate.dictionaryFile);
Robert Swiecki47476f22017-09-28 15:45:02 +0200210 return false;
211 }
Robert Swiecki3ab16642018-01-12 18:08:37 +0100212 defer {
213 fclose(fDict);
214 };
Robert Swiecki47476f22017-09-28 15:45:02 +0200215
Robert Swiecki4e595fb2017-10-11 17:26:51 +0200216 char* lineptr = NULL;
Robert Swiecki47476f22017-09-28 15:45:02 +0200217 size_t n = 0;
Robert Swiecki3ab16642018-01-12 18:08:37 +0100218 defer {
219 free(lineptr);
220 };
Robert Swiecki47476f22017-09-28 15:45:02 +0200221 for (;;) {
222 ssize_t len = getdelim(&lineptr, &n, '\n', fDict);
223 if (len == -1) {
224 break;
225 }
226 if (len > 1 && lineptr[len - 1] == '\n') {
227 lineptr[len - 1] = '\0';
228 len--;
229 }
230 if (lineptr[0] == '#') {
231 continue;
232 }
233 if (lineptr[0] == '\n') {
234 continue;
235 }
236 if (lineptr[0] == '\0') {
237 continue;
238 }
Robert Swiecki49117302017-12-27 20:47:31 +0100239 char bufn[1025] = {};
240 char bufv[1025] = {};
Robert Swiecki40332e92018-01-14 16:50:35 +0100241 if (sscanf(lineptr, "\"%1024s", bufv) != 1 &&
242 sscanf(lineptr, "%1024[^=]=\"%1024s", bufn, bufv) != 2) {
Robert Swiecki47476f22017-09-28 15:45:02 +0200243 LOG_W("Incorrect dictionary entry: '%s'. Skipping", lineptr);
244 continue;
245 }
246
Robert Swiecki40332e92018-01-14 16:50:35 +0100247 LOG_D("Parsing word: '%s'", bufv);
248
Robert Swiecki4e595fb2017-10-11 17:26:51 +0200249 char* s = util_StrDup(bufv);
250 struct strings_t* str = (struct strings_t*)util_Malloc(sizeof(struct strings_t));
Robert Swiecki47476f22017-09-28 15:45:02 +0200251 str->len = util_decodeCString(s);
252 str->s = s;
Robert Swiecki04dcac32018-03-02 03:05:26 +0100253 hfuzz->mutate.dictionaryCnt += 1;
254 TAILQ_INSERT_TAIL(&hfuzz->mutate.dictq, str, pointers);
Robert Swiecki47476f22017-09-28 15:45:02 +0200255
256 LOG_D("Dictionary: loaded word: '%s' (len=%zu)", str->s, str->len);
257 }
Robert Swiecki04dcac32018-03-02 03:05:26 +0100258 LOG_I("Loaded %zu words from the dictionary", hfuzz->mutate.dictionaryCnt);
Robert Swiecki47476f22017-09-28 15:45:02 +0200259 return true;
260}
261
Robert Swieckid50ed422017-11-13 23:32:26 +0100262bool input_parseBlacklist(honggfuzz_t* hfuzz) {
Robert Swieckia5b918a2018-03-07 23:59:53 +0100263 FILE* fBl = fopen(hfuzz->feedback.blacklistFile, "rb");
Robert Swiecki47476f22017-09-28 15:45:02 +0200264 if (fBl == NULL) {
Robert Swieckia5b918a2018-03-07 23:59:53 +0100265 PLOG_W("Couldn't open '%s' - R/O mode", hfuzz->feedback.blacklistFile);
Robert Swiecki47476f22017-09-28 15:45:02 +0200266 return false;
267 }
Robert Swiecki3ab16642018-01-12 18:08:37 +0100268 defer {
269 fclose(fBl);
270 };
Robert Swiecki47476f22017-09-28 15:45:02 +0200271
Robert Swiecki4e595fb2017-10-11 17:26:51 +0200272 char* lineptr = NULL;
Robert Swiecki47476f22017-09-28 15:45:02 +0200273 /* lineptr can be NULL, but it's fine for free() */
Robert Swiecki3ab16642018-01-12 18:08:37 +0100274 defer {
275 free(lineptr);
276 };
Robert Swiecki47476f22017-09-28 15:45:02 +0200277 size_t n = 0;
278 for (;;) {
279 if (getline(&lineptr, &n, fBl) == -1) {
280 break;
281 }
282
Robert Swieckia5b918a2018-03-07 23:59:53 +0100283 if ((hfuzz->feedback.blacklist = util_Realloc(hfuzz->feedback.blacklist,
284 (hfuzz->feedback.blacklistCnt + 1) * sizeof(hfuzz->feedback.blacklist[0]))) ==
285 NULL) {
286 PLOG_W("realloc failed (sz=%zu)",
287 (hfuzz->feedback.blacklistCnt + 1) * sizeof(hfuzz->feedback.blacklist[0]));
Robert Swiecki47476f22017-09-28 15:45:02 +0200288 return false;
289 }
290
Robert Swieckia5b918a2018-03-07 23:59:53 +0100291 hfuzz->feedback.blacklist[hfuzz->feedback.blacklistCnt] = strtoull(lineptr, 0, 16);
292 LOG_D("Blacklist: loaded %'" PRIu64 "'",
293 hfuzz->feedback.blacklist[hfuzz->feedback.blacklistCnt]);
Robert Swiecki47476f22017-09-28 15:45:02 +0200294
Robert Swiecki5eeb29b2018-01-21 16:07:06 +0100295 /* Verify entries are sorted so we can use interpolation search */
Robert Swieckia5b918a2018-03-07 23:59:53 +0100296 if (hfuzz->feedback.blacklistCnt > 1) {
297 if (hfuzz->feedback.blacklist[hfuzz->feedback.blacklistCnt - 1] >
298 hfuzz->feedback.blacklist[hfuzz->feedback.blacklistCnt]) {
Robert Swiecki98e23372019-01-30 11:50:18 +0100299 LOG_F("Blacklist file not sorted. Use 'tools/createStackBlacklist.sh' to sort "
300 "records");
Robert Swiecki47476f22017-09-28 15:45:02 +0200301 return false;
302 }
303 }
Robert Swieckia5b918a2018-03-07 23:59:53 +0100304 hfuzz->feedback.blacklistCnt += 1;
Robert Swiecki47476f22017-09-28 15:45:02 +0200305 }
306
Robert Swieckia5b918a2018-03-07 23:59:53 +0100307 if (hfuzz->feedback.blacklistCnt > 0) {
308 LOG_I("Loaded %zu stack hash(es) from the blacklist file", hfuzz->feedback.blacklistCnt);
Robert Swiecki47476f22017-09-28 15:45:02 +0200309 } else {
Robert Swieckia5b918a2018-03-07 23:59:53 +0100310 LOG_F("Empty stack hashes blacklist file '%s'", hfuzz->feedback.blacklistFile);
Robert Swiecki47476f22017-09-28 15:45:02 +0200311 }
312 return true;
313}
Robert Swiecki0f2c30a2018-01-13 14:03:39 +0100314
Robert Swiecki0f2c30a2018-01-13 14:03:39 +0100315bool input_prepareDynamicInput(run_t* run) {
Robert Swiecki0f2c30a2018-01-13 14:03:39 +0100316 {
Robert Swiecki363510f2018-03-09 02:00:30 +0100317 MX_SCOPED_RWLOCK_READ(&run->global->io.dynfileq_mutex);
Robert Swiecki0f2c30a2018-01-13 14:03:39 +0100318
Robert Swiecki363510f2018-03-09 02:00:30 +0100319 if (run->global->io.dynfileqCnt == 0) {
Robert Swieckifb8a5b62018-01-14 05:16:59 +0100320 LOG_F("The dynamic file corpus is empty. This shouldn't happen");
Robert Swiecki0f2c30a2018-01-13 14:03:39 +0100321 }
322
323 if (run->dynfileqCurrent == NULL) {
Robert Swiecki363510f2018-03-09 02:00:30 +0100324 run->dynfileqCurrent = TAILQ_FIRST(&run->global->io.dynfileq);
Robert Swiecki0f2c30a2018-01-13 14:03:39 +0100325 } else {
Robert Swiecki363510f2018-03-09 02:00:30 +0100326 if (run->dynfileqCurrent == TAILQ_LAST(&run->global->io.dynfileq, dyns_t)) {
327 run->dynfileqCurrent = TAILQ_FIRST(&run->global->io.dynfileq);
Robert Swiecki0f2c30a2018-01-13 14:03:39 +0100328 } else {
329 run->dynfileqCurrent = TAILQ_NEXT(run->dynfileqCurrent, pointers);
330 }
331 }
332 }
333
334 input_setSize(run, run->dynfileqCurrent->size);
335 memcpy(run->dynamicFile, run->dynfileqCurrent->data, run->dynfileqCurrent->size);
336 mangle_mangleContent(run);
337
338 return true;
339}
340
341bool input_prepareStaticFile(run_t* run, bool rewind) {
Robert Swiecki94d314c2018-02-07 21:23:00 +0100342 char fname[PATH_MAX];
Robert Swieckifb8a5b62018-01-14 05:16:59 +0100343 if (!input_getNext(run, fname, /* rewind= */ rewind)) {
Robert Swiecki0f2c30a2018-01-13 14:03:39 +0100344 return false;
345 }
Robert Swiecki94d314c2018-02-07 21:23:00 +0100346 snprintf(run->origFileName, sizeof(run->origFileName), "%s", fname);
Robert Swiecki0f2c30a2018-01-13 14:03:39 +0100347
Robert Swieckif31fdf72019-02-11 00:33:27 +0100348 input_setSize(run, run->global->mutate.maxFileSz);
Robert Swieckie9231d62018-03-02 03:35:11 +0100349 ssize_t fileSz = files_readFileToBufMax(fname, run->dynamicFile, run->global->mutate.maxFileSz);
Robert Swiecki0f2c30a2018-01-13 14:03:39 +0100350 if (fileSz < 0) {
351 LOG_E("Couldn't read contents of '%s'", fname);
352 return false;
353 }
354
355 input_setSize(run, fileSz);
356 mangle_mangleContent(run);
357
358 return true;
359}
360
361bool input_prepareExternalFile(run_t* run) {
Robert Swiecki94d314c2018-02-07 21:23:00 +0100362 snprintf(run->origFileName, sizeof(run->origFileName), "[EXTERNAL]");
Robert Swiecki0f2c30a2018-01-13 14:03:39 +0100363
Robert Swieckib4333062018-01-15 23:00:45 +0100364 int fd = files_writeBufToTmpFile(run->global->io.workDir, (const uint8_t*)"", 0, 0);
Robert Swieckicdb2f232018-01-15 23:05:58 +0100365 if (fd == -1) {
366 LOG_E("Couldn't write input file to a temporary buffer");
367 return false;
368 }
Robert Swieckib4333062018-01-15 23:00:45 +0100369 defer {
370 close(fd);
371 };
Robert Swieckib4333062018-01-15 23:00:45 +0100372
Robert Swiecki0f2c30a2018-01-13 14:03:39 +0100373 char fname[PATH_MAX];
Robert Swieckib4333062018-01-15 23:00:45 +0100374 snprintf(fname, sizeof(fname), "/dev/fd/%d", fd);
Robert Swiecki0f2c30a2018-01-13 14:03:39 +0100375
376 const char* const argv[] = {run->global->exe.externalCommand, fname, NULL};
377 if (subproc_System(run, argv) != 0) {
378 LOG_E("Subprocess '%s' returned abnormally", run->global->exe.externalCommand);
379 return false;
380 }
381 LOG_D("Subporcess '%s' finished with success", run->global->exe.externalCommand);
382
Robert Swieckif31fdf72019-02-11 00:33:27 +0100383 input_setSize(run, run->global->mutate.maxFileSz);
Robert Swieckie9231d62018-03-02 03:35:11 +0100384 ssize_t sz = files_readFromFdSeek(fd, run->dynamicFile, run->global->mutate.maxFileSz, 0);
Robert Swieckib4333062018-01-15 23:00:45 +0100385 if (sz == -1) {
386 LOG_E("Couldn't read file from fd=%d", fd);
Robert Swiecki0f2c30a2018-01-13 14:03:39 +0100387 return false;
388 }
389
Robert Swieckib4333062018-01-15 23:00:45 +0100390 input_setSize(run, (size_t)sz);
Robert Swiecki0f2c30a2018-01-13 14:03:39 +0100391 return true;
392}
393
394bool input_postProcessFile(run_t* run) {
Robert Swieckib4333062018-01-15 23:00:45 +0100395 int fd =
396 files_writeBufToTmpFile(run->global->io.workDir, run->dynamicFile, run->dynamicFileSz, 0);
Robert Swieckicdb2f232018-01-15 23:05:58 +0100397 if (fd == -1) {
398 LOG_E("Couldn't write input file to a temporary buffer");
399 return false;
400 }
Robert Swieckib4333062018-01-15 23:00:45 +0100401 defer {
402 close(fd);
403 };
Robert Swieckib4333062018-01-15 23:00:45 +0100404
Robert Swiecki0f2c30a2018-01-13 14:03:39 +0100405 char fname[PATH_MAX];
Robert Swieckib4333062018-01-15 23:00:45 +0100406 snprintf(fname, sizeof(fname), "/dev/fd/%d", fd);
Robert Swiecki0f2c30a2018-01-13 14:03:39 +0100407
408 const char* const argv[] = {run->global->exe.postExternalCommand, fname, NULL};
409 if (subproc_System(run, argv) != 0) {
410 LOG_E("Subprocess '%s' returned abnormally", run->global->exe.postExternalCommand);
411 return false;
412 }
413 LOG_D("Subporcess '%s' finished with success", run->global->exe.externalCommand);
414
Robert Swieckif31fdf72019-02-11 00:33:27 +0100415 input_setSize(run, run->global->mutate.maxFileSz);
Robert Swieckie9231d62018-03-02 03:35:11 +0100416 ssize_t sz = files_readFromFdSeek(fd, run->dynamicFile, run->global->mutate.maxFileSz, 0);
Robert Swieckib4333062018-01-15 23:00:45 +0100417 if (sz == -1) {
418 LOG_E("Couldn't read file from fd=%d", fd);
Robert Swiecki0f2c30a2018-01-13 14:03:39 +0100419 return false;
420 }
421
Robert Swieckib4333062018-01-15 23:00:45 +0100422 input_setSize(run, (size_t)sz);
Robert Swiecki0f2c30a2018-01-13 14:03:39 +0100423 return true;
424}