Skip to content

Commit 459f7f7

Browse files
committed
Add back exits
1 parent 36fdb12 commit 459f7f7

File tree

2 files changed

+66
-34
lines changed

2 files changed

+66
-34
lines changed

FuzzerCorn.cpp

+38-15
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,12 @@ class FuzzerCorn {
2727
bool IsFuzzing() { return this->IsFuzzing_; }
2828

2929
FuzzerCornError
30-
Fuzz(uc_engine *Uc, int *Argc, char ***Argv,
31-
FuzzerCornPlaceInputCallback Input, FuzzerCornInitialize Init,
32-
FuzzerCornValidateCallback Validate, FuzzerCornMutatorCallback Mutate,
33-
FuzzerCornCrossOverCallback Cross, InstrumentRange *Ranges,
34-
size_t RangeCount, void *UserData, bool AlwaysValidate, int *ExitCode,
35-
size_t CounterCount) {
30+
Fuzz(uc_engine *Uc, int *Argc, char ***Argv, uint64_t *Exits,
31+
size_t ExitCount, FuzzerCornPlaceInputCallback Input,
32+
FuzzerCornInitialize Init, FuzzerCornValidateCallback Validate,
33+
FuzzerCornMutatorCallback Mutate, FuzzerCornCrossOverCallback Cross,
34+
InstrumentRange *Ranges, size_t RangeCount, void *UserData,
35+
bool AlwaysValidate, int *ExitCode, size_t CounterCount) {
3636
InitializeCallback InitCb = Init ? InitializeCallbackWrapper_ : nullptr;
3737
CustomMutatorCallback MutCb = Mutate ? MutateCallbackWrapper_ : nullptr;
3838
CustomCrossOverCallback CrossCb =
@@ -51,6 +51,8 @@ class FuzzerCorn {
5151
this->PrevLoc_ = 0;
5252
this->Ranges_ = Ranges_;
5353
this->RangeCount_ = RangeCount;
54+
this->Exits_ = Exits;
55+
this->ExitCount_ = ExitCount_;
5456

5557
*ExitCode = LLVMFuzzerRunDriver(
5658
Argc, Argv, TestOneInputCallbackWrapper_, InitCb, MutCb, CrossCb,
@@ -226,6 +228,23 @@ class FuzzerCorn {
226228
// In the fork mode:
227229
// TODO!
228230

231+
if (this->ExitCount_ == 0) {
232+
return FUZZERCORN_ERR_OK;
233+
}
234+
235+
// Enable multiple exits.
236+
Err = uc_ctl_exits_enable(this->Uc_);
237+
if (unlikely(Err)) {
238+
return FUZZERCORN_ERR_UC_ERR;
239+
}
240+
241+
// Setup exits.
242+
V.assign(this->Exits_, this->Exits_ + this->ExitCount_);
243+
Err = uc_ctl_set_exits(this->Uc_, (uint64_t *)&V[0], this->ExitCount_);
244+
if (unlikely(Err)) {
245+
return FUZZERCORN_ERR_UC_ERR;
246+
}
247+
229248
return FUZZERCORN_ERR_OK;
230249
}
231250

@@ -237,6 +256,8 @@ class FuzzerCorn {
237256
void *UserData_;
238257
InstrumentRange *Ranges_;
239258
size_t RangeCount_;
259+
uint64_t *Exits_;
260+
size_t ExitCount_;
240261
uc_engine *Uc_;
241262
FuzzerCornInitialize Init_;
242263
FuzzerCornPlaceInputCallback Input_;
@@ -252,12 +273,14 @@ class FuzzerCorn {
252273

253274
FuzzerCorn FuzzerCorn::fuzzer;
254275

255-
FuzzerCornError FuzzerCornFuzz(
256-
uc_engine *Uc, int *Argc, char ***Argv, FuzzerCornPlaceInputCallback Input,
257-
FuzzerCornInitialize Init, FuzzerCornValidateCallback Validate,
258-
FuzzerCornMutatorCallback Mutate, FuzzerCornCrossOverCallback Cross,
259-
InstrumentRange *Ranges, size_t RangeCount, void *UserData,
260-
bool AlwaysValidate, int *ExitCode, size_t CounterCount) {
276+
FuzzerCornError
277+
FuzzerCornFuzz(uc_engine *Uc, int *Argc, char ***Argv, uint64_t *Exits,
278+
size_t ExitCount, FuzzerCornPlaceInputCallback Input,
279+
FuzzerCornInitialize Init, FuzzerCornValidateCallback Validate,
280+
FuzzerCornMutatorCallback Mutate,
281+
FuzzerCornCrossOverCallback Cross, InstrumentRange *Ranges,
282+
size_t RangeCount, void *UserData, bool AlwaysValidate,
283+
int *ExitCode, size_t CounterCount) {
261284
FuzzerCorn &fuzzer = FuzzerCorn::Get();
262285

263286
if (unlikely(fuzzer.IsFuzzing())) {
@@ -285,7 +308,7 @@ FuzzerCornError FuzzerCornFuzz(
285308
return FUZZERCORN_ERR_ARG;
286309
}
287310

288-
return fuzzer.Fuzz(Uc, Argc, Argv, Input, Init, Validate, Mutate, Cross,
289-
Ranges, RangeCount, UserData, AlwaysValidate, ExitCode,
290-
CounterCount);
311+
return fuzzer.Fuzz(Uc, Argc, Argv, Exits, ExitCount, Input, Init, Validate,
312+
Mutate, Cross, Ranges, RangeCount, UserData,
313+
AlwaysValidate, ExitCode, CounterCount);
291314
}

include/FuzzerCorn.h

+28-19
Original file line numberDiff line numberDiff line change
@@ -63,32 +63,41 @@ typedef struct {
6363
// @Uc: The Unicorn instance.
6464
// @Argc: A pointer to argc.
6565
// @Argv: A pointer to argv array.
66-
// @Input: The Callback to place input. If it returns false, the unicorn won't be
67-
// started. Users also may use this to implement custom fuzzing logic, for
68-
// example starting fuzzer in the callback. Always return 0.
69-
// @Init: The Callback to initialize before fuzzing. Only called once and should always
66+
// @Input: The Callback to place input. If it returns false, the unicorn won't
67+
// be
68+
// started. Users also may use this to implement custom fuzzing logic,
69+
// for example starting fuzzer in the callback. Always return 0.
70+
// @Init: The Callback to initialize before fuzzing. Only called once and should
71+
// always
7072
// return 0 whatever happens.
71-
// @Validate: Validate if an error is a crash. Only get called if unicorn returns an
72-
// error by default. If @AlwaysValidate is set to true, it would be called
73-
// everytime the emulation is done.
74-
// @Mutate: Mutate the input **in-place**. Note that setting this pointer to non-null but
75-
// don't provide any implementation may have side-effects. If you would not like to
76-
// mutate, set it to nullptr.
73+
// @Validate: Validate if an error is a crash. Only get called if unicorn
74+
// returns an
75+
// error by default. If @AlwaysValidate is set to true, it would be
76+
// called everytime the emulation is done.
77+
// @Mutate: Mutate the input **in-place**. Note that setting this pointer to
78+
// non-null but
79+
// don't provide any implementation may have side-effects. If you would
80+
// not like to mutate, set it to nullptr.
7781
// @Cross: Combines two input to new output.
78-
// @Ranges: Specify the ranges the fuzzer is interested. Only the code within the ranges
79-
// would be intrumented. Setting this to nullptr will get all code instrumented.
82+
// @Ranges: Specify the ranges the fuzzer is interested. Only the code within
83+
// the ranges
84+
// would be intrumented. Setting this to nullptr will get all code
85+
// instrumented.
8086
// @UserData: User provided data and will be passed to callbacls.
8187
// @AlwaysValidate: see @Validate.
82-
// @ExitCode: The program (fuzzer) exit code. Should be returned as the exit code of the
88+
// @ExitCode: The program (fuzzer) exit code. Should be returned as the exit
89+
// code of the
8390
// outer program.
84-
// @CounterCount: The coverage map size. Reduce this can speedup the fuzzing but may cause
91+
// @CounterCount: The coverage map size. Reduce this can speedup the fuzzing but
92+
// may cause
8593
// more conflicts.
8694
FUZZER_INTERFACE_VISIBILITY FuzzerCornError FuzzerCornFuzz(
87-
uc_engine *Uc, int *Argc, char ***Argv, FuzzerCornPlaceInputCallback Input,
88-
FuzzerCornInitialize Init, FuzzerCornValidateCallback Validate,
89-
FuzzerCornMutatorCallback Mutate, FuzzerCornCrossOverCallback Cross,
90-
InstrumentRange *Ranges, size_t RangeCount, void *UserData,
91-
bool AlwaysValidate, int *ExitCode, size_t CounterCount);
95+
uc_engine *Uc, int *Argc, char ***Argv, uint64_t *Exits, size_t ExitCount,
96+
FuzzerCornPlaceInputCallback Input, FuzzerCornInitialize Init,
97+
FuzzerCornValidateCallback Validate, FuzzerCornMutatorCallback Mutate,
98+
FuzzerCornCrossOverCallback Cross, InstrumentRange *Ranges,
99+
size_t RangeCount, void *UserData, bool AlwaysValidate, int *ExitCode,
100+
size_t CounterCount);
92101

93102
#ifdef __cplusplus
94103
} // extern "C"

0 commit comments

Comments
 (0)