| Commit message (Collapse) | Author | Age | Files | Lines |
| |
|
|
| |
Any is the preferred over interface{} now in Go.
|
| |
|
|
|
|
|
|
| |
Semaphore is a very low-level primitive type,
while pkg/instance is a very high-level package with lots of deps.
Semaphore does not belong there, and may lead to cyclic deps
if we use it more. Move it to pkg/osutil. It's not really OS-specific,
but we don't have a better package.
|
| |
|
|
|
| |
After this change it fits more naturally into the Go's error
functionality.
|
| |
|
|
| |
./tools/syz-env bin/golangci-lint run ./... --fix
|
| |
|
|
| |
They are shorter, more readable, and don't require temp vars.
|
| |
|
|
|
|
|
| |
These have been the cause of too many invalid bisection results
recently.
This is the first step towards the more universal approach of #5414.
|
| |
|
|
| |
Only select them as relevant if there are not other crash types.
|
| |
|
|
|
|
|
| |
Currently we have HeadCommit function that returns info
about the HEAD commit. Change it to a more flexible Commit
function that can return info about any commit.
This will be used in future changes.
|
| |
|
|
|
|
| |
This unifies the build() and clean() interfaces such that if a custom
compiler or make binary is provided in the manager or bisection config,
they can be taken into account by the clean() interface.
|
| |
|
|
|
|
| |
Certain environments might need a specific make command or wrap make
calls with extra logic. This lets users provide a path to a custom make
binary.
|
| |
|
|
|
|
|
| |
Handle SIGKILL (exit code = 137) on osutil.Run() during Linux kernel image
building and return build.InfraError without reporting.
Fixes: https://github.com/google/syzkaller/issues/5317
|
| | |
|
| |
|
|
| |
The latter is a better suitable name.
|
| |
|
|
|
| |
The parameter defines the maximum number of CPUs involved in the kernel
build process.
|
| |
|
|
|
|
|
|
|
| |
The "1 crashed, 9 OK" cases are a frequent reason of invalid bisection
results on syzbot.
Let's define a cutoff for a BisectBad verdict and use it to prevent such
obvious outliers. We cannot safely declare such results as BisectGood
either, so let's return BisectSkip in this case.
|
| |
|
|
|
|
|
| |
Bisection should not fail if the Kconfig or the baseline config have issues.
Broken kernel sources might lead to issues when parsing Kconfig, ignore this and
proceed with the original config. If the baseline config is not parseable,
proceed anyway as this is an optional parameter to begin with.
|
| |
|
|
|
|
|
|
| |
I couldn't manage to add "pkg/bisect.env.log" to
"govet"."settings"."printf"."funcs", so let's use another way suggested
by govet documentation.
Fix one instance of invalid arguments.
|
| |
|
|
|
|
|
|
|
|
| |
For older bugs (or for bugs on stable trees), our cause bisection
strategy times out while trying to iterate over all reachable tags.
Try to be smarter and only take a subset of them, thus limiting the time
we spend detecting the bug-free release.
Closes #3376.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Consider the following situation: we're fix bisecting an lts bug on the
mainline tree. Reproducer works on lts HEAD, but does not crash the
mainline.
If the bug was not introduced in the mainline, but it's a purely lts
bug, bisection would currently end up pointing to the mainline HEAD
(in #4123, we assume env.commit to be a commit on the tree we're
currently bisecting, otherwise we'd always hit the same merge base
commit).
Let's first determine 100% correct bisection range on the mainline tree
by testing that both the HEAD does not crash (we already do) and by
testing that the new starting commit (=merge base) can be crashed by the
reproducer.
|
| |
|
|
|
|
|
|
| |
For cause bisections, don't require Kernel.Commit to be reachable from
Kernel.Branch. We can start cause bisections from any existing commit.
This should help with linux-next bisections, where no older HEADs are
ever reachable from each new `master`.
|
| |
|
|
|
|
|
|
|
|
|
|
| |
If there's a merge from a branch that was based on a much older
revision, it's likely that it does not YET contain the bug. If we don't
consider this possibility, we're likely to get invalid fix bisection
results for bugs that existed only for a short period of time.
For every fix bisection step, determine first whether the guilty
revision is reachable from it. Cache resuls to speed up processing.
See #4117.
|
| |
|
|
|
| |
Move predicate code out of env.bisect(). The function is already too
complicated.
|
| |
|
|
|
| |
We incorrectly log crash verdicts twice, which makes bisection logs more
confusing. Don't do that.
|
| | |
|
| | |
|
| |
|
|
|
|
|
|
| |
It might be the case that the kernels that are being fuzzed on syz-ci
require their own backports to build/test older revisions during
bisection.
Let users specify it in the syz-ci config.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Estimate reproducer's flakiness more carefully, as it can help us get
better results.
During config minimization, do not let reproducibility drop too low.
For each test() run, estimate our confidence in the result. For now,
only consider the false negative case: if we got no crashes, it's likely
that the bug is there, but the reproducer was not lucky enough. Given an
estimate of reproduction likelihood, we can easily calculate the chance
of an invalid result: (1-probability)^runs.
Combine all individual test() confidences into Result.Confidence. If the
resulting Confidence is too low, ignore the bisection result.
|
| |
|
|
|
| |
After the previous change, pkg/bisect is unable to bisect SYZFATAL
errors. Fix the bug in the logic and add a test.
|
| |
|
|
|
|
|
|
|
| |
There are cases when a crash, even though it didn't occur during boot
and image testing phases, still should not be counted during bisection.
Otherwise we risk diverting the whole process in the wrong direction.
One of such problem classes is getting SYZFATAL errors when we are not
bisecting a SYZFATAL crash.
|
| |
|
|
|
|
|
|
|
|
| |
Refactor Minimize().
As a part of Minimize(), attempt to drop all unnecessary instrumentation
and test whether the kernel is still crashing.
This should reduce the number of irrelevant crashes during bisection and
thus increase bisection result quality.
|
| |
|
|
|
|
|
|
|
| |
This will later help in adjusting kernel configuration.
Also, adjust how test() determines the crash report: pick the one with
the most frequent type. Earlier we were taking the last crash report,
but this seems to have a bias towards the crashes that take longer to
appear (e.g. rcu stalls).
|
| |
|
|
|
|
|
|
|
| |
1) For the good verdict, demand a certain minimum number of good runs to
be present.
2) For the bad verdict, demand that at least 50% of runs did not fail
with boot/image test error.
Refactor the code and add tests.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The current code only supports fix/cause bisections when the known bad
commit is reachable from Kernel.Repo/Kernel.Branch.
Add a CrossTree parameter to pkg/bisect. If it's set to true and we're
doing a fix bisection, the bisection algorithm first operates with the
original commit message (i.e. checks that it indeed crashes the kernel
and performs config minimization), but the actual bisection starts from
the merge base of Commit and Branch.
We could have calculated the merge base outside of pkg/bisect and just
started the algorithm from that merge base, but there's a problem:
there's no guarantee that the kernel will build/boot with a syzbot
config at the merge base. So we take the commit known to work well and
then assume that the bug is also present on the merge base commit. If it
were not present, we wouldn't have found a fix commit from Branch
anyway.
|
| |
|
|
|
|
|
|
|
| |
If there are only a few non-crashed results among many boot/test errors,
we cannot really be sure that the commit is good. It might be that the
reproducer is not 100% reliable and we just needed more runs.
Require > 50% of runs to be successful in order to claim that the
revision is good. Otherwise skip it.
|
| |
|
|
| |
This will let us later restart them automatically.
|
| |
|
|
|
|
| |
There's not much sense to continue the bisection if something in the
testing infrastructure got broken. Indicate it with the InfraError
error.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Background info:
When a bisection is started, we only know the kernel commit on which
syzkaller encountered the crash. Before the actual bisection begins,
bisect() needs to find a good commit. Then we can bisect between them.
For fix bisections bisect() tests HEAD. If HEAD doesn't have the bug
the fixing commit must be somewhere in the middle. For cause bisection
we test a number of old releases, starting with the newest release.
Both this commit range search and the actual bisection later use test()
to build the kernel and run the reproducer.
During actual bisections we invoke test() for every step. If any test()
invocation returns a non nil error, the bisection it was called from
is aborted. Any non-fatal errors should be signaled via the testResult
returned from test(). For this reason a build/boot failure does not
return an error. Instead testResult.verdict will be vcs.BisectSkip.
The Problem:
Given the following call stack:
bisect() -> commitRange() -> commitRangeFor{Fix,Cause}() -> test()
Previously we reported fix bisections, where HEAD was build broken and
cause bisections where all tested releases were build broken as
inconclusive.
This is confusing for users. For fix bisections it looks like the
fixing commit is either the commit from the original crash or HEAD.
For cause bisections it looks like the breaking commit is either the
original commit or the commit of the oldest tested release. Neither
is correct.
For fix bisections we see this, when the HEAD of a tested branch is
build broken. When this happens all attempted fix bisections will get
nonsense results. For cause bisections we see this, when changes to the
bisection compilers or test rootfs cause us to not be able to build or
boot very old kernels.
These inconclusive bisection results will not be retried automatically
and we don't have an easy way to clear them.
The Solution:
For fix bisections: Retry the bisection later. If HEAD is completely
broken we will know, because fuzzing will stop.
For cause bisections: Mark the bisection as failed. The result is
unlikely to change in the future without intervention by the syzbot
admins. Users won't bother looking at those bisections and the
dashboard already has code to mass-retry failed bisections.
- In test(): Populate testResult.rep with a meaningful report before
returning, after build/boot failures.
- In bisect(): Explicitly check the testResult.verdict of the last
commit tested in commitRange(), instead of using testResult.rep==nil
as an oracle for aborting the bisection.
- In bisect(): Don't return an inconclusive result when build/boot
failures prevent us from finding a commit range to bisect between.
|
| |
|
|
| |
This will help reduce the number of overcommitted VMs.
|
| |
|
|
|
|
|
|
| |
Currently it's held during the whole job processing, which can take too
long.
Adjust it so that it's only taken when we really begin to build the
kernel or syzkaller.
|
| | |
|
| |
|
|
|
|
| |
Previously we only used the linter from the syz-ci config when building
the kernel for regular fuzzing. We were missing some plumbing to have
this setting reach patch testing and bisection jobs.
|
| |
|
|
|
|
|
| |
This allows us to bisect at least recently introduced bugs, where the
manager that found the bug uses a non standard compiler. This is usefull
during development of a new sanitizer for which a compiler with
non-upstreamed patches is required.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
When bisecting a breaking commit, syzkaller starts the bisection from
the commit recorded in the last crash for the given bug. Previously the
bisection was aborted should the commit no longer exist in the repo.
Now we try to reidentify the breaking commit. For git pretty much the
best we can do is to search a commit reachable from HEAD with the same
title. Other VCS systems might have something better.
Syzkaller will still first validate that the start commit is indeed
broken in the way it expects. This prevents syzkaller from getting
confused should we accidentally pick a completely unrelated commit.
|
| |
|
|
|
| |
Before we hardcoded bisection to use gcc, now the compiler family can
be configured in the bisection config.
|
| | |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
During a bisection the call stack looks like this:
Starting at env.bisect() in pkg/bisect/bisect.go
bisect() -> Bisect() -> pred() -> test() -> build()
Previously the `results[testRes1.com.Hash]` in pred() could run into a
nil pointer deref and crash, when:
* build() didn't bother to return current in certain error conditions
* test() didn't handle cases where build() couldn't query current
When test() returns an error, the bisection it was called from is
aborted. Hence test() is expected to not simply bubble up recoverable
errors, but instead return a testResult with verdict=vcs.BisectSkip.
I ran into this with a linux branch, where syzkaller could not find any
release tags, running into one of the cases where build() did not return
current, even though it was able to obtain it.
|
| |
|
|
|
|
|
|
| |
Log bisection date and hostname of the bisecting machine for
the debugging purposes. It makes more easy to check bisection
problems on the bisecting host if something goes wrong.
Signed-off-by: Denis Efremov <denis.e.efremov@oracle.com>
|
| |
|
|
|
| |
This might help get more insight into patch testing failures, especially
for old bugs.
|
| |
|
|
|
|
| |
Currently syzbot only saves a log if there was a build/test error.
Closes #3185
|
| |
|
|
|
|
|
|
|
| |
Default compilers are specified in the OS- and platform-dependent logic.
It is more convenient to extract info about them during the kernel build
itself, rather than during the manager object initialization.
Apply the necessary changes throughout the code that is involved in
building the kernels and processing information about this process.
|