Commit Graph

63 Commits

Author SHA1 Message Date
Dmitry Vyukov
93dcf0adc8 prog: implement complex len target support
This actually implements support for complex len targets
during program generation and mutation.
2019-05-14 19:28:01 +02:00
Dmitry Vyukov
c35ee0ea6d prog, pkg/compiler: fix warnings
gometalinter says:

pkg/compiler/consts.go:192:⚠️ internal error: no range for "n" (vetshadow)
pkg/compiler/consts.go:197:⚠️ internal error: no range for "n" (vetshadow)
prog/encoding.go:862:⚠️ declaration of "v" shadows declaration at prog/encoding.go:852 (vetshadow)

This somehow happens only with Go1.11 but not 1.12 so wasn't detected locally.
The prog warnings looks legit.
The pkg/compiler warning was amusingly introduced to please golangci-lint checker,
revert that fix for now.
2019-03-29 19:04:30 +01:00
Dmitry Vyukov
c84501fe70 prog: fix a bunch of bugs in parsing
Add fuzzer for Deserialize and fix 5 or so bugs it found.

Fixes #1086
2019-03-29 08:56:02 +01:00
Dmitry Vyukov
8e579f27d6 prog: fix escaping of C strings
C's \xHH hex constants in strings accept any number of hex digits
(not just 2 or 4). So later non-hex escaped chars glue to the \x construct.
Use \OOO instead as it accepts at most 3 octal digits.
2019-01-31 11:35:53 +01:00
Dmitry Vyukov
def91db3fe prog, pkg/csource: more readable serialization for strings
Always serialize strings in readable format (non-hex).
Serialize binary data in readable format in more cases.

Fixes #792
2018-12-15 15:17:13 +01:00
Dmitry Vyukov
28bd3e371b prog: support AUTO args in programs
AUTO arguments can be used for:
 - consts
 - lens
 - pointers

For const's and len's AUTO is replaced with the natural value,
addresses for AUTO pointers are allocated linearly.

This greatly simplifies writing test programs by hand
as most of the time we want these natural values.

Update tests to use AUTO.
2018-12-10 16:37:02 +01:00
Dmitry Vyukov
ba64d006de prog: implement strict parsing mode
Add bulk of checks for strict parsing mode.
Probably not complete, but we can extend then in future as needed.
Turns out we can't easily use it for serialized programs
as they omit default args and during deserialization it looks like missing args.
2018-12-10 16:37:01 +01:00
Dmitry Vyukov
95fe19c19e prog: introduce strict parsing mode
Over time we relaxed parsing to handle all kinds of invalid programs
(excessive/missing args, wrong types, etc).
This is useful when reading old programs from corpus.
But this is harmful for e.g. reading test inputs as they can become arbitrary outdated.
For runtests which creates additional problem of executing not
what is actually written in the test (or at least what author meant).
Add strict parsing mode that does not tolerate any errors.
For now it just checks excessive syscall arguments.
2018-12-10 16:37:01 +01:00
Dmitry Vyukov
a5efea3ec3 prog: refactor deserialization code
Move target and vars into parser and make all
parsing functions methods of the parser.
This reduces number of args that we need to pass around
and eases adding more state that needs to be passed around.
2018-12-10 16:37:01 +01:00
Dmitry Vyukov
ceaec61a83 prog: export Type.DefaultArg
It's effectively exported anyway.
So export it the proper way.
2018-12-06 18:55:46 +01:00
Dmitry Vyukov
e8dd2c6713 prog: add concept of "special pointers"
Currently we only generate either valid user-space pointers or NULL.
Extend NULL to a set of special pointers that we will use in programs.
All targets now contain 3 special values:
 - NULL
 - 0xfffffffffffffff (invalid kernel pointer)
 - 0x999999999999999 (non-canonical address)
Each target can add additional special pointers on top of this.

Also generate NULL/special pointers for non-opt ptr's.
This restriction was always too restrictive. We may want to generate
them with very low probability, but we do want to generate them.

Also change pointers to NULL/special during mutation
(but still not in the opposite direction).
2018-08-30 21:45:03 -07:00
Dmitry Vyukov
c00da3df66 prog: collect all prog comments
Parse and collect and prog comments.
Will be needed for runtest annotations
(e.g. "requires threaded mode", etc).
2018-08-08 13:07:49 +02:00
Dmitry Vyukov
1da82ae0f0 prog: introduce debugValidate
Move debug validation into a separate function.

Update #538
2018-08-02 16:57:31 +02:00
Dmitry Vyukov
c8643744fe prog: refactor defaultArg/isDefaultArg
Refactor from single-big-switch to type methods.

Update #538
2018-08-02 16:57:31 +02:00
Dmitry Vyukov
97bce4e2ce prog: refactor program serialization
Make argument serialization Arg method.
This eliminates a very long function
that serializes all arguments.

Update #538
2018-07-31 18:43:50 +02:00
Dmitry Vyukov
68faa52582 prog: parse comments in serialized programs
Remember per-call comments, will be useful for annotating tests.
Also support this form:
call() # comment
2018-07-27 10:22:23 +02:00
Dmitry Vyukov
afe402d20a prog: make c.Ret optional
No reason to allocate return value if there is no return type.
c.Ret == nil is the reasonable indication that this is a "void" call.
2018-05-05 10:25:45 +02:00
Dmitry Vyukov
9dfb5efa91 prog: simplify code
Now that we don't have ReturnArg and only ResultArg's refer
to other ResultArg's we can remove ArgUser/ArgUsed and
devirtualize lots of code.
2018-05-05 10:13:04 +02:00
Dmitry Vyukov
2c7e14a847 gometalinter: enable cyclomatic complexity checking
Refactor some functions to be simpler.

Update #538
2018-05-04 18:03:46 +02:00
Dmitry Vyukov
7c923cf8d4 sys/linux: add support for mounting filesystem images 2018-03-30 19:51:27 +02:00
Dmitry Vyukov
36d1c4540a all: fix gometalinter warnings
Fix typos, non-canonical code, remove dead code, etc.
2018-03-08 18:48:26 +01:00
Dmitry Vyukov
d0790618dc prog: fix isDefaultArg
Test that isDefaultArg returns true for result of DefaultArg.
Fix few bugs uncovered by this test.
2018-03-08 12:02:17 +01:00
Dmitry Vyukov
70a1ddb939 prog: harden program parsing against description changes more
Handle most of type changes, e.g. const is changed to struct,
or struct to pointers. In all these cases we create default args.
They may not give the coverage anymore, but still better than
losing them right away.
2018-03-05 12:10:27 +01:00
Dmitry Vyukov
bd5df8f49b prog: handle excessive args and fields during program parsing
Tolerate excessive args and fields during program parsing.
This is useful after description changes to not lose corpus.
2018-03-05 12:10:27 +01:00
Dmitry Vyukov
e28ba02d9d prog: harden program parsing
This fixes crash during parsing of existing programs in corpus
after vma<->ptr type change in descriptions.
2018-03-05 12:10:27 +01:00
Dmitry Vyukov
d1322dff4c prog: remove stale TODOs 2018-02-26 17:46:44 +01:00
Dmitry Vyukov
b37b65b0e6 sys/linux: remove proc type from network descriptions
We now always create net namespace for testing,
so socket ports and other IDs do not overlap between
different test processes.
Proc types play badly with squashing packets to ANYBLOB.
To squash into a block we need concrete value, but it depends
on process id.
Removing proc also makes tun setup and address descriptions simpler.
2018-02-26 16:48:31 +01:00
Dmitry Vyukov
9fe8aa42c5 prog: add arbitrary mutation of complex structs
Squash complex structs into flat byte array and mutate this array
with generic blob mutations. This allows to mutate what we currently
consider as paddings and add/remove paddings from structs, etc.
2018-02-25 18:22:02 +01:00
Dmitry Vyukov
3be86de046 sys/linux: prevent programs from doing arbitrary writes with ARCH_SET_FS 2018-02-23 11:55:37 +01:00
Dmitry Vyukov
75a7c5e2d1 prog: rework address allocation
1. mmap all memory always, without explicit mmap calls in the program.
This makes lots of things much easier and removes lots of code.
Makes mmap not a special syscall and allows to fuzz without mmap enabled.

2. Change address assignment algorithm.
Current algorithm allocates unmapped addresses too frequently
and allows collisions between arguments of a single syscall.
The new algorithm analyzes actual allocations in the program
and places new arguments at unused locations.
2018-02-19 21:48:20 +01:00
Dmitry Vyukov
d973f28294 prog: don't serialize default arguments
This reduces size of a corpus in half.
We store corpus on manager and on hub,
so this will reduce their memory consumption.
But also makes large programs more readable.
2018-02-01 15:20:12 +01:00
Dmitry Vyukov
5d7477249b prog: remove unused UnionArg.OptionType 2018-01-27 17:08:43 +01:00
Dmitry Vyukov
0019344752 prog: detect argument type mismatch during deserialization 2017-12-31 12:49:20 +01:00
Dmitry Vyukov
dcfdc02b77 prog: minor refactoring around arguments
Introduce isUsed(arg) helper, use it in several places.
Move method definitions closer to their types.
Simplify presence check for ArgUsed.Used() in several places.
2017-12-17 11:39:14 +01:00
Dmitry Vyukov
8ef0050706 prog: don't serialize output data args
Fixes #188

We now will write just ""/1000 to denote a 1000-byte output buffer.
Also we now don't store 1000-byte buffer in memory just to denote size.
Old format is still parsed.
2017-12-17 11:39:14 +01:00
Dmitry Vyukov
41799debdc prog: introduce more readable format for data args
Fixes #460

File names, crypto algorithm names, etc in programs are completely unreadable:

bind$alg(r0, &(0x7f0000408000)={0x26, "6861736800000000000000000000",
0x0, 0x0, "6d6435000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000
00000000000"}, 0x58)

Introduce another format for printable strings.
New args are denoted by '' ("" for old args).
New format is enabled for printable chars, \x00
and \t, \r, \n.

Example:
`serialize(&(0x7f0000408000)={"6861736800000000000000000000", "4849000000"})`,
vs:
`serialize(&(0x7f0000408000)={'hash\x00', 'HI\x00'})`,
2017-12-17 11:39:14 +01:00
Dmitry Vyukov
1808de66ce prog: repair arrays/buffers with incorrect size in Deserialize
For string[N] we successfully deserialize a string of any length.
Similarly for a fixed-size array[T, N] we successfully deserialize
an array of any size.
Such programs later crash in foreachSubargOffset because static size
Type.Size() does not match what we've calculated iterating over fields.
The crash happens only in SerializeForExec in syz-fuzzer,
which is especially bad.
Fix this from both sides:
1. Validate sizes of arrays/buffers in Validate.
2. Repair incorrect sizes in Deserialize.
2017-11-28 19:15:28 +01:00
Dmitry Vyukov
7e076b78b4 prog: export MakeData/UnionArg as we do for other arg types
Target code can use these to generate special structs.
2017-11-22 11:46:26 +01:00
Dmitry Vyukov
52a33fd516 prog: remove default target and all global state
Now each prog function accepts the desired target explicitly.
No global, implicit state involved.
This is much cleaner and allows cross-OS/arch testing, etc.
2017-09-15 16:02:37 +02:00
Dmitry Vyukov
ffe7e17368 prog, sys: move types to prog
Large overhaul moves syscalls and arg types from sys to prog.
Sys package now depends on prog and contains only generated
descriptions of syscalls.
Introduce prog.Target type that encapsulates all targer properties,
like syscall list, ptr/page size, etc. Also moves OS-dependent pieces
like mmap call generation from prog to sys.

Update #191
2017-09-05 15:52:42 +02:00
Dmitry Vyukov
4fc4702694 prog: dot-import sys
In preparation for moving sys types to prog to reduce later diffs.
2017-09-05 10:46:34 +02:00
Dmitry Vyukov
5db39ab953 sys: rename Call to Syscall
In preparation for moving sys types to prog
to avoid confusion between sys.Call and prog.Call.
2017-09-05 10:38:22 +02:00
Dmitry Vyukov
399addc875 sys, pkg/compiler: move padding computation to compiler
This makes types constant during execution, everything is precomputed.
2017-09-04 20:25:23 +02:00
Dmitry Vyukov
9ec49e082f prog: restore missing struct fields
We already do this for syscall arguments.
Helps to save some old programs after description changes.
2017-08-25 21:56:07 +02:00
Dmitry Vyukov
838e336594 sys, prog: switch values to to uint64
We currently use uintptr for all values.
This won't work for 32-bit archs.
Moreover in some cases we use uintptr but assume
that it is always 64-bits (e.g. in encodingexec).
Switch everything to uint64.

Update #324
2017-08-19 10:16:23 +02:00
Andrey Konovalov
1517bd9548 prog: generate missing syscall args when decoding
After a change in syscall description the number of syscall arguments
might change and some of the programs in corpus get invalidated.

This change makes syzkaller to generate missing arguments when decoding a
program as an attempt to fix and keep more programs from corpus.
2017-08-01 19:19:05 +02:00
Andrey Konovalov
2b21a44565 prog: return error instead of panic when parsing 2017-07-24 16:37:24 +02:00
Andrey Konovalov
cfc46d9d0b prog: split Arg into smaller structs
Right now Arg is a huge struct (160 bytes), which has many different fields
used for different arg kinds. Since most of the args we see in a typical
corpus are ArgConst, this results in a significant memory overuse.

This change:
- makes Arg an interface instead of a struct
- adds a SomethingArg struct for each arg kind we have
- converts all *Arg pointers into just Arg, since interface variable by
  itself contains a pointer to the actual data
- removes ArgPageSize, now ConstArg is used instead
- consolidates correspondence between arg kinds and types, see comments
  before each SomethingArg struct definition
- now LenType args that denote the length of VmaType args are serialized as
  "0x1000" instead of "(0x1000)"; to preserve backwards compatibility
  syzkaller is able to parse the old format for now
- multiple small changes all over to make the above work

After this change syzkaller uses twice less memory after deserializing a
typical corpus.
2017-07-17 14:34:09 +02:00
Dmitry Vyukov
40723a067e prog: validate deserialized programs
The optimization change removed validation too aggressively.
We do need program validation during deserialization,
because we can get bad programs from corpus or hub.
Restore program validation after deserialization.
2017-01-24 10:53:21 +01:00
Andrey Konovalov
b323c5aaa9 prog: add FieldName to Type
FieldName() is the name of the struct field or union option with this type.
TypeName() is now always the name of the type.
2017-01-23 18:13:06 +01:00