Skip to content

Commit a0162e8

Browse files
authored
Merge pull request #151 from trailofbits/take_over_rand
If you include DeepState, then rand() is actually DeepState_Int()
2 parents 54c42c7 + ead8c5c commit a0162e8

File tree

2 files changed

+104
-85
lines changed

2 files changed

+104
-85
lines changed

src/include/deepstate/DeepState.h

Lines changed: 7 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@
4848
#define assume DeepState_Assume
4949
#define check DeepState_Check
5050

51+
#define rand DeepState_Int
52+
#define srand DeepState_Warn_srand
53+
5154
#define MAYBE(...) \
5255
if (DeepState_Bool()) { \
5356
__VA_ARGS__ ; \
@@ -445,6 +448,8 @@ static bool DeepState_IsTestCaseFile(const char *name) {
445448
return false;
446449
}
447450

451+
extern void DeepState_Warn_srand(unsigned int seed);
452+
448453
/* Resets the global `DeepState_Input` buffer, then fills it with the
449454
* data found in the file `path`. */
450455
static void DeepState_InitInputFromFile(const char *path) {
@@ -603,36 +608,7 @@ DeepState_ForkAndRunTest(struct DeepState_TestInfo *test) {
603608
return DeepState_TestRunCrash;
604609
}
605610

606-
/* Run a test case with input initialized by fuzzing. */
607-
static enum DeepState_TestRunResult
608-
DeepState_FuzzOneTestCase(struct DeepState_TestInfo *test) {
609-
DeepState_InputIndex = 0;
610-
611-
for (int i = 0; i < DeepState_InputSize; i++) {
612-
DeepState_Input[i] = (char)rand();
613-
}
614-
615-
DeepState_Begin(test);
616-
617-
enum DeepState_TestRunResult result = DeepState_ForkAndRunTest(test);
618-
619-
if (result == DeepState_TestRunCrash) {
620-
DeepState_LogFormat(DeepState_LogError, "Crashed: %s", test->test_name);
621-
622-
if (HAS_FLAG_output_test_dir) {
623-
DeepState_SaveCrashingTest();
624-
}
625-
626-
DeepState_Crash();
627-
}
628-
629-
if (FLAGS_abort_on_fail && ((result == DeepState_TestRunCrash) ||
630-
(result == DeepState_TestRunFail))) {
631-
abort();
632-
}
633-
634-
return result;
635-
}
611+
extern enum DeepState_TestRunResult DeepState_FuzzOneTestCase(struct DeepState_TestInfo *test);
636612

637613
/* Run a single saved test case with input initialized from the file
638614
* `name` in directory `dir`. */
@@ -757,61 +733,7 @@ static int DeepState_RunSingleSavedTestCase(void) {
757733
return num_failed_tests;
758734
}
759735

760-
/* Fuzz test `FLAGS_input_which_test` or first test, if not defined. */
761-
static int DeepState_Fuzz(void) {
762-
DeepState_LogFormat(DeepState_LogInfo, "Starting fuzzing");
763-
764-
if (HAS_FLAG_seed) {
765-
srand(FLAGS_seed);
766-
} else {
767-
unsigned int seed = time(NULL);
768-
DeepState_LogFormat(DeepState_LogWarning, "No seed provided; using %u", seed);
769-
srand(seed);
770-
}
771-
772-
long start = (long)time(NULL);
773-
long current = (long)time(NULL);
774-
long diff = 0;
775-
unsigned i = 0;
776-
777-
int num_failed_tests = 0;
778-
779-
struct DeepState_TestInfo *test = NULL;
780-
781-
DeepState_Setup();
782-
783-
for (test = DeepState_FirstTest(); test != NULL; test = test->prev) {
784-
if (HAS_FLAG_input_which_test) {
785-
if (strncmp(FLAGS_input_which_test, test->test_name, strlen(FLAGS_input_which_test)) == 0) {
786-
break;
787-
}
788-
} else {
789-
DeepState_LogFormat(DeepState_LogInfo,
790-
"No test specified, defaulting to last test defined");
791-
break;
792-
}
793-
}
794-
795-
if (test == NULL) {
796-
DeepState_LogFormat(DeepState_LogInfo,
797-
"Could not find matching test for %s",
798-
FLAGS_input_which_test);
799-
return 0;
800-
}
801-
802-
while (diff < FLAGS_timeout) {
803-
i++;
804-
num_failed_tests += DeepState_FuzzOneTestCase(test);
805-
806-
current = (long)time(NULL);
807-
diff = current-start;
808-
}
809-
810-
DeepState_LogFormat(DeepState_LogInfo, "Ran %u tests. %d failed tests.",
811-
i, num_failed_tests);
812-
813-
return num_failed_tests;
814-
}
736+
extern int DeepState_Fuzz(void);
815737

816738
/* Run tests from `FLAGS_input_test_files_dir`, under `FLAGS_input_which_test`
817739
* or first test, if not defined. */

src/lib/DeepState.c

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@
2323
#include <setjmp.h>
2424
#include <stdio.h>
2525

26+
#undef rand
27+
#undef srand
28+
2629
DEEPSTATE_BEGIN_EXTERN_C
2730

2831
DEFINE_uint(num_workers, 1,
@@ -454,6 +457,11 @@ void DrMemFuzzFunc(volatile uint8_t *buff, size_t size) {
454457
}
455458
}
456459

460+
void DeepState_Warn_srand(unsigned int seed) {
461+
DeepState_LogFormat(DeepState_LogWarning,
462+
"srand under DeepState has no effect: rand is re-defined as DeepState_Int");
463+
}
464+
457465
void DeepState_RunSavedTakeOverCases(jmp_buf env,
458466
struct DeepState_TestInfo *test) {
459467
int num_failed_tests = 0;
@@ -630,6 +638,95 @@ bool DeepState_CatchAbandoned(void) {
630638
return DeepState_CurrentTestRun->result == DeepState_TestRunAbandon;
631639
}
632640

641+
/* Fuzz test `FLAGS_input_which_test` or first test, if not defined.
642+
Has to be defined here since we redefine rand in the header. */
643+
int DeepState_Fuzz(void){
644+
DeepState_LogFormat(DeepState_LogInfo, "Starting fuzzing");
645+
646+
if (HAS_FLAG_seed) {
647+
srand(FLAGS_seed);
648+
} else {
649+
unsigned int seed = time(NULL);
650+
DeepState_LogFormat(DeepState_LogWarning, "No seed provided; using %u", seed);
651+
srand(seed);
652+
}
653+
654+
long start = (long)time(NULL);
655+
long current = (long)time(NULL);
656+
long diff = 0;
657+
unsigned i = 0;
658+
659+
int num_failed_tests = 0;
660+
661+
struct DeepState_TestInfo *test = NULL;
662+
663+
DeepState_Setup();
664+
665+
for (test = DeepState_FirstTest(); test != NULL; test = test->prev) {
666+
if (HAS_FLAG_input_which_test) {
667+
if (strncmp(FLAGS_input_which_test, test->test_name, strlen(FLAGS_input_which_test)) == 0) {
668+
break;
669+
}
670+
} else {
671+
DeepState_LogFormat(DeepState_LogInfo,
672+
"No test specified, defaulting to last test defined");
673+
break;
674+
}
675+
}
676+
677+
if (test == NULL) {
678+
DeepState_LogFormat(DeepState_LogInfo,
679+
"Could not find matching test for %s",
680+
FLAGS_input_which_test);
681+
return 0;
682+
}
683+
684+
while (diff < FLAGS_timeout) {
685+
i++;
686+
num_failed_tests += DeepState_FuzzOneTestCase(test);
687+
688+
current = (long)time(NULL);
689+
diff = current-start;
690+
}
691+
692+
DeepState_LogFormat(DeepState_LogInfo, "Ran %u tests. %d failed tests.",
693+
i, num_failed_tests);
694+
695+
return num_failed_tests;
696+
}
697+
698+
699+
/* Run a test case with input initialized by fuzzing.
700+
Has to be defined here since we redefine rand in the header. */
701+
enum DeepState_TestRunResult DeepState_FuzzOneTestCase(struct DeepState_TestInfo *test) {
702+
DeepState_InputIndex = 0;
703+
704+
for (int i = 0; i < DeepState_InputSize; i++) {
705+
DeepState_Input[i] = (char)rand();
706+
}
707+
708+
DeepState_Begin(test);
709+
710+
enum DeepState_TestRunResult result = DeepState_ForkAndRunTest(test);
711+
712+
if (result == DeepState_TestRunCrash) {
713+
DeepState_LogFormat(DeepState_LogError, "Crashed: %s", test->test_name);
714+
715+
if (HAS_FLAG_output_test_dir) {
716+
DeepState_SaveCrashingTest();
717+
}
718+
719+
DeepState_Crash();
720+
}
721+
722+
if (FLAGS_abort_on_fail && ((result == DeepState_TestRunCrash) ||
723+
(result == DeepState_TestRunFail))) {
724+
abort();
725+
}
726+
727+
return result;
728+
}
729+
633730
extern int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
634731
if (Size > sizeof(DeepState_Input)) {
635732
return 0; // Just ignore any too-big inputs

0 commit comments

Comments
 (0)