| Commit message (Collapse) | Author | Age | Files | Lines |
| |
|
|
|
|
|
|
|
| |
All OSes we have now support shmem.
Support for Fuchia/Starnix/Windows wasn't implemented,
but generally they support shared memory.
Remove all of the complexity and code associated with noshmem mode.
If/when we revive these OSes, it's easier to properly
implement shmem mode for them.
|
| |
|
|
|
|
|
|
|
| |
Asan build with sharem memory mode is broken for a long time
since the address for output region is incompatible with asan
(asan doesn't have shadow for these addresses).
We did not notice it b/c we only tested no shared memory mode
in short test mode used on CI.
Don't use fixed mmap address under asan.
|
| |
|
|
|
|
|
|
|
| |
Fix 2 bugs:
1. We remove low 12 bits of every PC on amd64 b/c use_cover_edges return true.
This results in extremly low signal (gvisor PC are dense integers).
2. We hash prev/next PC on arm64 which does not make sense
since gvisor coverage is not a trace. This results in falsely large signal.
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
Return failure reason from setup functions rather than crash.
This will provide better error messages, but also allow setup
w/o creating subprocesses which will be needed when we combine
fuzzer and executor.
Also close all resources created during setup.
This is also useful for in-process setup, but also should improve
chances of reproducing a bug with C reproducer. Currently leaked
file descriptors may disturb repro execution (e.g. it may act
on a wrong fd).
|
| |
|
|
|
|
| |
Update the descriptions to mark calls that cause remote coverage
collection.
Remote some hacky code from the executor.
|
| |
|
|
|
|
|
|
|
|
|
|
| |
On 64 bit machine, when CONFIG_RANDOMIZE_BASE enabled,
even [32:64] bits changed across reboot.
And, core kernel and modules can have diff [31:64] bits.
We need to add 64bit pc support and this is to always
send 64bit pc and sig to syz-fuzzer.
Send 64bit pc and sig is compatable with 32bit OS.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Feature checking procedure is split into 2 phases:
1. syz-fuzzer invokes "syz-executor setup feature" for each feature one-by-one,
and checks if executor does not fail.
Executor can also return a special "this feature does not need custom setup",
this allows to not call setup of these features in each new VM.
2. pkg/vminfo runs a simple program with ipc.ExecOpts specific for a concrete feature,
e.g. for wifi injection it will try to run a program with wifi feature enabled,
if setup of the feature fails, executor should also exit with an error.
For coverage features we also additionally check that we actually got coverage.
Then pkg/vminfo combines results of these 2 checks into final result.
syz-execprog now also uses vminfo package and mimics the same checking procedure.
Update #1541
|
| | |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Move the syscall checking logic to the host.
Diffing sets of disabled syscalls before/after this change
in different configurations (none/setuid sandboxes, amd64/386 arches,
large/small kernel configs) shows only some improvements/bug fixes.
1. socket$inet[6]_icmp are now enabled.
Previously they were disabled due to net.ipv4.ping_group_range sysctl
in the init namespace which prevented creation of ping sockets.
In the new net namespace the sysctl gets default value which allows creation.
2. get_thread_area and set_thread_area are now disabled on amd64.
They are available only in 32-bit mode, but they are present in /proc/kallsyms,
so we enabled them always.
3. socket$bt_{bnep, cmtp, hidp, rfcomm} are now disabled.
They cannot be created in non init net namespace.
bt_sock_create() checks init_net and returns EAFNOSUPPORT immediately.
This is a bug in descriptions we need to fix.
Now we see it due to more precise checks.
4. fstat64/fstatat64/lstat64/stat64 are now enabled in 32-bit mode.
They are not present in /proc/kallsyms as syscalls, so we have not enabled them.
But they are available in 32-bit mode.
5. 78 openat variants + 10 socket variants + mount are now disabled
with setuid sandbox. They are not permitted w/o root permissions,
but we ignored that. This additionally leads to 700 transitively
disabled syscalls.
In all cases checking in the actual executor context/sandbox
looks very positive, esp. for more restrictive sandboxes.
Android sandbox should benefit as well.
The additional benefit is full testability of the new code.
The change includes only a basic test that covers all checks,
and ensures the code does not crash/hang, all generated programs
parse successfully, etc. But it's possible to unit-test
every condition now.
The new version also parallelizes checking across VMs,
checking on a slow emulated qemu drops from 210 seconds
to 140 seconds.
|
| |
|
|
|
|
|
| |
Currently we set errno=999 in executor for non-finished syscalls,
but syscalls that were not even started still have errno=0.
They also don't have Executed flag, but it's still handy to have
a non-0 errno when the call is not successful.
|
| |
|
|
|
|
| |
Prepend total number of calls to the exec encoding.
This will allow pkg/ipc to better parse executor response
without full parsing of the encoded program.
|
| |
|
|
|
|
|
|
|
|
| |
1. Don't write size/flags for addresses.
2. Write address w/o data offset (fewer bytes in leb128 encoding).
Median exec size shrinks by 25%:
- exec sizes: 10%:584 50%:1423 90%:7076
+ exec sizes: 10%:448 50%:1065 90%:6319
|
| |
|
|
|
|
|
|
| |
With leb128 ints it does not make any sense.
Reduces exec sizes a bit more:
- exec sizes: 10%:597 50%:1438 90%:7145
+ exec sizes: 10%:584 50%:1423 90%:7076
|
| |
|
|
|
|
|
|
|
|
|
|
| |
Switch from uint64 to leb128 encoding for integers.
This almost more than halves serialized size:
- exec sizes: 10%:2160 50%:4792 90%:14288
+ exec sizes: 10%:597 50%:1438 90%:7145
and makes it smaller than the text serialization:
text sizes: 10%:837 50%:1591 90%:10156
|
| |
|
|
|
|
|
| |
Akaros support is unused, it was shutdown on syzbot for a while,
the akaros development seems to be frozen for years as well.
We have a bunch of hacks for Akaros since it supported
only super old gcc and haven't supported Go. Remove it.
|
| |
|
|
|
| |
This should never be happening during fuzzing. Otherwise we let
syz-executor silently crash and restart insane number of times.
|
| |
|
|
|
| |
It makes these extentions much more flexible as they can now also
customize what other features set up.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
We have a long history of executor managing to corrupt itself in various
interesting ways (e.g. using read with a pointer pointing to some
global/stack variable and then kernel overwrites it). Or rt_sigreturn
can corrupt other registers which won't cause immediate SIGSEGV, but
rather some random behavior later. This is the race we can't win.
We can't rely on memory consistency when the test already started, so we
should use exitf instead of fail outside of setup sequence (and relying
more on unit testing to ensure that executor works as expected for sane
programs).
Suggested-by: Dmitry Vyukov <dvyukov@google.com>
Signed-off-by: Andrei Vagin <avagin@google.com>
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
Adjust signal creation in syz-executor so hash
is independent of module offsets. This allows
for canonicalization of the signal between VMs.
Added signals to canonicalization/decanonicalization
between instances.
Coverts serialized Signal values as they have already
been serialized in rpc.go. Added a function in signal.go
to update serial signal elements.
|
| | |
|
| | |
|
| |
|
|
|
|
|
| |
Pages residing in the BSS section are by now flagged as immutable on OpenBSD.
Meaning that their corresponding permissions cannot change. The input_data
therefore needs to be explicitly marked as mutable. Should hopefully bring
syzbot on OpenBSD back.
|
| |
|
|
|
|
| |
A fixed-address mmap can fail completely or return a different address.
Log what it was. Based on:
https://groups.google.com/g/syzkaller/c/lto00RwlDIQ
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Add support for moving a NIC PCI pass-through VF into Syzkaller's network
namespace so that it will tested. As DEVLINK support is triggered by
setting the pass-through device to "addr=0x10", NIC PCI pass-through VF
support will be triggered by setting the device to "addr=0x11".
If a NIC PCI pass-through VF is detected in do_sandbox, setup a staging
namespace before the fork() and transfer the NIC VF interface to it.
After the fork() and in the child transfer the NIC VF interface to
Syzkaller's network namespace and rename the interface to netpci0 so
that it will be tested.
Signed-off-by: George Kennedy <george.kennedy@oracle.com>
|
| |
|
|
| |
syz-manager: introduce a new setting 'sandbox_arg' (#3263)
|
| | |
|
| | |
|
| |
|
|
| |
Fixes: fcfad4ffcf3a ("ipc: add magic in a call reply")
|
| |
|
|
|
|
|
|
|
|
| |
When a shared memory is used, the executor can corrupt reply messages,
so let's add magic to detect such cases.
It is an attempt to debug issues like this one:
https://syzkaller.appspot.com/bug?id=faca64c3182e9f130ca94b7931dd771be390ef67
Signed-off-by: Andrei Vagin <avagin@google.com>
|
| |
|
|
| |
Allow common_ext.h to provide setup_ext() function that is called during VM setup.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
As was found out in #2921, fork bombs are still possible in Linux-based
instances. One of the possible reasons is described below.
An invalid stack can be passed to the clone() call, thus causing it to stumble
on an invalid memory access right during returning from the clone() call. This
is in turn catched by the NONFAILING() macro and the control actually jumps
over it and eventually both the child and the parent continue executing the
same code.
Prevent it by handling SIGSEGV and SIGBUS differently during the clone process.
Co-authored-by: Andrei Vagin <avagin@google.com>
|
| |
|
|
| |
Don't print the confuing errno 14 for successful calls.
|
| |
|
|
|
|
|
|
| |
pkg/repro tries to clear the Threaded flag during repro simplification,
so it's easier just to ignore the remaining async flags in that case -
they won't be in the C repro either.
Add a test to pkg/ipc to verify the new behavior.
|
| |
|
|
|
|
|
|
|
| |
Set new kcov count limits: 6 for the default mode and 16 for the
optimized mode (when the instances are mmapped a needed). Don't generate
SYZFAIL when these limits are exhausted.
Just increasing those limits won't help as syzkaller will anyway come up
with programs that overcome them.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
To be able to collide specific syscalls more precisely, we need to
repeat the process many times.
Introduce the `rerun` call property, which instructs `syz-executor` to
repeat the call the specified number of times. The intended use is:
call1() (rerun: 100, async)
call2() (rerun: 100)
For now, assign rerun values randomly to consecutive pairs of calls,
where the first one is async.
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
Replace the currently existing straightforward approach to race triggering
(that was almost entirely implemented inside syz-executor) with a more
flexible one.
The `async` call property instructs syz-executor not to block until the
call has completed execution and proceed immediately to the next call.
The decision on what calls to mark with `async` is made by syz-fuzzer.
Ultimately this should let us implement more intelligent race provoking
strategies as well as make more fine-grained reproducers.
|
| |
|
|
|
| |
As all opened kcov instances are mmapped, we don't need to check it one
more time at all.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
It turns out that the current Linux implementation of KCOV does not
properly handle multiple mmap invocations on the same instance. The
first one succeedes, but the subsequent ones do not actually mmap
anything, yet returning no error at all.
The ability to mmap that memory multiple times allows us to increase
syz-executor performance and it would be a pity to completely lose it
(especially given that mmapping kcov works fine on *BSD).
In some time a patch will be prepared, but still we will have to support
both versions at the same time - the buggy one and the correct one.
Detect whether the bug is present by writing a value at the pointer
returned by mmap. If it is present, disable dynamic kcov mmapping and
pre-mmap 5 instances in the main() function - it should be enough for
all reasonable uses. Otherwise, pre-mmap 3 and let syz-executor mmap
them as needed.
|
| |
|
|
|
| |
Currently it is dup2'd to 0, which is quite likely to be closed by the
fuzzer. Dup2 it to a safer fd instead.
|
| |
|
|
|
|
|
|
|
| |
The previous strategy (delay kcov instance creation) seems not to work
very well in carefully sandboxed environments. Let's see if the new
approach is more versatile.
Open a kcov handle for each thread at syz-executor's initialization, but
don't mmap it right away.
|
| |
|
|
|
|
|
|
|
| |
As now kcov instances may get set up during fuzzing, performing dup2 in
cover_open is no longer safe as it may close some important resource.
Prevent that by reserving most of fds that belong to the kcov fds range.
Unfortunately we must duplicate the code because of the way kcov
implementations are organized.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The amount of virtual memory affects the speed of forking/exiting. As in
most cases we do it for each executed program, the difference may be
substantial.
We don't need 16MB of output data for each execution (in fact,
experiments have shown that we never cross even 8MB on Linux). But
reducing that cap in more than 2 times is a pretty bold decision, and
perhaps it's better to just make the allocation process smarter.
Mmap the output region depending on the exact amount of memory needed
for a specific program. E.g. if comparisons are collected, the expected
amount of output is maximal. If we only collect signals, the output
is minimal.
Mmap the minimally required region in the parent and then re-mmap it in
the forked child if it turns out that a higher amount of memory is
needed.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Experiments have shown that the amount of allocated memory has a very
big impact on the syz-executor's performance (at least under Linux) -
much bigger than was expected.
One source of that extra virtual memory is kcov and, in fact, usually we
don't need all 16 kcov handles we create. E.g. only 4 are enough for 99.5%
progs that syzkaller executes. The biggest consumer of threads - the
collide mode doesn't need kcov at all.
Let kcov handle be an optional property of a thread, not a mandatory
one. Allocate only 3 kcov instances initially (they'll be preserved over
forks) and let the forked processes create other kcov instances if they
happen to be needed.
|
| |
|
|
|
|
|
| |
Currently we setup cgroups on every test process start
(along with sandbox creation). That's unnecessary because
that's global per-machine setup. Move cgroup setup into setup section
that's executed once per machine from pkg/host.Setup.
|
| |
|
|
|
|
| |
Historically the code base does not use single-line compound statements
({} around single-line blocks). But there are few precedents creeped into
already. Add a check to keep the code base consistent.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
We have seen cases when a test program re-execed the current binary:
11:53:29 executing program 0:
openat$zero(0xffffffffffffff9c, &(0x7f0000000040), 0x0, 0x0)
r0 = openat(0xffffffffffffff9c, &(0x7f0000000080)='/proc/self/exe\x00', 0x0, 0x0)
lseek(r0, 0x4000000000000000, 0x4)
execveat(r0, &(0x7f0000000080)='\x00', 0x0, 0x0, 0x1000)
In such cases, we have to be sure that executor will not print SYZFAIL
log messages and will not exit with kFailStatus.
Since a659b3f1, syzkaller reports bugs in all these cases.
Fixes: a659b3f1dc88 ("pkg/report: detect executor failures")
Signed-off-by: Andrei Vagin <avagin@google.com>
|
| |
|
|
|
|
|
|
|
|
|
|
| |
Now that call properties mechanism is implemented, we can refactor
fault injection.
Unfortunately, it is impossible to remove all traces of the previous apprach.
In reprolist and while performing syz-ci jobs, syzkaller still needs to
parse the old format.
Remove the old prog options-based approach whenever possible and replace
it with the use of call properties.
|
| |
|
|
|
|
|
|
|
| |
Call properties let us specify how each individual call within a program
must be executed. So far the only way to enforce extra rules was to pass
extra program-level properties (e.g. that is how fault injection was done).
However, it entangles the logic and not flexible enough.
Implement an ability to pass properties along with each individual call.
|
| |
|
|
|
|
|
|
|
| |
Currently the data_offset field of cover_t is only initialized for
per-syscall coverage collection. As a result, remote coverage is read
from an invalid location, fails to pass sanity checks and is not
returned to syzkaller.
Fix the initialization of cover_t fields.
|
| | |
|