Commit Graph

35 Commits

Author SHA1 Message Date
Dmitry Vyukov
c1147c8df7 all: fix comments format
Fix capitalization, dots at the end
and two spaces after a period.

Update #1876
2020-07-12 08:22:44 +02:00
Dmitry Vyukov
e3d77cf2a3 .golangci.yml: enable godot checker
A good one. Lots of fixed comments are contributed by episodic contributors.
So it's good to catch these earlier.
2020-06-05 12:23:19 +02:00
Dmitry Vyukov
e54e9781a4 prog: remove Dir from Type
Having Dir is Type is handy, but forces us to duplicate lots of types.
E.g. if a struct is referenced as both in and out, then we need to
have 2 copies and 2 copies of structs/types it includes.
If also prevents us from having the struct type as struct identity
(because we can have up to 3 of them).

Revert to the old way we used to do it: propagate Dir as we walk
syscall arguments. This moves lots of dir passing from pkg/compiler
to prog package.
Now Arg contains the dir, so once we build the tree, we can use dirs
as before.

Reduces size of sys/linux/gen/amd64.go from 6058336 to 5661150 (-6.6%).

Update #1580
2020-05-01 13:31:17 +02:00
Dmitry Vyukov
80d43738f1 prog: rename target.SanitizeCall to Neutralize
We will need a wrapper for target.SanitizeCall that will do more
than just calling the target-provided function. To avoid confusion
and potential mistakes, give the target function and prog function
different names. Prog package will continue to call this "sanitize",
which will include target's "neutralize" + more.
Also refactor API a bit: we need a helper function that sanitizes
the whole program because that's needed most of the time.

Fixes #477
Fixes #502
2020-03-17 21:19:13 +01:00
Dmitry Vyukov
026aaeb2b5 prog: don't mutate strings with enumerated values
Strings with enumerated values are frequently file names
or have complete enumeration of relevant values.
Mutating complete enumeration if not very profitable.
Mutating file names leads to escaping paths and
fuzzer messing with things it is not supposed to mess with as in:

r0 = openat$apparmor_task_exec(0xffffffffffffff9c, &(0x7f0000000440)='/proc/self//exe\x00', 0x3, 0x0)
2020-01-05 11:46:35 +01:00
Veronica Radu
fc17ba4941 prog: add size checks for const arguments during hints mutation
Update #507
2019-10-03 10:57:55 +02:00
Dmitry Vyukov
709e893d24 prog: don't produce the same program when mutating with hints
No point in producing the same program as result of mutation with hints.
So don't do it.
2019-01-03 13:39:30 +01:00
Dmitry Vyukov
adddc5fd46 prog: remove several sources of non-determinism
Non-determinism is bad:
 - it leads to flaky coverage reports
 - it makes test failures non-reproducible

Remove 4 sources of non-determinism related to maps:
 - file name generation
 - string generation
 - resource generation
 - hints generation

All a test that ensures all main operations are fully deterministic.
2019-01-03 12:23:57 +01: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
06c33b3af0 prog: sanitize calls after hints mutation
Hints mutation could produce unsanitized calls.
Sanitize calls after hints mutation.
Also sanitize on load (in validate), because bad programs
can already be in corpuses. And it's just the right thing
to do because sanitization rules can change over time.
2018-07-12 12:40:30 +02:00
Dmitry Vyukov
1c667063a8 prog: don't generate filenames that escape sandbox
All files that fuzzer works with must be in the working dir.
Using "/" is known to cause problems when fuzzer
removes files there or mounts something.
2018-07-08 22:52:24 +02:00
Dmitry Vyukov
068da17e1f prog: dedup mutation code
Update #538
2018-05-07 14:42:22 +02:00
Dmitry Vyukov
a630fd8b41 gometalinter: some fixes for unparam
But we still can't enable it as there are more [uninteresting] warnings.

Update #538
2018-05-03 15:48:26 +02:00
Dmitry Vyukov
185ac3525e prog: support big-endian during hints matching
Use big-endian match/replace for both blobs and ints.
Sometimes we have unmarked blobs (no little/big-endian info);
for ANYBLOBs we intentionally lose all marking;
but even for marked ints we may need this too.
Consider that kernel code does not convert the data
(i.e. not ntohs(pkt->proto) == ETH_P_BATMAN),
but instead converts the constant (i.e. pkt->proto == htons(ETH_P_BATMAN)).
In such case we will see dynamic operand that does not
match what we have in the program.
2018-04-01 15:28:01 +02:00
Dmitry Vyukov
0174c6c8f7 prog: reduce nesting level in shrinkExpand 2018-03-31 18:55:59 +02:00
Dmitry Vyukov
6ceee05ad9 prog: extend a TODO about big-endian hints 2018-02-27 12:06:28 +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
c1f526e3e5 prog: mutate len fields based on hints
With the new address allocation logic,
the reason to not touch len has gone.
2018-02-19 21:48:20 +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
85d1218f41 prog: rework foreachArg
Make Foreach* callback accept the arg and a context struct
that can contain lots of aux info.
This (1) removes lots of unuser base/parent args,
(2) provides foundation for stopping recursion,
(3) allows to merge foreachSubargOffset.
2018-02-19 21:48:20 +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
b0fa969c09 prog: speedup and simplify hints code
Clone program only once.
Preallocate slices in clone.
Remove the clone full mode.
Always mutate args in place.
Allocate replacers map lazily.
Don't allocate res map at all (calculate valus on the go).
Remove sliceToUint64, pad.

benchmark          old ns/op     new ns/op     delta
BenchmarkHints     122100048     7466013       -93.89%
2017-12-08 12:27:39 +01:00
Dmitry Vyukov
5e7b20cfc3 prog: fix a data race
The race initially showed up on the new benchmark (see race report below).
The race indicated a wrong call passed to replaceArg,
as the result we sanitized the wrong call and left the new call un-sanitized.

Fix this.
Add test that exposes this.
Run benchmarks in race mode during presubmit
(benchmarks have higher chances of uncovering races than tests).

WARNING: DATA RACE
Write at 0x00c42000d3f0 by goroutine 18:
  github.com/google/syzkaller/sys/linux.(*arch).sanitizeCall()
      sys/linux/init.go:155 +0x256
  github.com/google/syzkaller/sys/linux.(*arch).(github.com/google/syzkaller/sys/linux.sanitizeCall)-fm()
      sys/linux/init.go:42 +0x4b
  github.com/google/syzkaller/prog.(*Prog).replaceArg()
      prog/prog.go:357 +0x239
  github.com/google/syzkaller/prog.generateHints.func2()
      prog/hints.go:105 +0x124
  github.com/google/syzkaller/prog.checkConstArg()
      prog/hints.go:128 +0xf3
  github.com/google/syzkaller/prog.generateHints()
      prog/hints.go:120 +0x495
  github.com/google/syzkaller/prog.(*Prog).MutateWithHints.func1()
      prog/hints.go:72 +0x67
  github.com/google/syzkaller/prog.foreachSubargImpl.func1()
      prog/analysis.go:86 +0x9f
  github.com/google/syzkaller/prog.foreachSubargImpl()
      prog/analysis.go:104 +0xc8
  github.com/google/syzkaller/prog.foreachArgArray()
      prog/analysis.go:113 +0x89
  github.com/google/syzkaller/prog.foreachArg()
      prog/analysis.go:121 +0x50
  github.com/google/syzkaller/prog.(*Prog).MutateWithHints()
      prog/hints.go:71 +0x18e
  github.com/google/syzkaller/prog.BenchmarkHints.func1()
      prog/hints_test.go:477 +0x77
  testing.(*B).RunParallel.func1()
      testing/benchmark.go:626 +0x156

Previous read at 0x00c42000d3f0 by goroutine 17:
  github.com/google/syzkaller/prog.clone()
      prog/clone.go:38 +0xbaa
  github.com/google/syzkaller/prog.(*Prog).cloneImpl()
      prog/clone.go:21 +0x17f
  github.com/google/syzkaller/prog.generateHints()
      prog/hints.go:95 +0xd0
  github.com/google/syzkaller/prog.(*Prog).MutateWithHints.func1()
      prog/hints.go:72 +0x67
  github.com/google/syzkaller/prog.foreachSubargImpl.func1()
      prog/analysis.go:86 +0x9f
  github.com/google/syzkaller/prog.foreachSubargImpl()
      prog/analysis.go:104 +0xc8
  github.com/google/syzkaller/prog.foreachArgArray()
      prog/analysis.go:113 +0x89
  github.com/google/syzkaller/prog.foreachArg()
      prog/analysis.go:121 +0x50
  github.com/google/syzkaller/prog.(*Prog).MutateWithHints()
      prog/hints.go:71 +0x18e
  github.com/google/syzkaller/prog.BenchmarkHints.func1()
      prog/hints_test.go:477 +0x77
  testing.(*B).RunParallel.func1()
      testing/benchmark.go:626 +0x156
2017-12-08 11:33:30 +01:00
Dmitry Vyukov
4016fc5ad7 prog: fix hints of data args
Hints for data args don't work.
We do all the work, but at the final stage we patch
arg in the _old_ program, not in the _new_ one.
So programs passed to the callback are all the same
and don't contain any mutations.
Tests did not catch this because they work right before that point
(don't test the actual interface function MutateWithHints).

Fix that and add a test that catches this.
2017-12-08 10:45:11 +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
8fa0c867d4 syz-fuzzer: generates hints only for the call that gave new coverage
During smashing we know what call gave new coverage,
so we can concentrate just on it.
This helps to reduce amount of hints generated (we have too many of them).
2017-10-23 09:59:39 +02:00
Dmitry Vyukov
5044885ca2 prog: add a TODO for hints 2017-10-23 09:59:39 +02:00
Dmitry Vyukov
4f9fc95501 prog: fix bugs in hints generation
Add a random hints test and fix bugs it uncovers.
2017-10-23 09:59:39 +02: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
91def5c506 prog: remove special knowledge about "mmap" syscall
Abstract "mmap" away as it can be called differently on another OS.
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
Victor Chibotaru
d9a07bf6e9 hints: add new mutations and tests 2017-09-01 17:17:08 +02:00
Victor Chibotaru
49c11eb514 ipc, prog, fuzzer, execprog: add hints generation code
A hint is basically a tuple consisting of a pointer to an argument
in one of the syscalls of a program and a value, which should be
assigned to that argument.

A simplified version of hints workflow looks like this:
    1. Fuzzer launches a program and collects all the comparisons' data
for every syscall in the program.
    2. Next it tries to match the obtained comparison operands' values
vs. the input arguments' values.
    3. For every such match the fuzzer mutates the program by
replacing the pointed argument with the saved value.
    4. If a valid program is obtained, then fuzzer launches it and
checks if new coverage is obtained.

This commit includes:
    1. All the code related to hints generation, parsing and mutations.
    2. Fuzzer functions to launch the process.
    3. Some new stats gathered by fuzzer and manager, related to hints.
    4. An updated version of execprog to test the hints process.
2017-08-30 18:40:14 +02:00
Victor Chibotaru
07c84b670b executor, ipc: modify the IO between KCOV<->executor<->fuzzer
Now executor is able to read comparisons data from KCOV and write them
to fuzzer.
2017-08-30 18:40:14 +02:00