From: George Dunlap <george.dunlap@citrix.com>
To: xen-devel@lists.xenproject.org
Cc: Ian Jackson <ian.jackson@citrix.com>,
Wei Liu <wei.liu2@citrix.com>,
George Dunlap <george.dunlap@citrix.com>,
Jan Beulich <jbeulich@suse.com>,
Andrew Cooper <andrew.cooper3@citrix.com>
Subject: [PATCH v2 10/13] fuzz/x86_emulate: Make input more compact
Date: Mon, 25 Sep 2017 15:26:45 +0100 [thread overview]
Message-ID: <20170925142648.25959-10-george.dunlap@citrix.com> (raw)
In-Reply-To: <20170925142648.25959-1-george.dunlap@citrix.com>
At the moment, AFL reckons that for any given input, 87% of it is
completely irrelevant: that is, it can change it as much as it wants
but have no impact on the result of the test; and yet it can't remove
it.
This is largely because we interpret the blob handed to us as a large
struct, including CR values, MSR values, segment registers, and a full
cpu_user_regs.
Instead, modify our interpretation to have a "set state" stanza at the
front. Begin by reading a byte; if it is lower than a certain
threshold, set some state according to what byte it is, and repeat.
Continue until the byte is above a certain threshold.
This allows AFL to compact any given test case much smaller; to the
point where now it reckons there is not a single byte of the test file
which becomes irrelevant. Testing have shown that this option both
allows AFL to reach coverage much faster, and to have a total coverage
higher than with the old format.
Make this an option (rather than a unilateral change) to enable
side-by-side performance comparison of the old and new formats.
Signed-off-by: George Dunlap <george.dunlap@citrix.com>
---
v2: Port over previous changes
CC: Ian Jackson <ian.jackson@citrix.com>
CC: Wei Liu <wei.liu2@citrix.com>
CC: Andrew Cooper <andrew.cooper3@citrix.com>
CC: Jan Beulich <jbeulich@suse.com>
---
tools/fuzz/x86_instruction_emulator/afl-harness.c | 13 +++-
tools/fuzz/x86_instruction_emulator/fuzz-emul.c | 94 ++++++++++++++++++++---
2 files changed, 97 insertions(+), 10 deletions(-)
diff --git a/tools/fuzz/x86_instruction_emulator/afl-harness.c b/tools/fuzz/x86_instruction_emulator/afl-harness.c
index 669f698711..806f54d606 100644
--- a/tools/fuzz/x86_instruction_emulator/afl-harness.c
+++ b/tools/fuzz/x86_instruction_emulator/afl-harness.c
@@ -4,6 +4,7 @@
#include <stdlib.h>
#include <string.h>
#include <getopt.h>
+#include <stdbool.h>
extern int LLVMFuzzerInitialize(int *argc, char ***argv);
extern int LLVMFuzzerTestOneInput(const uint8_t *data_p, size_t size);
@@ -12,6 +13,8 @@ extern unsigned int fuzz_minimal_input_size(void);
#define INPUT_SIZE 4096
static uint8_t input[INPUT_SIZE];
+extern bool opt_compact;
+
int main(int argc, char **argv)
{
size_t size;
@@ -22,13 +25,17 @@ int main(int argc, char **argv)
setbuf(stdin, NULL);
setbuf(stdout, NULL);
+ opt_compact = true;
+
while ( 1 )
{
enum {
OPT_MIN_SIZE,
+ OPT_COMPACT,
};
static const struct option lopts[] = {
{ "min-input-size", no_argument, NULL, OPT_MIN_SIZE },
+ { "compact", required_argument, NULL, OPT_COMPACT },
{ 0, 0, 0, 0 }
};
int c = getopt_long_only(argc, argv, "", lopts, NULL);
@@ -43,8 +50,12 @@ int main(int argc, char **argv)
exit(0);
break;
+ case OPT_COMPACT:
+ opt_compact = atoi(optarg);
+ break;
+
case '?':
- printf("Usage: %s $FILE [$FILE...] | [--min-input-size]\n", argv[0]);
+ printf("Usage: %s [--compact=0|1] $FILE [$FILE...] | [--min-input-size]\n", argv[0]);
exit(-1);
break;
diff --git a/tools/fuzz/x86_instruction_emulator/fuzz-emul.c b/tools/fuzz/x86_instruction_emulator/fuzz-emul.c
index c8a5507f8b..d99a50d12c 100644
--- a/tools/fuzz/x86_instruction_emulator/fuzz-emul.c
+++ b/tools/fuzz/x86_instruction_emulator/fuzz-emul.c
@@ -53,6 +53,15 @@ struct fuzz_state
};
#define DATA_OFFSET offsetof(struct fuzz_state, corpus)
+bool opt_compact;
+
+unsigned int fuzz_minimal_input_size(void)
+{
+ if ( opt_compact )
+ return sizeof(unsigned long) + 1;
+ else
+ return DATA_OFFSET + 1;
+}
static inline bool input_available(struct fuzz_state *s, size_t size)
{
@@ -647,9 +656,81 @@ static void setup_state(struct x86_emulate_ctxt *ctxt)
{
struct fuzz_state *s = ctxt->data;
- /* Fuzz all of the state in one go */
- if (!input_read(s, s, DATA_OFFSET))
- exit(-1);
+ if ( !opt_compact )
+ {
+ /* Fuzz all of the state in one go */
+ if (!input_read(s, s, DATA_OFFSET))
+ exit(-1);
+ return;
+ }
+
+ /* Modify only select bits of state */
+
+ /* Always read 'options' */
+ if ( !input_read(s, &s->options, sizeof(s->options)) )
+ return;
+
+ while(1) {
+ uint16_t offset;
+
+ /* Read 16 bits to decide what bit of state to modify */
+ if ( !input_read(s, &offset, sizeof(offset)) )
+ return;
+
+ /*
+ * Then decide if it's "pointing to" different bits of the
+ * state
+ */
+
+ /* cr[]? */
+ if ( offset < 5 )
+ {
+ if ( !input_read(s, s->cr + offset, sizeof(*s->cr)) )
+ return;
+ printf("Setting CR %d to %lx\n", offset, s->cr[offset]);
+ continue;
+ }
+
+ offset -= 5;
+
+ /* msr[]? */
+ if ( offset < MSR_INDEX_MAX )
+ {
+ if ( !input_read(s, s->msr + offset, sizeof(*s->msr)) )
+ return;
+ printf("Setting MSR i%d (%x) to %lx\n", offset,
+ msr_index[offset], s->msr[offset]);
+ continue;
+ }
+
+ offset -= MSR_INDEX_MAX;
+
+ /* segments[]? */
+ if ( offset < SEG_NUM )
+ {
+ if ( !input_read(s, s->segments + offset, sizeof(*s->segments)) )
+ return;
+ printf("Setting Segment %d\n", offset);
+ continue;
+
+ }
+
+ offset -= SEG_NUM;
+
+ /* regs? */
+ if ( offset < sizeof(struct cpu_user_regs)
+ && offset + sizeof(uint64_t) <= sizeof(struct cpu_user_regs) )
+ {
+ if ( !input_read(s, ((char *)ctxt->regs) + offset, sizeof(uint64_t)) )
+ return;
+ printf("Setting cpu_user_regs offset %x\n", offset);
+ continue;
+ }
+
+ /* None of the above -- take that as "start emulating" */
+
+ return;
+ }
}
#define CANONICALIZE(x) \
@@ -821,7 +902,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data_p, size_t size)
/* Reset all global state variables */
memset(&input, 0, sizeof(input));
- if ( size <= DATA_OFFSET )
+ if ( size < fuzz_minimal_input_size() )
{
printf("Input too small\n");
return 1;
@@ -858,11 +939,6 @@ int LLVMFuzzerTestOneInput(const uint8_t *data_p, size_t size)
return 0;
}
-unsigned int fuzz_minimal_input_size(void)
-{
- return DATA_OFFSET + 1;
-}
-
/*
* Local variables:
* mode: C
--
2.14.1
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel
next prev parent reply other threads:[~2017-09-25 14:27 UTC|newest]
Thread overview: 56+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-09-25 14:26 [PATCH v2 01/13] x86emul/fuzz: add rudimentary limit checking George Dunlap
2017-09-25 14:26 ` [PATCH v2 02/13] fuzz/x86_emulate: Actually use cpu_regs input George Dunlap
2017-10-04 8:21 ` Jan Beulich
2017-09-25 14:26 ` [PATCH v2 03/13] fuzz/x86_emulate: Clear errors after each iteration George Dunlap
2017-10-04 8:22 ` Jan Beulich
2017-09-25 14:26 ` [PATCH v2 04/13] fuzz/x86_emulate: Improve failure descriptions in x86_emulate harness George Dunlap
2017-10-04 8:22 ` Jan Beulich
2017-09-25 14:26 ` [PATCH v2 05/13] fuzz/x86_emulate: Implement input_read() and input_avail() George Dunlap
2017-10-04 8:22 ` Jan Beulich
2017-10-04 16:23 ` George Dunlap
2017-09-25 14:26 ` [PATCH v2 06/13] fuzz/x86_emulate: Rename the file containing the wrapper code George Dunlap
2017-10-04 8:23 ` Jan Beulich
2017-10-04 16:34 ` George Dunlap
2017-10-05 9:01 ` Jan Beulich
2017-10-05 13:50 ` George Dunlap
2017-09-25 14:26 ` [PATCH v2 07/13] fuzz/x86_emulate: Add 'afl-cov' target George Dunlap
2017-10-04 8:23 ` Jan Beulich
2017-10-04 16:48 ` George Dunlap
2017-10-05 9:06 ` Jan Beulich
2017-09-25 14:26 ` [PATCH v2 08/13] fuzz/x86_emulate: Take multiple test files for inputs George Dunlap
2017-10-04 8:24 ` Jan Beulich
2017-10-04 16:58 ` George Dunlap
2017-10-05 9:08 ` Jan Beulich
2017-09-25 14:26 ` [PATCH v2 09/13] fuzz/x86_emulate: Move all state into fuzz_state George Dunlap
2017-10-04 8:25 ` Jan Beulich
2017-10-04 16:51 ` George Dunlap
2017-09-25 14:26 ` George Dunlap [this message]
2017-10-04 8:26 ` [PATCH v2 10/13] fuzz/x86_emulate: Make input more compact Jan Beulich
2017-10-05 15:04 ` George Dunlap
2017-10-05 15:37 ` Jan Beulich
2017-09-25 14:26 ` [PATCH v2 11/13] fuzz/x86_emulate: Add --rerun option to try to track down instability George Dunlap
2017-10-04 8:27 ` Jan Beulich
2017-10-05 16:12 ` George Dunlap
2017-10-06 5:53 ` Jan Beulich
2017-09-25 14:26 ` [PATCH v2 12/13] fuzz/x86_emulate: Set and fuzz more CPU state George Dunlap
2017-10-04 8:28 ` Jan Beulich
2017-10-05 17:08 ` George Dunlap
2017-10-06 6:10 ` Jan Beulich
2017-10-06 10:53 ` George Dunlap
2017-10-06 9:57 ` Jan Beulich
2017-10-06 10:50 ` George Dunlap
2017-10-06 11:53 ` Jan Beulich
2017-10-06 11:56 ` Jan Beulich
2017-10-10 15:45 ` George Dunlap
2017-09-25 14:26 ` [PATCH v2 13/13] fuzz/x86_emulate: Add an option to limit the number of instructions executed George Dunlap
2017-10-04 8:28 ` Jan Beulich
2017-10-06 10:40 ` George Dunlap
2017-10-06 12:12 ` Jan Beulich
2017-10-06 13:02 ` George Dunlap
2017-10-06 15:21 ` [PATCH v2 01/13] x86emul/fuzz: add rudimentary limit checking George Dunlap
2017-10-06 15:54 ` Jan Beulich
2017-10-06 17:06 ` George Dunlap
2017-10-09 7:17 ` Jan Beulich
2017-10-09 12:54 ` Andrew Cooper
2017-10-09 13:26 ` Jan Beulich
2017-10-09 13:35 ` Andrew Cooper
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20170925142648.25959-10-george.dunlap@citrix.com \
--to=george.dunlap@citrix.com \
--cc=andrew.cooper3@citrix.com \
--cc=ian.jackson@citrix.com \
--cc=jbeulich@suse.com \
--cc=wei.liu2@citrix.com \
--cc=xen-devel@lists.xenproject.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).