Merge pull request #214 from trailofbits/readme_tweaks_and_log_level_change
Change name of `log_level` option, add libfuzzer/AFL to example in README
This commit is contained in:
commit
aabd298774
62
README.md
62
README.md
@ -290,16 +290,72 @@ CRITICAL: /Users/alex/deepstate/examples/Runlen.cpp(60): ORIGINAL: '91c499', ENC
|
|||||||
ERROR: Failed: Runlength_EncodeDecode
|
ERROR: Failed: Runlength_EncodeDecode
|
||||||
```
|
```
|
||||||
|
|
||||||
|
If you're using the DeepState docker, it's easy to also try libFuzzer
|
||||||
|
and AFL on the Runlen example:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
mkdir libfuzzer_runlen
|
||||||
|
./Runlen_LF libfuzzer_runlen -max_total_time=30
|
||||||
|
./Runlen --input_test_files_dir libfuzzer_runlen
|
||||||
|
```
|
||||||
|
|
||||||
|
And you'll see a number of failures, e.g.:
|
||||||
|
```
|
||||||
|
WARNING: No test specified, defaulting to last test defined (Runlength_EncodeDecode)
|
||||||
|
CRITICAL: /home/user/deepstate/examples/Runlen.cpp(60): ORIGINAL: '4af4aa', ENCODED: '4AaAfA4AaA', ROUNDTRIP: '4af4a'
|
||||||
|
ERROR: Failed: Runlength_EncodeDecode
|
||||||
|
ERROR: Test case libfuzzer_runlen//9e266f6cb627ce3bb7d717a6e569ade6b3633f23 failed
|
||||||
|
CRITICAL: /home/user/deepstate/examples/Runlen.cpp(60): ORIGINAL: 'aaaaaa', ENCODED: 'aA', ROUNDTRIP: 'a'
|
||||||
|
ERROR: Failed: Runlength_EncodeDecode
|
||||||
|
ERROR: Test case libfuzzer_runlen//d8fc60ccdd8f555c1858b9f0820f263e3d2b58ec failed
|
||||||
|
CRITICAL: /home/user/deepstate/examples/Runlen.cpp(60): ORIGINAL: '4aaa', ENCODED: '4AaA', ROUNDTRIP: '4a'
|
||||||
|
ERROR: Failed: Runlength_EncodeDecode
|
||||||
|
ERROR: Test case libfuzzer_runlen//3177c75208f2d35399842196dc8093243d5a8243 failed
|
||||||
|
CRITICAL: /home/user/deepstate/examples/Runlen.cpp(60): ORIGINAL: 'aaa', ENCODED: 'aA', ROUNDTRIP: 'a'
|
||||||
|
ERROR: Failed: Runlength_EncodeDecode
|
||||||
|
ERROR: Test case libfuzzer_runlen//9842926af7ca0a8cca12604f945414f07b01e13d failed
|
||||||
|
CRITICAL: /home/user/deepstate/examples/Runlen.cpp(60): ORIGINAL: 'aaa', ENCODED: 'aA', ROUNDTRIP: 'a'
|
||||||
|
ERROR: Failed: Runlength_EncodeDecode
|
||||||
|
ERROR: Test case libfuzzer_runlen//85e53271e14006f0265921d02d4d736cdc580b0b failed
|
||||||
|
CRITICAL: /home/user/deepstate/examples/Runlen.cpp(60): ORIGINAL: 'aaaaa', ENCODED: 'aA', ROUNDTRIP: 'a'
|
||||||
|
ERROR: Failed: Runlength_EncodeDecode
|
||||||
|
ERROR: Test case libfuzzer_runlen//241cbd6dfb6e53c43c73b62f9384359091dcbf56 failed
|
||||||
|
CRITICAL: /home/user/deepstate/examples/Runlen.cpp(60): ORIGINAL: 'aa', ENCODED: 'aA', ROUNDTRIP: 'a'
|
||||||
|
ERROR: Failed: Runlength_EncodeDecode
|
||||||
|
ERROR: Test case libfuzzer_runlen//05a79f06cf3f67f726dae68d18a2290f6c9a50c9 failed
|
||||||
|
CRITICAL: /home/user/deepstate/examples/Runlen.cpp(60): ORIGINAL: '25aaaa', ENCODED: '2A5AaA', ROUNDTRIP: '25a'
|
||||||
|
ERROR: Failed: Runlength_EncodeDecode
|
||||||
|
ERROR: Test case libfuzzer_runlen//419c3b754bacd6fc14ff9a932c5e2089d6dfcab5 failed
|
||||||
|
CRITICAL: /home/user/deepstate/examples/Runlen.cpp(60): ORIGINAL: 'aaaa', ENCODED: 'aA', ROUNDTRIP: 'a'
|
||||||
|
ERROR: Failed: Runlength_EncodeDecode
|
||||||
|
ERROR: Test case libfuzzer_runlen//bb589d0621e5472f470fa3425a234c74b1e202e8 failed
|
||||||
|
CRITICAL: /home/user/deepstate/examples/Runlen.cpp(60): ORIGINAL: '97aa', ENCODED: '9A7AaA', ROUNDTRIP: '97a'
|
||||||
|
ERROR: Failed: Runlength_EncodeDecode
|
||||||
|
ERROR: Test case libfuzzer_runlen//ca61c43b0e3ff0a8eccf3136996c9f1d9bfd627c failed
|
||||||
|
INFO: Ran 16 tests; 10 tests failed
|
||||||
|
```
|
||||||
|
|
||||||
|
Using AFL is similarly easy:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
mkdir afl_seeds
|
||||||
|
echo "ok" >& seeds/seed
|
||||||
|
afl-fuzz -i seeds -o afl_runlen -- ./Runlen_AFL --input_test_file @@ --no_fork --abort_on_fail
|
||||||
|
```
|
||||||
|
|
||||||
|
You'll have to stop this with Ctrl-C. The `afl_runlen/crashes`
|
||||||
|
directory will contain crashing inputs AFL found.
|
||||||
|
|
||||||
## Log Levels
|
## Log Levels
|
||||||
|
|
||||||
By default, DeepState is not very verbose about testing activity,
|
By default, DeepState is not very verbose about testing activity,
|
||||||
other than failing tests. The `--log_level` argument lowers the
|
other than failing tests. The `--min_log_level` argument lowers the
|
||||||
threshold for output, with 0 = `DEBUG`, 1 = `TRACE` (output from the
|
threshold for output, with 0 = `DEBUG`, 1 = `TRACE` (output from the
|
||||||
tests, including from `printf`), 2 = INFO (DeepState messages, the default), 3 = `WARNING`,
|
tests, including from `printf`), 2 = INFO (DeepState messages, the default), 3 = `WARNING`,
|
||||||
4 = `ERROR`, 5 = `EXTERNAL` (output from other programs such as
|
4 = `ERROR`, 5 = `EXTERNAL` (output from other programs such as
|
||||||
libFuzzer), and 6 = `CRITICAL` messages. Lowering the `log_level` can be very
|
libFuzzer), and 6 = `CRITICAL` messages. Lowering the `min_log_level` can be very
|
||||||
useful for understanding what a DeepState harness is actually doing;
|
useful for understanding what a DeepState harness is actually doing;
|
||||||
often, setting `--log_level 1` in either fuzzing or symbolic
|
often, setting `--min_log_level 1` in either fuzzing or symbolic
|
||||||
execution will give sufficient information to debug your test harness.
|
execution will give sufficient information to debug your test harness.
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -144,8 +144,8 @@ class DeepState(object):
|
|||||||
help="Verbosity level for symbolic execution tool (default: 1, lower means less output).")
|
help="Verbosity level for symbolic execution tool (default: 1, lower means less output).")
|
||||||
|
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--log_level", default=2, type=int,
|
"--min_log_level", default=2, type=int,
|
||||||
help="DeepState log level (default: 2), 0-6 (debug, trace, info, warning, error, external, critical).")
|
help="Minimum DeepState log level to print (default: 2), 0-6 (debug, trace, info, warning, error, external, critical).")
|
||||||
|
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"binary", type=str, help="Path to the test binary to run.")
|
"binary", type=str, help="Path to the test binary to run.")
|
||||||
@ -273,7 +273,7 @@ class DeepState(object):
|
|||||||
LOG_LEVEL_ERROR: logging.ERROR,
|
LOG_LEVEL_ERROR: logging.ERROR,
|
||||||
LOG_LEVEL_FATAL: logging.CRITICAL
|
LOG_LEVEL_FATAL: logging.CRITICAL
|
||||||
}
|
}
|
||||||
LOGGER.setLevel(logging_levels[args.log_level])
|
LOGGER.setLevel(logging_levels[args.min_log_level])
|
||||||
|
|
||||||
if args.output_test_dir is not None:
|
if args.output_test_dir is not None:
|
||||||
test_dir = os.path.join(args.output_test_dir,
|
test_dir = os.path.join(args.output_test_dir,
|
||||||
|
|||||||
@ -74,7 +74,7 @@ DECLARE_bool(fuzz);
|
|||||||
DECLARE_bool(fuzz_save_passing);
|
DECLARE_bool(fuzz_save_passing);
|
||||||
DECLARE_bool(fork);
|
DECLARE_bool(fork);
|
||||||
|
|
||||||
DECLARE_int(log_level);
|
DECLARE_int(min_log_level);
|
||||||
DECLARE_int(seed);
|
DECLARE_int(seed);
|
||||||
DECLARE_int(timeout);
|
DECLARE_int(timeout);
|
||||||
|
|
||||||
@ -794,8 +794,8 @@ static int DeepState_RunSingleSavedTestDir(void) {
|
|||||||
int num_failed_tests = 0;
|
int num_failed_tests = 0;
|
||||||
struct DeepState_TestInfo *test = NULL;
|
struct DeepState_TestInfo *test = NULL;
|
||||||
|
|
||||||
if (!HAS_FLAG_log_level) {
|
if (!HAS_FLAG_min_log_level) {
|
||||||
FLAGS_log_level = 2;
|
FLAGS_min_log_level = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
DeepState_Setup();
|
DeepState_Setup();
|
||||||
@ -876,8 +876,8 @@ static int DeepState_RunSavedTestCases(void) {
|
|||||||
int num_failed_tests = 0;
|
int num_failed_tests = 0;
|
||||||
struct DeepState_TestInfo *test = NULL;
|
struct DeepState_TestInfo *test = NULL;
|
||||||
|
|
||||||
if (!HAS_FLAG_log_level) {
|
if (!HAS_FLAG_min_log_level) {
|
||||||
FLAGS_log_level = 2;
|
FLAGS_min_log_level = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
DeepState_Setup();
|
DeepState_Setup();
|
||||||
|
|||||||
@ -47,7 +47,7 @@ DEFINE_bool(fuzz, false, "Perform brute force unguided fuzzing.");
|
|||||||
DEFINE_bool(fuzz_save_passing, false, "Save passing tests during fuzzing.");
|
DEFINE_bool(fuzz_save_passing, false, "Save passing tests during fuzzing.");
|
||||||
DEFINE_bool(fork, true, "Fork when running a test.");
|
DEFINE_bool(fork, true, "Fork when running a test.");
|
||||||
|
|
||||||
DEFINE_int(log_level, 0, "Minimum level of logging to output.");
|
DEFINE_int(min_log_level, 0, "Minimum level of logging to output (default 2, 0=debug, 1=trace, 2=info, ...).");
|
||||||
DEFINE_int(seed, 0, "Seed for brute force fuzzing (uses time if not set).");
|
DEFINE_int(seed, 0, "Seed for brute force fuzzing (uses time if not set).");
|
||||||
DEFINE_int(timeout, 120, "Timeout for brute force fuzzing.");
|
DEFINE_int(timeout, 120, "Timeout for brute force fuzzing.");
|
||||||
|
|
||||||
@ -739,8 +739,8 @@ bool DeepState_CatchAbandoned(void) {
|
|||||||
int DeepState_Fuzz(void){
|
int DeepState_Fuzz(void){
|
||||||
DeepState_LogFormat(DeepState_LogInfo, "Starting fuzzing");
|
DeepState_LogFormat(DeepState_LogInfo, "Starting fuzzing");
|
||||||
|
|
||||||
if (!HAS_FLAG_log_level) {
|
if (!HAS_FLAG_min_log_level) {
|
||||||
FLAGS_log_level = 2;
|
FLAGS_min_log_level = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (HAS_FLAG_seed) {
|
if (HAS_FLAG_seed) {
|
||||||
@ -853,7 +853,7 @@ extern int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
|
|||||||
|
|
||||||
const char* loud = getenv("LIBFUZZER_LOUD");
|
const char* loud = getenv("LIBFUZZER_LOUD");
|
||||||
if (loud != NULL) {
|
if (loud != NULL) {
|
||||||
FLAGS_log_level = 0;
|
FLAGS_min_log_level = 0;
|
||||||
DeepState_LibFuzzerLoud = 1;
|
DeepState_LibFuzzerLoud = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -77,7 +77,7 @@ char DeepState_LogBuf[DeepState_LogBufSize + 1] = {};
|
|||||||
DEEPSTATE_NOINLINE
|
DEEPSTATE_NOINLINE
|
||||||
void DeepState_Log(enum DeepState_LogLevel level, const char *str) {
|
void DeepState_Log(enum DeepState_LogLevel level, const char *str) {
|
||||||
if ((DeepState_UsingLibFuzzer && !DeepState_LibFuzzerLoud && (level < DeepState_LogExternal)) ||
|
if ((DeepState_UsingLibFuzzer && !DeepState_LibFuzzerLoud && (level < DeepState_LogExternal)) ||
|
||||||
(level < FLAGS_log_level)) {
|
(level < FLAGS_min_log_level)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
memset(DeepState_LogBuf, 0, DeepState_LogBufSize);
|
memset(DeepState_LogBuf, 0, DeepState_LogBufSize);
|
||||||
|
|||||||
@ -10,7 +10,7 @@ def logrun(cmd, file, timeout):
|
|||||||
sys.stderr.flush()
|
sys.stderr.flush()
|
||||||
with open(file, 'w') as outf:
|
with open(file, 'w') as outf:
|
||||||
# We need to set log_level so we see ALL messages, for testing
|
# We need to set log_level so we see ALL messages, for testing
|
||||||
p = subprocess.Popen(cmd + ["--log_level", "0"], stdout=outf, stderr=outf)
|
p = subprocess.Popen(cmd + ["--min_log_level", "0"], stdout=outf, stderr=outf)
|
||||||
start = time.time()
|
start = time.time()
|
||||||
oldContents = ""
|
oldContents = ""
|
||||||
lastOutput = time.time()
|
lastOutput = time.time()
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user