| 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
|
| |
|
|
|
|
| |
What we need is the category for "matched unknown KASAN bug".
This king on bugs should be recategorised.
The final goal is to keep this category empty.
|
| |
|
|
| |
We want to prioritize KASAN bugs differently.
|
| | |
|
| |
|
|
| |
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 function is similar to minimize.Slice(), but it allows to designate
a subset of slice elements that must always remain.
|
| |
|
|
| |
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`.
|
| |
|
|
|
|
|
|
|
|
| |
Merge history is quite complicated in the 500-600 range. Depending on
randomly selected `git bisect skip` values, output might be different.
If 500 is randomly selected, it will not be among skipped values. If 650
is selected first, it excludes 500.
Use the 600-700 range instead. It's stable.
|
| |
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
|
| |
Currently we assume that a bug is present in all revisions before the
culprit one (or, alternatively, in all revisions after it).
The reality is more complicated, so let's split culprit into introduced
and fixCommit. Use commit titles instead of numbers as it provides more
flexibility.
|
| |
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Given a set of chunks and a predicate, the algorithm does the following:
a) If the chunk is not needed (*), drop it.
b) Split the chunk in two and attempt to drop these halves individually.
Optimizations are applied to avoid unneeded predicate invokations.
Also, the algorithm proceeds from larger to smaller chunks, thus
providing on average the best possible result at each step.
This represents the generic functionality needed both for program
bisection in pkg/repro and kernel config bisection in pkg/kconfig.
(*) Needed means that the predicate returns true when the chunk is
present and false when it's removed.
|
| |
|
|
|
| |
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.
|