When we build a list of resource constructors we over and over iterate through
all types in a syscall to find resource types. Speed it up by iterating only
once to build a list of constructors for each resource and then reuse it.
This significantly speeds up syz-exeprog startup time on Raspberry Pi Zero.
If we deserialized a huge blob (larger than max blob size),
then we can get a negative size in the "Insert random bytes" case at:
if r := int(maxLen) - len(data); n > r {
n = r
}
Don't insert bytes if data is already larger than maxLen.
Default value for ProcType is 0 (same for all PID's).
Usually 0 either does not make sense at all or make different PIDs collide
(since we use ProcType to separate value ranges for different PIDs).
So don't change ProcType to 0 unless the type is explicitly marked as opt
(in that case we will also generate 0 anyway).
Fix several nasty bugs in minimization that could lead
to almost arbitrary results. These bugs affected both
crash minimization and corpus population.
Extend the randomized test to catch these bugs.
Add additional asserts to code to catch similar bugs in future.
Reported-by @xairy
Providing additional info, especially regarding syscall arguments, in reproducers
can be helpful. An example is device numbers passed to mknod(2).
This commit introduces an optional annotate function on a per target basis.
Example for the OpenBSD target:
$ cat prog.in
mknod(0x0, 0x0, 0x4503)
getpid()
$ syz-prog2c -prog prog.in
int main(void)
{
syscall(SYS_mmap, 0x20000000, 0x1000000, 3, 0x1012, -1, 0, 0);
syscall(SYS_mknod, 0, 0, 0x4503); /* major = 69, minor = 3 */
syscall(SYS_getpid);
return 0;
}
We may be in createResource but have no resources at all because of ANYRES
that are not in target.Resources.
This is actually the case for some test targets. We have resources there,
but syscalls that create them are disabled.
In such case we crash in Intn(0).
Check that we have some resources before calling Intn.
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.
Differences in code formatting between Go versions cause constant
problems for us (https://github.com/golang/go/issues/25161).
Currently we support 1.9 and 1.10. Switch to newer 1.11 and 1.12.
Fixes#1013
Make pseudo checksums depend (via csumUses) on the arg it requires for
calculation. Otherwise we fail to assign addrs to those args during encoding
for execution. Also add a test.
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.
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.
We don't specify trailing unused args for some syscalls
(e.g. ioctl that does not use its arg).
Executor always filled tailing unsed args with 0's
but pkg/csource didn't. Some such syscalls actually
check that the unsed arg is 0 and as the result failed with C repro.
We could statically check and eliminate all such cases,
but it turns out the warning fires in 1500+ cases:
a3ace5a63f/gistfile1.txt
So instead fill such args with 0's in pkg/csource too.
Without this check programs may end up panicing in places far away
from the real cause. E.g.
worker# ./syz-fuzzer -executor=./syz-executor -name=vm-0 -arch=amd64 -manager=10.128.0.101:21386 -sandbox=setuid -procs=2 -v=0 -cover=true -debug=false -test=false
2004/02/03 12:11:11 fuzzer started
2004/02/03 12:11:11 dialing manager at 10.128.0.101:21386
2004/02/03 12:11:12 syscalls: 1
2004/02/03 12:11:12 code coverage: enabled
2004/02/03 12:11:12 comparison tracing: support is not implemented in syzkaller
2004/02/03 12:11:12 setuid sandbox: support is not implemented in syzkaller
2004/02/03 12:11:12 namespace sandbox: support is not implemented in syzkaller
2004/02/03 12:11:12 Android sandbox: support is not implemented in syzkaller
2004/02/03 12:11:12 fault injection: support is not implemented in syzkaller
2004/02/03 12:11:12 leak checking: support is not implemented in syzkaller
2004/02/03 12:11:12 net packet injection: enabled
2004/02/03 12:11:12 net device setup: support is not implemented in syzkaller
panic: invalid argument to Intn
goroutine 27 [running]:
math/rand.(*Rand).Intn(0xc000dff530, 0x0, 0x40)
/usr/local/go/src/math/rand/rand.go:169 +0x9c
github.com/google/syzkaller/prog.(*ChoiceTable).Choose(0xc000d92ec0, 0xc000dff530, 0xffffffffffffffff, 0xc000dff650)
/syzkaller/gopath/src/github.com/google/syzkaller/prog/prio.go:241 +0x1a0
github.com/google/syzkaller/prog.(*randGen).generateCall(0xc000e145a0, 0xc000c2a200, 0xc000ce7f80, 0x2348f1940, 0xc000ce3440, 0xc000e6ee01)
/syzkaller/gopath/src/github.com/google/syzkaller/prog/rand.go:451 +0x69
github.com/google/syzkaller/prog.(*Target).Generate(0xc00007f1e0, 0x8f8680, 0xc000ce3440, 0x1e, 0xc000d92ec0, 0x0)
/syzkaller/gopath/src/github.com/google/syzkaller/prog/generation.go:19 +0x2b2
main.(*Proc).loop(0xc000d92f40)
/syzkaller/gopath/src/github.com/google/syzkaller/syz-fuzzer/proc.go:93 +0x2a1
created by main.main
/syzkaller/gopath/src/github.com/google/syzkaller/syz-fuzzer/fuzzer.go:236 +0xfe2
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.
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.
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.
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.
There are 2 bugs:
1. We always allocate 1 page, even if use more.
2. VMA addresses are not aligned, so most mmap-like functions fail with EINVAL.
The added test currently panics with "unaligned vma address".