| Commit message (Collapse) | Author | Age | Files | Lines |
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
Currently we stop both executor binary and the RPC server concurrently
due to use of errgroup.WithContext. As the result, executor may SYZFAIL
on the closed network connection before it's killed.
This race leads to very high percent (25%) of failed repro attempts
for my local syz-manager runs. When we run syz-execprog with Repeat=false,
the race triggers frequently. May have something to do with heavily
instrumented kernel where some operations may take longer (e.g. killing
syz-executor and stopping all of its threads).
This should also fix #6091
|
| |
|
|
|
| |
To be useful, the stat should have a different name depending on the VM
pool name.
|
| |
|
|
|
| |
This will let us see executor restart statistics per VM pool (relevant
for diff fuzzing).
|
| | |
|
| |
|
|
|
| |
If we set it too early, it will be filtered out as it is not within the
addresses of the .text segment.
|
| | |
|
| | |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
| |
Dump the whole flatrpc.ConnectRequest to the logs, so that we can
better understand the cause of #5805
|
| | |
|
| |
|
|
|
| |
Running it from the VM context causes its cancellation each time VM
crashes or the connection is aborted.
|
| |
|
|
|
| |
On context abortion, return a special error.
On the pkg/rpcserver side, recognize and process it.
|
| |
|
|
|
| |
If an instance crashed during machine check, that should not normally
abort all RPCServer operation.
|
| |
|
|
|
| |
Accept context as a function argument.
Split out the code that creates a syz-executor process instance.
|
| |
|
|
| |
It should hopefully let us debug #5674.
|
| |
|
|
|
| |
Whenever the status is set, also include the reason. It should help
easier debug execution and machine check time problems.
|
| |
|
|
| |
Apply necessary changes to pkg/flatrpc and pkg/manager as well.
|
| |
|
|
|
|
|
| |
The context is assumed to be passed into the function doing the actual
processing. Refactor vminfo to follow this approach.
This will help refactor pkg/rpcserver later.
|
| |
|
|
|
|
|
| |
If we get a Hanged != "" response from a non-RequestTypeProgram request,
we used to end up trying to serialize an nil *prog.Prog value.
Add a missing if condition.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
|
|
|
| |
Few assorted changes to reduce future diffs:
- add rpcserver.RemoteConfig similar to LocalConfig
(there are too many parameters)
- add CheckGlobs to requesting additional globs from VMs
- pass whole InfoRequest to the MachineChecked callback
so that it's possible to read globs information
- add per-mode config checking in the manager
- add Manager.saveJson helper
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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>
|
| |
|
|
|
| |
We have a /modules link in the manager, but it's not exposed anywhere.
Add a stat with this link.
|
| | |
|
| |
|
|
|
| |
It will enable collecting statistics for several simultaneous RPCServer
objects.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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).
|
| |
|
|
| |
./tools/syz-env make generate
|
| |
|
|
|
|
|
|
|
| |
It does sometimes happen that the kernel is crashed so fast that
syz-manager is not notified that the syz-executor has started running
the faulty input.
In cases when the exact program is known from Comm, let's make sure it's
always present in the log of the last executed programs.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Added more test coverage of the package and created an interface of
rpcserver to use it as the dependency (for syz-manager).
Also tried to cover with tests a private method handleConn(),
though it calls handleRunnerConn which has a separate logic in
Handshake(), which within handleConn() unit test we should've mocked.
This will require a refactoring of `runners map[int]*Runner` and
runner.go in general with a separate interface which we can mock as
well.
General idea is to have interfaces of Server (rpc), Runner etc. and mock a
compound logic like Handshake during a separate public (or private if it
has callable, if-else logic) method unit-testing.
|
| | |
|
| |
|
|
|
|
| |
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.
|
| | |
|
| | |
|
| |
|
|
|
| |
These stats will be needed for snapshot mode that does not use rpcserver.
Move them from pkg/rpcserver to pkg/fuzzer/queue.
|
| |
|
|
|
|
|
|
| |
Go package names should generally be singular form:
https://go.dev/blog/package-names
https://rakyll.org/style-packages
https://groups.google.com/g/golang-nuts/c/buBwLar1gNw
|
| |
|
|
|
|
| |
New is more idiomatic name and is shorter
(lines where stats.Create is used are usually long,
so making them a bit shorter is good).
|
| | |
|
| |
|
|
|
|
|
|
|
| |
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).
|
| |
|
|
|
|
|
|
|
|
|
|
| |
For local rpcserver runs, we do not reboot the executor in case of
errors. Moreover, if the error did not lead to the executor process
exit, we may never detect that something went wrong.
Return an error channel from CreateInstance() to be able to act on
connection loop errors.
Explicitly register the instance during local executions and exit from
RunLocal() in case of connection problems.
|
| |
|
|
|
|
|
|
| |
In some cases, the executor seems to be mysteriously silent when we were
awaiting a reply.
During pkg/runtest tests, give it 1 minute to prepare a reply, then try
to request the current state and abort the connection.
|
| |
|
|
|
| |
Rely on instance.Pool to perform fuzzing and do bug reproductions.
Extract the reproduction queue logic to separate testable class.
|
| |
|
|
|
|
|
| |
The pool operates on a low level and assumes that there's one default
activity (=fuzzing) that is performed by the VMs and that there are
also occasional non-default activities that must be performed by some
VMs (=bug reproduction).
|
| | |
|
| |
|
|
|
| |
It's assumed that the caller would use a context to control waits on
individual requests.
|
| |
|
|
|
|
|
|
|
| |
There's no sense in continuing the operation once the Runner has been
stopped.
If no new requests are coming, the loop goroutine may last a long time
since it never actually interacts with the (possibly already closed)
socket.
|
| |
|
|
| |
The object enables a graceful shutdown of machine checks.
|
| |
|
|
|
| |
For fuzzing, we don't strictly need the kernel directory or the kernel
object file. We just need a disk/kernel image.
|
| |
|
|
|
| |
Make it explicit which methods of Runner refer to its implementation and
which are supposed to be invoked by its users.
|