| Commit message (Collapse) | Author | Age | Files | Lines |
| ... | |
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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().
|
| |
|
|
|
|
|
|
| |
syz_create_resource allows to turn any value into a resource.
Improve binfmt descriptions using syz_create_resource:
we need to pass the same file name to write syscalls and execve.
Use syz_create_resource to improve binfmt descriptions.
|
| | |
|
| |
|
|
|
| |
To ease fuzzing the dirty ring, explicitly reserve two pages with
the KVM_MEM_LOG_DIRTY_PAGES flag at known address.
|
| |
|
|
|
|
|
|
| |
The new API call will be used to write values to guest memory specified
by base+offset.
Writing to e.g. MMIO registers for VGIC (or any other MMIO ranges) may
result in new coverage.
|
| |
|
|
|
|
|
|
| |
Implement basic IRQ controller setup for VMs with a single CPU.
SYZOS_API_IRQ_SETUP sets up the VGICv3 distributor/redistributor and
enables the specified number of SPIs starting from 32.
The default IRQ handler is set up to perform a uexit(-2).
|
| |
|
|
|
| |
The new pseudo-syscall sets up VGICv3 IRQ controller on the host.
That still requires guest setup code, which will be submitted separately.
|
| |
|
|
|
|
| |
Occasionally a SIGCHLD would cause EINTR to be returned by pselect(),
and then the runner would become hung by attempting to read a socket
that was not in fact ready.
|
| |
|
|
|
| |
Reset coverage right before scheduling next syscall for execution.
See the added comment for details.
|
| |
|
|
|
|
|
| |
Protect KCOV regions with pkeys if they are available.
Protect output region with pkeys in snapshot mode.
Snapshot mode is especially sensitive to output buffer corruption
since its location is not randomized.
|
| |
|
|
|
| |
Replace just the SYZFAIL part instead of the whole message.
This makes debugging of things easier.
|
| | |
|
| |
|
|
|
| |
It's not necessary to set process name in snapshot mode
since we execute only 1 program each time.
|
| |
|
|
|
| |
Make the necessary changes to support HVC in addition to SMC.
These two may subtly differ, so they are handled separately.
|
| |
|
|
|
|
|
|
| |
Provide an API call to invoke the ARM64 Secure Monitor Call instruction
with user-supplied function id and 5 parameters passed in registers x1-x5.
For now only `smc #0` is invoked, although in the future we may want to
pass other (reserved) immediate values to SMC.
|
| |
|
|
| |
Fixes #5143
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
MSR is an ARM64 instruction that writes a value from a GP register to
one of the system CPU registers. Exposing those registers to a fuzzer will
let us trigger unexpected behavior in handling them on the kernel side.
The SYZOS_API_MSR call has two int64 arguments, register ID and value.
Register IDs are 64-bit values obtained from ARM64_SYS_REG() in the Linux asm/kvm.h
UAPI header. Same register IDs are used by ioctl$KVM_GET_ONE_REG and
ioctl$KVM_SET_ONE_REG.
Also add sys/linux/test/syz_kvm_setup_cpu_arm64-msr
|
| |
|
|
|
| |
Call guest_uexit(-1) to break from ioctl(KVM_RUN), otherwise the VM
will be running infinitely until it is killed.
|
| | |
|
| |
|
|
|
|
| |
Using actual VM indices for VM identification allows to match these indices to VMs in the pool,
allows to use dense arrays to store information about runners (e.g. in queue.Distributor),
and just removes string names as unnecessary additional entities.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Currently we force restart in rpcserver, but this has 2 problems:
1. It does not know the proc where the requets will land.
2. It does not take into account if the proc has already restarted
recently for other reasons.
Restart procs in executor only if they haven't restarted recenlty.
Also make it deterministic. Given all other randomess we have,
there does not seem to be a reason to use randomized restarts
and restart after fewer/more runs.
Also restart only after corpus triage.
Corpus triage is slow already and there does not seem to be enough
benefit to restart during corpus triage.
Also restart at most 1 proc at a time,
since there are lots of serial work in the kernel.
|
| |
|
|
| |
Distribute triage requests to different VMs.
|
| |
|
|
| |
ConnectWait is directly from OpenBSD man page.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Allow guest payload to call syzos API functions. The available calls
are enumerated by SYZOS_API_* constants, and have a form of:
struct api_call {
uint64 call;
uint64 struct_size;
/* arbitrary call-related data here */
};
Complex instruction sequences are too easy to break, so most of the time
fuzzer won't be able to efficiently mutate them.
We replace kvm_text_arm64 with a sequence of `struct api_call`, making it
possible to intermix assembly instructions (SYZOS_API_CODE) with
higher-level constructs.
Right now the supported calls are:
- SYZOS_API_UEXIT - abort from KVM_RUN (1 argument: exit code, uint64)
- SYZOS_API_CODE - execute an ARM64 assembly blob
(1 argument: inline array of int32's)
|
| |
|
|
| |
Do not report errors when a function name contains '[_]exit' as a substring.
|
| |
|
|
|
|
|
|
|
|
| |
For KVM fuzzing we are going to need some library code that will be
running inside KVM to perform common tasks (e.g. register accesses,
device setup etc.)
This code will reside in a special ".guest" section that the executor
will map at address 0xeeee8000. For now it contains just the main function,
but will be extended in further patches.
|
| |
|
|
|
|
|
| |
Refactor phys page allocation in syz_kvm_setup_cpu$arm64 to prepare for
more address ranges.
Load user-supplied code at ARM64_ADDR_USER_CODE and allocate EL1 stack
at ARM64_ADDR_EL1_STACK_BOTTOM.
|
| | |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Running the vusb_ath9k runtest (with [1] and [2] applied) produces ~100k of
extra coverage, which is somewhat close to the current 256k limit. A more
complicated program might produce more extra coverage and overflow the
coverage buffer.
Increase kExtraCoverSize to 1024k.
As the extra coverage buffer is maintained per-executor and not per-thread,
the total increase of the coverage mapping is ~9%, which is not too bad.
[1] https://lore.kernel.org/all/eaf54b8634970b73552dcd38bf9be6ef55238c10.1718092070.git.dvyukov@google.com/
[2] https://lore.kernel.org/all/20240722223726.194658-1-andrey.konovalov@linux.dev/T/#u
|
| |
|
|
|
|
|
|
| |
We never reset remote coverage, so if there is one block,
we will write it after every call and multiple times at the end.
It can lead to "too many calls in output" and just writes quadratic
amount of coverage/signal.
Reset remote coverage after writing.
|
| |
|
|
| |
Check that we have at least command argument in the beginning.
|
| |
|
|
|
|
|
|
|
| |
We are getting too many generated candidates, the fuzzer may not keep up
with them at all (hints jobs keep growing infinitely). If a hint indeed came
from the input w/o transformation, then we should guess it on the first
attempt (or at least after few attempts). If it did not come from the input,
or came with a non-trivial transformation, then any number of attempts won't
help. So limit the total number of attempts (until the next restart).
|
| |
|
|
|
|
|
|
|
|
|
| |
This kind of deduplication is confusing for the fuzzer, which expects to
control the process itself (by MaxSignal and by specifying the calls for
which full signal must be returned).
There's also a chance that it may contribute to the difficulties during
program triage and minimization.
Let's err on the safe side and deduplicate signal only per-call.
|
| |
|
|
|
| |
In case only ipv6 is supported, we should try ipv4-localhost first and see if it
fails, and then go on to trying ipv6.
|
| |
|
|
|
|
|
| |
It should fix errors like this one:
SYZFAIL: failed to resolve manager addr
addr=localhost h_errno=2
(errno 11: Resource temporarily unavailable
|
| |
|
|
|
| |
See commit bc144f9a58782daa2399d417b56aad80e82a219e. The justification
applies to other BSDs as well, so apply the same workaround.
|
| |
|
|
|
| |
There are also synchnous fatal signals that can happen due to bugs
in executor code. So handle them as SIGSEGV.
|
| |
|
|
|
|
|
| |
cad_pid must not point to a persistent runner process,
b/c it will be killed on ctrl+alt+del.
Fixes #5027
|
| |
|
|
|
| |
This will allow to reuse finish_output function for snapshot mode as well.
NFC
|