| Commit message (Collapse) | Author | Age | Files | Lines |
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* Fixes a bug when setting up a 64-bit guest by making the bit
manipulation macros produce unsigned long long: To create a VCPU that
has paging enabled, one needs to set the CR0.PE and CR0.PG bits in
CR0. The latter is problematic when setting up a 64-bit guest since if
the macro is not using 1ULL, it sign extends the output (in 64-bit
mode the control registers are extended to 64-bits with some of the
CR0[32:63] bits reserved). This results in either failing the
KVM_SET_SREGS ioctl (in newer kernel versions) or just failing the
KVM_RUN ioctl with EXIT_REASON_INVALID_STATE.
* Moved the bit manipulation definitions from the amd64 specific to the generic
kvm header to consolidate them with the already existing ones.
Prefixed them with X86_ to avoid confusion.
|
| |
|
|
|
| |
The error handling for the setsid() call in sandbox_common() requires
it. Without it, some csource builds fail.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
During machine checks, syzkaller will execute calls with coverage
disabled, in which case per-thread coverage structures are zeroed out.
write_output() will temporarily map the coverage data as writeable via
CoverAccessScope, whether or not cover is enabled. In effect,
write_output() may trigger a call mprotect(0, kCoverSize, PROT_RW).
On FreeBSD, mprotect() silently ignores unmapped regions, so this does
not result in an error. In fact, kCoverSize is now large enough that
this ends up removing the eXecute bit from part of syz-executor's text
region.
Make CoverAccessScope a no-op if coverage is not enabled. Modify BSD
cover_protect() and cover_unprotect() to fail if invoked when coverage
is disabled.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
As we figured out in #5805, syz-manager treats random incoming RPC
connections as trusted, and will crash if a non-executor client sends
an invalid packet to it.
To address this issue, we introduce another stage of handshake, which
includes a cookie exchange:
- upon connection from an executor, the manager sends a ConnectHello RPC
message to it, which contains a random 64-bit cookie;
- the executor calculates a hash of that cookie and includes it into
its ConnectRequest together with the other information;
- before checking the validity of ConnectRequest, the manager ensures
client sanity (passed ID didn't change, hashed cookie has the expected
value)
We deliberately pick a random cookie instead of a magic number: if the
fuzzer somehow learns to send packets to the manager, we don't want it to
crash multiple managers on the same machine.
|
| |
|
|
| |
Some environments don't define MAP_FIXED_NOREPLACE.
|
| |
|
|
|
|
|
|
|
|
|
|
| |
MAP_FIXED_NOREPLACE allows to fail early if we happened to overlap with
an existing memory mapping. It should help detects bugs #5674 at an
earlier stage, before it led to memory corruptions.
MAP_FIXED_NOREPLACE is supported from Linux 4.17, which is okay for all
syzkaller use cases on syzbot.
There's no such option for some of the supported OSes, so set it
depending on the configuration we're building for.
|
| |
|
|
|
|
| |
Proper glob resolution is required for fuzzing.
If it times out, it does so silently, and fuzzing dictionary will be smaller then expected, without any obvious errors.
Given that, it makes sense to increase glob timeouts.
|
| |
|
|
|
|
|
|
| |
Syzkaller allows user to specify filepath arguments in syscalls via globs.
However, on linux, you are effectivly limited to some /sys and /dev paths due to sandboxing.
With this change, user can supply their custom fuzzing artifacts to /syz-inputs to use those in globs.
They are mounted read-only to increase reproducibility.
|
| | |
|
| |
|
|
| |
Add support for the MRS instruction in a similar manner to MSR.
|
| |
|
|
|
|
| |
Make sure operands passed to 64-bit MOV, MSR and MRS instructions are
actually 64-bit.
This fixes compiler warnings in certain build configurations.
|
| |
|
|
| |
Add a pseudo-syscall to assert on register values.
|
| |
|
|
|
|
|
|
|
|
|
| |
In some build environments (notably Yocto), syzkaller host and target
binaries end up in separate packages for each built architecture, which
are then shipped with the respective image/SDK.
Add the "Execprog/ExecutorBinOnTarget" and "StraceBinOnTarget" options
to the manager config, which when set expects the respective binaries to
be shipped with the target image and does not attempt to copy them from
the host.
|
| |
|
|
| |
We can reach it at least with automatic descriptions.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
We query globs for 2 reasons:
1. Expand glob types in syscall descriptions.
2. Dynamic file probing for automatic descriptions generation.
In both of these contexts are are interested in files
that will be present during test program execution
(rather than normal unsandboxed execution).
For example, some files may not be accessible to test programs
after pivot root. On the other hand, we create and link
some additional files for the test program that don't
normally exist.
Add a new request type for querying of globs that are
executed in the test program context.
|
| |
|
|
|
| |
The new pseudo-syscall will serve as a test assertion, checking the uexit
return value. This is going to help us validate SyzOS code.
|
| |
|
|
|
|
|
|
|
| |
When running syscalls asynchronously, syz_kvm_add_vcpu() sometimes
receives a zero VM handle, on which it then crashes.
Check for the zero value to ensure stability of the tests in sys/linux/tests.
Also make sure to set errno for the pseudo-syscall in the cases where it's not
done by the underlying syscalls.
|
| |
|
|
| |
We missed that step for snapshot mode.
|
| |
|
|
|
| |
Make sure regressions in guest code validation are reported during testing
rather than fuzzing.
|
| |
|
|
|
|
|
|
| |
Glob() doesn't work on 32-bit ARM when run on a 64-bit system under QEMU:
https://gitlab.com/qemu-project/qemu/-/issues/263
Not sure whether this is specific to tests running under qemu-user, or
the ARM32 executor in the wild as well.
|
| |
|
|
|
|
| |
Prevent the compiler from generating a jump table by replacing a switch
with a series of if statements.
This is ugly, but lets us work around crashes caused by https://github.com/google/syzkaller/issues/5565
|
| |
|
|
|
|
| |
Apply __attribute__((noinline)) to SyzOS API command handlers to prevent
overly optimizing them.
While at it, rearrange specifiers in guest function declarations
|
| |
|
|
|
|
|
| |
Detect and report ADRP instructions in the linked binaries to avoid
crashes inside SyzOS.
See https://github.com/google/syzkaller/issues/5565 for more context.
|
| |
|
|
| |
It's no longer needed.
|
| | |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
This is done to solve a particular test failure running:
$ tools/syz-env go test ./prog -run TestSpecialStructs
, which failed on PPC64, because prog/rand.go instanciated a call to
syz_kvm_setup_syzos_vm(), which requested too much memory (1024 pages)
from the allocator (PPC64 uses 64k pages, so the number of available pages
is lower).
On the other hand, factoring out syzos-related descriptions is probably
a nice thing to do anyway.
|
| |
|
|
|
|
|
| |
Pass 1024 pages of memory to both syz_kvm_setup_syzos_vm() and
syz_kvm_setup_cpu$arm64() to make sure that:
- there is enough memory for guest allocations (e.g. ITS pages)
- host can tamper with that memory, provoking more bugs
|
| |
|
|
|
| |
In addition to the predefined ITS setup, let the guest execute different
ITS configuration commands in an attempt to trigger interesting interactions.
|
| |
|
|
|
| |
The new API call implements basic setup of the ARM Interrupt Translation Service
for the given number of CPUs, virtual devices, and LPIs.
|
| |
|
|
|
|
| |
There's no need to mask the IDs, and it actually doesn't work for LPIs.
Also add more comments.
|
| | |
|
| | |
|
| | |
|
| |
|
|
|
|
|
| |
Currently we write coverage backwards.
This is visible e.g. when running syz-execprog -coverfile,
and in the manager raw cover mode.
Write it in the right order.
|
| |
|
|
|
|
| |
Don't follow symlinks when globbing.
It's haarmful for both files and dirs
(see the added comment for details).
|
| |
|
|
|
|
|
|
|
|
|
| |
The coverage buffer frequently overflows.
We cannot increase it radically b/c they consume lots of memory
(num procs x num kcovs x buffer size) and lead to OOM kills
(at least with 8 procs and 2GB KASAN VM).
So increase it 2x and slightly reduce number of threads/kcov descriptors.
However, in snapshot mode we can be more aggressive (only 1 proc).
This reduces number of overflows by ~~2-4x depending on syscall.
|
| |
|
|
|
| |
If the overflows happen often, it's bad.
Add visibility into this.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
After 9fc8fe026baa ("executor: better handling for hanged test
processes"), yz-executor's responses may reference procids outside of
the [0;procs] range.
If procids are no longer dense on the syz-executor side, we cannot rely
on this check in pkg/rpcserver:
```
if avoid == (uint64(1)<<runner.procs)-1 {
avoid = 0
}
```
Signed-off-by: Andrei Vagin <avagin@google.com>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Currently we kill hanged processes and consider the corresponding test finished.
We don't kill/wait for the actual test subprocess (we don't know its pid to kill,
and waiting will presumably hang). This has 2 problems:
1. If the hanged process causes "task hung" report, we can't reproduce it,
since the test finished too long ago (manager thinks its finished and
discards the request).
2. The test process still consumed per-pid resources.
Explicitly detect and handle such cases:
Manager keeps these hanged tests forever,
and we assign a new proc id for future processes
(don't reuse the hanged one).
|
| |
|
|
| |
This helps to avoid leaking processes when killing races with PR_SET_PDEATHSIG.
|
| |
|
|
|
|
|
|
| |
It's unclear why we need a new session.
Sessions group process groups, but we don't use that.
Setsid also creates a new process group,
but we don't kill this process group,
so also unclear why this is needed.
|
| |
|
|
|
|
|
|
|
| |
Killing a process group (negative pid) only makes sense
when the process is a group leader (called setsid/setpgrp/setpgid).
Executor exec process is not a group leader,
so don't try to kill its group. For our controlled executor
subprocesses we rely on PR_SET_PDEATHSIG for reliable
killing of all child subprocesses.
|
| |
|
|
|
|
|
| |
Reserve SYZOS address for the ITS redistributor at 0x08080000, add it to the
list of kvm_guest_addrs.
Also implement a syzlang test for the host part of ITS configuration as per
https://www.kernel.org/doc/html/v6.1/virt/kvm/devices/arm-vgic-its.html
|
| |
|
|
|
|
|
|
| |
All these broke when we started mounting new tmpfs for sandbox=root.
Some are not mounted at all, some are mounted in the outer root
and are not accessible from the new root.
Mount then inside of the new root tmpfs.
Other file systems (binderfs, cgroups) seem to be ok.
|
| |
|
|
|
| |
It is more common for the constants in the executor to not have the
SYZ_ prefix.
|
| |
|
|
|
|
|
|
|
| |
Let SYZOS distinguish CPUs inside VM by storing their ID in TPIDR_EL1.
Make sure existing code uses that ID:
- in guest_handle_msr(), to ensure concurrent calls do not write to the
same cache line;
- in gicv3_irq_enable(), to ensure proper CPU ID is being used for
IRQ setup.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
syz_kvm_add_vcpu
The old syz_kvm_setup_cpu() API mixed together VM and VCPU setup, making it
harder to create and fuzz two VCPUs in the same VM.
Introduce two new pseudo-syscalls, syz_kvm_setup_syzos_vm() and syz_kvm_add_vcpu(),
that will simplify this task.
syz_kvm_setup_syzos_vm() takes a VM file descriptor, performs VM setup
(allocates guest memory and installs SYZOS code into it) and returns a
new kvm_syz_vm resource, which is in fact a pointer to `struct kvm_syz_vm`
encapsulating VM-specific data in the C code.
syz_kvm_add_vcpu() takes the VM ID denoted by kvm_syz_vm and creates a
new VCPU within that VM with a proper CPU number. It then stores the
fuzzer-supplied SYZOS API sequence into the corresponding part (indexed by
CPU number) of the VM memory slot, and sets up the CPU registers to interpret
that sequence.
The new pseudo-syscall let the fuzzer create independent CPUs that run different
code sequences without interfering with each other.
|
| |
|
|
|
| |
Use the cpu id to choose the SYZOS API commands to be executed
by this particular CPU.
|
| |
|
|
|
|
|
|
| |
Prepare to let multiple (up to 4) CPUs run different pieces of code
by allocating 4 pages for ARM64_ADDR_USER_CODE.
Pass the CPU id to guest_main(), so that it can pick the correct
starting addres.
syz_kvm_setup_cpu() will implicitly use cpuid=0 to retain its current functionality.
|
| |
|
|
|
|
|
|
|
| |
No functional change.
For multiple CPUs within the same VM, calls to syz_kvm_setup_cpu()
will set up the VM memory space multiple times, so only the last one
will take effect.
Prepare to decouple VM setup from CPU setup by factoring this code out
of syz_kvm_setup_cpu().
|