Commit Graph

168 Commits

Author SHA1 Message Date
Andrey Konovalov
2b21a44565 prog: return error instead of panic when parsing 2017-07-24 16:37:24 +02:00
Andrey Konovalov
94f1595a77 prog: allow recursion for optional pointers
When syzkaller generates arg that uses a few structs that reference each
other via pointers, it can go into infinite recursion and crash.

Fix this by forcing pointer args to be null when the depth of recursion
reaches 3 for some struct.
2017-07-19 15:46:50 +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
Andrey Konovalov
d14bf09d4c prog: fix PtrType generation
The inner return value can't be nil, arguments are always created now.
2017-06-27 12:41:07 +02:00
Andrey Konovalov
b3ea23c379 repro: always minimize over EnableTun 2017-06-12 19:48:23 +02:00
Andrey Konovalov
4d1df73af9 csource: force enable tun flag when required 2017-06-12 19:48:23 +02:00
Dmitry Vyukov
09ec77612c prog: extend output on validation error 2017-06-06 17:21:00 +02:00
Dmitry Vyukov
46c6ed89bf pkg/ifuzz: move from ifuzz 2017-06-03 10:41:09 +02:00
Dmitry Vyukov
0fcd5fd3dd all: speed up tests
Mark tests as parallel where makes sense.
Speed up sys.TransitivelyEnabledCalls.

Execution time is now:

ok  	github.com/google/syzkaller/config		0.172s
ok  	github.com/google/syzkaller/cover		0.060s
ok  	github.com/google/syzkaller/csource		3.081s
ok  	github.com/google/syzkaller/db			0.395s
ok  	github.com/google/syzkaller/executor		0.060s
ok  	github.com/google/syzkaller/fileutil		0.106s
ok  	github.com/google/syzkaller/host		1.530s
ok  	github.com/google/syzkaller/ifuzz		0.491s
ok  	github.com/google/syzkaller/ipc			1.374s
ok  	github.com/google/syzkaller/log			0.014s
ok  	github.com/google/syzkaller/prog		2.604s
ok  	github.com/google/syzkaller/report		0.045s
ok  	github.com/google/syzkaller/symbolizer		0.062s
ok  	github.com/google/syzkaller/sys			0.365s
ok  	github.com/google/syzkaller/syz-dash		0.014s
ok  	github.com/google/syzkaller/syz-hub/state	0.427s
ok  	github.com/google/syzkaller/vm			0.052s

However, main time is still taken by rebuilding sys package.

Fixes #182
2017-05-29 13:15:07 +02:00
Dmitry Vyukov
220dc49106 csource: reproduce crashes with fault injection 2017-05-26 17:22:57 +02:00
Andrey Konovalov
96ee88d82d prog: fix buffer type with value 0x0 in tests 2017-05-26 16:35:11 +02:00
Andrey Konovalov
1813bf304a prog: remove unexpected resource generation calls whitelist
I think resource being a part of a variable length array or a union option
is an acceptable usecase.
I've started hitting this panic with some SCTP setsockopts after making
SCTP assoc_id a resource.
2017-05-26 16:24:32 +02:00
Andrey Konovalov
209dba0111 prog: better validate int and buffer types 2017-05-26 16:24:13 +02:00
Andrey Konovalov
f919224c44 sys, executor: extract tcp sequence numbers from /dev/net/tun
This commit adds a new pseudo syscall syz_extract_tcp_res, that reads
a packet from /dev/net/tun and extracts tcp sequence numbers to be used
in subsequent packets.

As a result this syzkaller program:

mmap(&(0x7f0000000000/0x10000)=nil, (0x10000), 0x3, 0x32, 0xffffffffffffffff, 0x0)
r0 = socket$inet_tcp(0x2, 0x1, 0x0)
bind$inet(r0, &(0x7f0000001000)={0x2, 0x0, @empty=0x0, [0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0]}, 0x10)
listen(r0, 0x5)
syz_emit_ethernet(0x36, &(0x7f0000002000)={@local={[0xaa, 0xaa, 0xaa, 0xaa, 0xaa], 0x0}, @random="4c6112cc15d8", [], {{0x800, @ipv4={{0x5, 0x4, 0x0, 0x0, 0x28, 0x0, 0x0, 0x0, 0x6, 0x0, @remote={0xac, 0x14, 0x0, 0xbb}, @local={0xac, 0x14, 0x0, 0xaa}, {[]}}, @tcp={{0x1, 0x0, 0x42424242, 0x42424242, 0x0, 0x0, 0x5, 0x2, 0x0, 0x0, 0x0, {[]}}, {""}}}}}})
syz_extract_tcp_res(&(0x7f0000003000)={<r1=>0x42424242, <r2=>0x42424242}, 0x1, 0x0)
syz_emit_ethernet(0x38, &(0x7f0000004000)={@local={[0xaa, 0xaa, 0xaa, 0xaa, 0xaa], 0x0}, @remote={[0xbb, 0xbb, 0xbb, 0xbb, 0xbb], 0x0}, [], {{0x800, @ipv4={{0x5, 0x4, 0x0, 0x0, 0x2a, 0x0, 0x0, 0x0, 0x6, 0x0, @remote={0xac, 0x14, 0x0, 0xbb}, @local={0xac, 0x14, 0x0, 0xaa}, {[]}}, @tcp={{0x1, 0x0, r2, r1, 0x0, 0x0, 0x5, 0x10, 0x0, 0x0, 0x0, {[]}}, {"0c10"}}}}}})
r3 = accept$inet(r0, &(0x7f0000005000)={0x0, 0x0, @multicast1=0x0, [0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0]}, &(0x7f0000006000)=0x10)

established a TCP connection:

Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 0.0.0.0:20000           0.0.0.0:*               LISTEN      5477/a.out
tcp        2      0 172.20.0.170:20000      172.20.0.187:20001      ESTABLISHED 5477/a.out

Similar program for IPv6:

mmap(&(0x7f0000000000/0x10000)=nil, (0x10000), 0x3, 0x32, 0xffffffffffffffff, 0x0)
r0 = socket$inet6_tcp(0xa, 0x1, 0x0)
bind$inet6(r0, &(0x7f0000000000)={0xa, 0x1, 0x0, @empty={[0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0]}, 0x0}, 0x1c)
listen(r0, 0x5)
syz_emit_ethernet(0x4a, &(0x7f0000001000)={@local={[0xaa, 0xaa, 0xaa, 0xaa, 0xaa], 0x0}, @random="de895db1468d", [], {{0x86dd, @ipv6={0x0, 0x6, "a228af", 0x14, 0x6, 0x0, @remote={0xfe, 0x80, [0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0], 0x0, 0xbb}, @local={0xfe, 0x80, [0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0], 0x0, 0xaa}, {[], @tcp={{0x0, 0x1, 0x42424242, 0x42424242, 0x0, 0x0, 0x5, 0x2, 0x0, 0x0, 0x0, {[]}}, {""}}}}}}})
syz_extract_tcp_res(&(0x7f0000002000)={<r1=>0x42424242, <r2=>0x42424242}, 0x1, 0x0)
syz_emit_ethernet(0x4a, &(0x7f0000003000)={@local={[0xaa, 0xaa, 0xaa, 0xaa, 0xaa], 0x0}, @random="de895db1468d", [], {{0x86dd, @ipv6={0x0, 0x6, "a228af", 0x14, 0x6, 0x0, @remote={0xfe, 0x80, [0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0], 0x0, 0xbb}, @local={0xfe, 0x80, [0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0], 0x0, 0xaa}, {[], @tcp={{0x0, 0x1, r2, r1, 0x0, 0x0, 0x5, 0x10, 0x0, 0x0, 0x0, {[]}}, {""}}}}}}})
r3 = accept$inet6(r0, &(0x7f0000004000)={0x0, 0x0, 0x0, @empty={[0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0]}, 0x0}, &(0x7f0000005000)=0x1c)

Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp6       0      0 :::20001                :::*                    LISTEN      5527/a.out
tcp6       0      0 fe80::aa:20001          fe80::bb:20000          ESTABLISHED 5527/a.out
2017-05-26 14:28:09 +02:00
Andrey Konovalov
ac0c70f74a prog, executor: move checksum computation to executor
This commit moves checksum computation to executor. This will allow to embed
dynamically generated values (like TCP sequence numbers) into packets.
2017-05-12 15:47:59 +02:00
Dmitry Vyukov
0036885d53 prog: fix dynamic prio calculation
Dynamic prio is meant to prioritize calls that
are already used together in existing programs.
The calculation used call index in the program
instead of call ID, which does not make any
sense and is a plain bug. It prioritized calls
starting from 'a' (as syscalls are sorted).

Use call ID for dynamic prio calculation.

Static prios for add_key:

1.0000	keyctl$search
1.0000	request_key
1.0000	add_key
0.5411	keyctl$assume_authority
0.5411	keyctl$setperm
0.5411	keyctl$set_timeout
0.5411	keyctl$unlink
0.5411	keyctl$revoke
0.5411	keyctl$reject
0.5411	keyctl$read
0.5411	keyctl$negate
0.5411	keyctl$link
0.5411	keyctl$join
0.5411	keyctl$invalidate
0.5411	keyctl$instantiate_iov
0.5411	keyctl$instantiate
0.5411	keyctl$get_security
0.5411	keyctl$get_persistent
0.5411	keyctl$update

Dynamic prios before fix:

0.1000	accept
0.1000	accept$alg
0.1000	accept$ax25
0.1000	accept$inet
0.1000	accept$inet6
0.1000	accept$inet_sctp
0.1000	accept$ipx
0.1000	accept$netrom
0.1000	accept$nfc_llcp
0.1000	accept$unix
0.1000	accept4
0.1000	accept4$ax25
0.1000	accept4$inet
0.1000	accept4$inet6
0.1000	accept4$inet_sctp
0.1000	accept4$ipx
0.1000	accept4$unix
0.1000	acct

Dynamic prios after fix:

0.2465	request_key
0.1142	keyctl$search
0.1000	add_key
0.1000	perf_event_open
0.0766	keyctl$invalidate
0.0717	keyctl$setperm
0.0717	keyctl$unlink
0.0717	keyctl$instantiate_iov
0.0681	keyctl$read
0.0649	keyctl$update
0.0649	keyctl$chown
0.0645	keyctl$link
0.0645	keyctl$get_security
0.0631	keyctl$revoke
0.0622	keyctl$clear
0.0622	keyctl$reject
0.0618	keyctl$set_timeout
0.0618	keyctl$negate
0.0613	keyctl$instantiate

Fixes #164
2017-05-02 12:28:48 +02:00
Dmitry Vyukov
bba1519958 prog: fix mknod sanitization
mknod mode also includes ownership flags, so filter out the node type.
Also allow creation of loop nodes.
Remove mount$fs as it does not seem to make any sense.
2017-02-14 11:56:41 +01:00
Andrey Konovalov
9989eadf77 prog: fix cheking nonoptional nil pointers in validation
Also update validation code to use arg.Type instead of passing typ recusively.
2017-02-09 21:33:14 +01:00
Andrey Konovalov
0130c7b34e prog, sys: add icmpv6 packet descriptions and checksums
Also generalize checksums into the two kinds: inet and pseudo.
Inet checksums is just the Internet checksum of a packet.
Pseudo checksum is the Internet checksum of a packet with a pseudo header.
2017-02-08 17:11:54 +01:00
Andrey Konovalov
b4bdefbe9b prog, sys: add icmp descriptions and checksum 2017-02-06 20:24:49 +01:00
Dmitry Vyukov
df41f80177 prog: reformat code 2017-02-02 20:26:43 +01:00
Andrey Konovalov
13266cc0b6 prog, sys: add udp description and checksum 2017-02-02 19:19:32 +01:00
Andrey Konovalov
97ebf05eb9 prog, sys: add ipv6 description and checksum 2017-02-02 16:30:47 +01:00
Andrey Konovalov
9e6516d4e9 prog: limit prog size when splicing 2017-02-01 16:47:44 +01:00
Andrey Konovalov
d875900eb8 prog: format checksum_test.go 2017-01-31 18:41:17 +01:00
Andrey Konovalov
1f7f5daef8 prog, sys: add tcp packets descriptions
Also embed tcp checksums into packets.
2017-01-30 21:00:45 +01:00
Andrey Konovalov
63b16a5d5c prog, sys: add csum type, embed checksums for ipv4 packets
This change adds a `csum[kind, type]` type.
The only available kind right now is `ipv4`.
Using `csum[ipv4, int16be]` in `ipv4_header` makes syzkaller calculate
and embed correct checksums into ipv4 packets.
2017-01-25 20:31:13 +01:00
Andrey Konovalov
c8d03a05f3 prog: move size-related functions to size.go 2017-01-25 16:33:37 +01: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
1cf6a05e0e sys, prog: add length of parent of parent to templates
Example:
```
struct s1 {
	f0	len[s2] # length of s2
}

struct s2 {
	f0	s1
	f1	array[int32]
}
```
2017-01-23 18:13:11 +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
Dmitry Vyukov
a7e4a49fae all: spot optimizations
A bunch of spot optmizations after cpu/memory profiling:
1. Optimize hot-path coverage comparison in fuzzer.
2. Don't allocate and copy serialized program, serialize directly into shmem.
3. Reduce allocations during parsing of output shmem (encoding/binary sucks).
4. Don't allocate and copy coverage arrays, refer directly to the shmem region
   (we are not going to mutate them).
5. Don't validate programs outside of tests, validation allocates tons of memory.
6. Replace the choose primitive with simpler switches.
   Choose allocates fullload of memory (for int, func, and everything the func refers).
7. Other minor optimizations.
2017-01-20 23:55:25 +01:00
Dmitry Vyukov
758a06c51f prog: generate larger arrays
Currently we generate arrays of size [0,5] with equal probability.
Generate [0,10] with bias towards smaller arrays. But 0 has the lowest probability.
I've benchmark a slightly different change with max array size of 20,
results are somewhat inconclusive: it was better than baseline almost all way,
but baseline suddenly caught up at the end. It also considerably reduced
executions per second (by ~20%). So increasing array size to 10 should be a win...
2017-01-20 14:56:20 +01:00
Dmitry Vyukov
c4901df5c3 prog: mutate programs more aggressively
Currently we stop mutating with 50% probability.
Stop mutating with 33% probability instead.
Benchmark shows both coverage increase and corpus reduction:

                    baseline          oneof3            diff
coverage               65467           65604             137
corpus                 35423           35354             -69
exec total           5474879         5023268         -451611
2017-01-20 14:56:20 +01:00
Dmitry Vyukov
b218a25ecb prog: mutate int arguments
Mutate int arguments instead of regenerating.
Benchmark shows strong increase of coverage:

                    baseline     mutateconst            diff
coverage               65467           65744            +277
corpus                 35423           35638            +215
exec total           5474879         5197932         -276947
2017-01-20 14:56:20 +01:00
Andrey Konovalov
243c4bf89c prog: fix bytesizeN for nonarray fields 2017-01-19 20:46:26 +01:00
Andrey Konovalov
8625843eeb prog: fix calculating parent length in struct with bitfields 2017-01-19 20:46:26 +01:00
Andrey Konovalov
872e436375 prog, sys: fix padding varlen structs 2017-01-19 15:22:04 +01:00
Dmitry Vyukov
4f62bc36e5 sys: improve sockaddr_un description
1. Embed real filename.
2. Use proc type for unique identifiers.
2017-01-18 19:58:12 +01:00
Dmitry Vyukov
10d2014b72 sys: drop kdbus description
kdbus haven't been merged into mainline, unmaintained and seems to be replaced by bus1.
2017-01-18 19:58:12 +01:00
Andrey Konovalov
a370347640 prog: add tests for alignment and offsets 2017-01-18 19:23:01 +01:00
Andrey Konovalov
8ff4256eb0 prog: fix union and struct offsets in SerializeForExec 2017-01-18 19:22:56 +01:00
Andrey Konovalov
023345d694 prog, sys: correctly calculate size of varlen structs 2017-01-18 19:16:11 +01:00
Andrey Konovalov
109c58ef68 prog: mutate sized strings with respect to size 2017-01-18 19:16:07 +01:00
Andrey Konovalov
11fa77cbbe prog, sys: fix struct with bitfields size calculation 2017-01-18 13:07:53 +01:00
Andrey Konovalov
9d963ea599 prog: fix Size() for unions args 2017-01-18 13:07:53 +01:00
Andrey Konovalov
54e0cede43 prog: add bitfields to templates
Now it's possible to use `int32:18` to denote a bitfield of size 18 as a struct field.

This fixes #72.
2017-01-17 13:25:33 +01:00
Dmitry Vyukov
ff8c0180ab sys, executor: more kvm improvements
1. Basic support for arm64 kvm testing.
2. Fix compiler warnings in x86 kvm code.
3. Test all pseudo syz calls in csource.
4. Fix handling of real code in x86.
2017-01-12 11:57:17 +01:00
Dmitry Vyukov
b8e1000d66 ifuzz: add package for generation/mutation of machine code
Add ifuzz package that can generate/mutate machine code.
It is based on Intel XED and for now supports only x86 code
(all of real, protected 16/32 and long modes).
This considerably increases KVM coverage.
2017-01-09 20:28:27 +01:00
Dmitry Vyukov
bbd4840872 sys: extend kvm support
Add new pseudo syscall syz_kvm_setup_cpu that setups VCPU into
interesting states for execution. KVM is too difficult to setup otherwise.
Lots of improvements possible, but this is a starting point.
2017-01-09 20:28:10 +01:00