11
11
#include " FuzzerCommand.h"
12
12
#include " FuzzerFork.h"
13
13
#include " FuzzerIO.h"
14
+ #include " FuzzerInternal.h"
14
15
#include " FuzzerMerge.h"
15
16
#include " FuzzerSHA1.h"
16
17
#include " FuzzerTracePC.h"
@@ -63,6 +64,7 @@ struct FuzzJob {
63
64
// Inputs.
64
65
Command Cmd;
65
66
std::string CorpusDir;
67
+ std::string FeaturesDir;
66
68
std::string LogPath;
67
69
std::string CFPath;
68
70
@@ -73,6 +75,7 @@ struct FuzzJob {
73
75
RemoveFile (CFPath);
74
76
RemoveFile (LogPath);
75
77
RmDirRecursive (CorpusDir);
78
+ RmDirRecursive (FeaturesDir);
76
79
}
77
80
};
78
81
@@ -122,12 +125,17 @@ struct GlobalEnv {
122
125
Cmd.addFlag (" seed_inputs" , Seeds);
123
126
Job->LogPath = DirPlusFile (TempDir, std::to_string (JobId) + " .log" );
124
127
Job->CorpusDir = DirPlusFile (TempDir, " C" + std::to_string (JobId));
128
+ Job->FeaturesDir = DirPlusFile (TempDir, " F" + std::to_string (JobId));
125
129
Job->CFPath = DirPlusFile (TempDir, std::to_string (JobId) + " .merge" );
126
130
127
131
128
132
Cmd.addArgument (Job->CorpusDir );
129
- RmDirRecursive (Job->CorpusDir );
130
- MkDir (Job->CorpusDir );
133
+ Cmd.addFlag (" features_dir" , Job->FeaturesDir );
134
+
135
+ for (auto &D : {Job->CorpusDir , Job->FeaturesDir }) {
136
+ RmDirRecursive (D);
137
+ MkDir (D);
138
+ }
131
139
132
140
Cmd.setOutputFile (Job->LogPath );
133
141
Cmd.combineOutAndErr ();
@@ -142,12 +150,30 @@ struct GlobalEnv {
142
150
}
143
151
144
152
void RunOneMergeJob (FuzzJob *Job) {
145
- Vector<SizedFile> TempFiles;
153
+ Vector<SizedFile> TempFiles, MergeCandidates;
154
+ // Read all newly created inputs and their feature sets.
155
+ // Choose only those inputs that have new features.
146
156
GetSizedFilesFromDir (Job->CorpusDir , &TempFiles);
157
+ std::sort (TempFiles.begin (), TempFiles.end ());
158
+ for (auto &F : TempFiles) {
159
+ auto FeatureFile = F.File ;
160
+ FeatureFile.replace (0 , Job->CorpusDir .size (), Job->FeaturesDir );
161
+ auto FeatureBytes = FileToVector (FeatureFile, 0 , false );
162
+ assert ((FeatureBytes.size () % sizeof (uint32_t )) == 0 );
163
+ Vector<uint32_t > NewFeatures (FeatureBytes.size () / sizeof (uint32_t ));
164
+ memcpy (NewFeatures.data (), FeatureBytes.data (), FeatureBytes.size ());
165
+ for (auto Ft : NewFeatures) {
166
+ if (!Features.count (Ft)) {
167
+ MergeCandidates.push_back (F);
168
+ break ;
169
+ }
170
+ }
171
+ }
172
+ if (MergeCandidates.empty ()) return ;
147
173
148
174
Vector<std::string> FilesToAdd;
149
175
Set<uint32_t > NewFeatures, NewCov;
150
- CrashResistantMerge (Args, {}, TempFiles , &FilesToAdd, Features,
176
+ CrashResistantMerge (Args, {}, MergeCandidates , &FilesToAdd, Features,
151
177
&NewFeatures, Cov, &NewCov, Job->CFPath , false );
152
178
for (auto &Path : FilesToAdd) {
153
179
auto U = FileToVector (Path);
@@ -265,6 +291,7 @@ void FuzzWithFork(Random &Rand, const FuzzingOptions &Options,
265
291
Stop = true ;
266
292
break ;
267
293
}
294
+ Fuzzer::MaybeExitGracefully ();
268
295
269
296
Env.RunOneMergeJob (Job.get ());
270
297
0 commit comments