The new pseudo syscall allows opening sockets that can only
be created in init net namespace (BLUETOOTH, NFC, LLC).
Use it to open these sockets.
Unfortunately this only works with sandbox none at the moment.
The problem is that setns of a network namespace requires CAP_SYS_ADMIN
in the target namespace, and we've lost all privs in the init namespace
during creation of a user namespace.
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.
1. Add size attribte on sockaddr.
2. Remove sockaddr's that are larger than 16 bytes from sockaddr.
3. Add size attribute on sockaddr_storage which wasn't actually 128 bytes.
4. Add size attribute to ifreq.
5. Fix ifmap field types as uncovered by the size attributes.
6. Fix sockaddr_storage_tcp from struct to union which is should be.
7. Make sockaddr_un_file fixed size as it should be.
8. Fix some explicit paddings that were only correct for 64 bits.
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.
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.
Fix alignemnt calculation for packed structs with alignment and bitfields.
Amusingly this affected only a single real struct -- ipv6_fragment_ext_header.
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.
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.
Put the underflow entry at the end.
Entries must end on an unconditional, non-goto entry,
otherwise fallthrough from the last entry is invalid.
Add arp tables support.
Split unspec matches/targets to unspec and inet.
Reset ipv6 and arp tables in executor.
Fix number of counters in tables.
Plus a bunch of assorted fixes for matches/targets.
We currently print unsupported consts to console during make extract.
But this is not very useful as there are too many output now.
This also does not allow to understand what's unsupported
in newly checked-in descriptions, or what's unsupported in all current
decriptions.
Save unsupported consts to the const files instead.
This solves all of the above problems.
Unions with only 1 field are not actually unions,
and can always be replaced with the option type.
However, they are still useful when there will be
more options in future but currently only 1 is described.
Alternatives are:
- not using union (but then all existing programs will be
broken when union is finally introduced)
- adding a fake field (ugly and reduces fuzzer efficiency)
Allow unions with only 1 field.
Consider the following example:
type len_templ1[DATA1, DATA2] {
data DATA1
inner len_temp2[DATA2]
}
type len_temp2[DATA] {
data DATA
len len[len_templ1, int8]
}
Here len refers to a parent struct, but the struct is a template,
so it's actual name is something like "len_templ1[int8, int16]".
Currently this does not work as compiler barks at incorrect
len target.
Make this work.
mknod$loop contains proc type as dev number.
Current sanitization code truncates 64-bit -1 to 32-bits
which later causes validation failure.
Don't do that, it's unnecessary for proc type.
We test in a new network namespace, which does not have any
devices set up (even lo). Create/up as many devices as possible.
Give them some addresses and use these addresses in descriptions.
Netlink descriptions contain tons of code duplication,
and need much more for proper descriptions. Introduce
type templates to simplify writing such descriptions
and remove code duplication.
Note: type templates are experimental, have poor error handling
and are subject to change.
Type templates can be declared as follows:
```
type buffer[DIR] ptr[DIR, array[int8]]
type fileoff[BASE] BASE
type nlattr[TYPE, PAYLOAD] {
nla_len len[parent, int16]
nla_type const[TYPE, int16]
payload PAYLOAD
} [align_4]
```
and later used as follows:
```
syscall(a buffer[in], b fileoff[int64], c ptr[in, nlattr[FOO, int32]])
```
Arm was broken on upstream kernel for some time
due to some assembler error. Now it seems to be fixed,
so regenerate consts.
Also fix small issues in new netlink descriptions.
open is not present on arm64, only openat.
accept is not present on 386, only accept4.
Duplicate all open/accept specializations with
corresponding openat/accept4 specializations
to enable testing on 386/arm64.
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.
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'})`,
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.
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.
KEYCTL_DH_COMPUTE used the old fixed list of algorithm names.
Use the new code for algorithm generation.
+ it needs only SHASH algs, but we passed in all alg names.
Pass only SHASH algs.
There is effectively infinite number of possible crypto
algorithm names due to templates. Plus there is tricky
relation between algorithms and algorithm type names.
This change adds custom mutator for sockaddr_alg struct
to improve variance in generated algorithms.
When manager is stopped there are sometimes runaway qemu
processes still running. Set PDEATHSIG for all subprocesses.
We never need child processes outliving parents.
commit 3520854be0 ("syz-extract: select declaring printf or not")
broke 'make extract' because it introduced invalid syntax in a text
template. Fix it.
Kernels are standalone implementations and can have their own
implementations of functions that have different prototypes than
the standard ones. In the NetBSD case the kernel printf returns
void, and it is declared in <sys/systm.h> so avoid re-declaring it.
Select if we are going to declare printf or not depending on the OS.
Add a definition for keyctl_dh_compute(), which was added in the v4.7
kernel, then in the v4.12 kernel extended to take in an optional
'keyctl_kdf_params' argument. (Requires CONFIG_KEY_DH_OPERATIONS=y.)
Many functions in the keys API take in an ID parameter that is expected
to refer to a keyring, not to any key. Therefore, define a resource
subtype 'keyring' which can be created by add_key("keyring", ...) or by
using one of the special keyring IDs.
Also define a resource subtype 'user_key', since we'll be adding a
definition for KEYCTL_DH_COMPUTE which takes in a struct containing
"user" key IDs.
Add to key.txt all key types that currently might be present in the
kernel. It was missing a few important ones such as "asymmetric", which
has a significant attack surface since the payloads are run through an
ASN.1 decoder.
* Lots of changes to sys/netbsd:
- Removed a few syscalls that did not have proper constants defined.
- Autogenerated *.const files.
- Removed a few types like uid and gid, that were not available.
- Ran make generate
* Few changes for NetBSD support:
- Added sys/netbsd/init.go
- Added netbsd to sys/sys.go
* Fix order in sys/sys.go
* Update documentation for NetBSD
This is mostly copied form linux.
We probably need better support for sharing descriptions
between multiple OSes. But there are lots of differences,
so this is not trivial.
1. remove workaround for pthread attrs (was fixed in akaros)
2. remove workaround for dup2 (was fixed in akaros)
3. check that we receive a program
4. implement timeout for test processes
We currently use more complex and functional protocol on linux,
and a simple ad-hoc protocol on other OSes.
This leads to code duplication in both ipc and executor.
Linux supports coverage, shared memory communication and fork server,
which would also be useful for most other OSes.
Unify communication protocol and parametrize it by
(1) use of shmem or only pipes, (2) use of fork server.
This reduces duplication in ipc and executor and will
allow to support the useful features for other OSes easily.
Finally, this fixes akaros support as it currently uses
syz-stress running on host (linux) and executor running on akaros.
Each arch duplicates significant portion of logic
to compile the extract source file.
Factor this logic into a separate function and reuse
it across all OSes.
A recent linux commit "tun: enable napi_gro_frags() for TUN/TAP driver"
added support for fragmentation when emitting packets via tun.
Support this feature in syz_emit_ethernet.
This breaks circular dependency between:
sysgen -> sys/linux -> sys -> sysgen
With this circular dependency it is very difficult to
update format of generated descriptions because sysgen does not build.
We used to generate them only because manager had no idea
what arch it is testing. So syscalls numbers had to match
between all arches.
This is not needed anymore.
Also don't generate unreferenced structs/resources.
Info about targets (like C arch/CFLAGS) is required in multiple places:
extract.sh
syz-extract
syz-sysgen
csource
vm/qemu
...
Consolidate it in one place and use that in syz-sysgen.
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
All other types have optional underlying type as the last argument.
Proc have it as first. This creates very irregular syntax and
complicates parsing. Make type the last argument.
Note: this is a breaking change if you have descriptions on the side.
We have implemented a new version of KCOV, which is able to dump
comparison operands' data, obtained from Clang's instrumentation hooks
__sanitizer_cov_trace_cmp[1248], __sanitizer_cov_trace_const_cmp[1248]
and __sanitizer_cov_trace_switch.
Current KCOV implementation can work in two modes: "Dump only the PCs"
or "Dump only comparisons' data". Mode selection is done by the
following series of calls:
fd = open(KCOV_PATH, ...); // works as previous
ioctl(fd, KCOV_INIT_TRACE, ...); // works as previous
mmap(fd, ...); // works as previous
ioctl(fd, KCOV_ENABLE, mode);
// mode = KCOV_MODE_TRACE_CMP or mode = KCOV_MODE_TRACE_PC
Note that this new interface is backwards compatible, as old KCOV
devices will just return -EINVAL for the last ioctl. This way we can
distinguish if the KCOV device is able to dump the comparisons.
Main changes in this commit:
1. Fuzzer now checks at startup which type (new/old) of KCOV device
is running.
2. Executor now receives an additional flag, which indicates if
executor should read the comparisons data from KCOV. The flag works on
per-call basis, so executor can collect PCs or Comps for each
individual syscall.