2017-06-30 13:58:14 +00:00
|
|
|
// Copyright 2017 syzkaller project authors. All rights reserved.
|
|
|
|
// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
|
|
|
|
|
2018-05-03 11:53:01 +00:00
|
|
|
// Package dashapi defines data structures used in dashboard communication
|
2017-06-30 13:58:14 +00:00
|
|
|
// and provides client interface.
|
|
|
|
package dashapi
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
|
|
|
"compress/gzip"
|
|
|
|
"encoding/json"
|
|
|
|
"fmt"
|
|
|
|
"io"
|
|
|
|
"io/ioutil"
|
|
|
|
"net/http"
|
|
|
|
"net/url"
|
2017-07-25 18:25:53 +00:00
|
|
|
"reflect"
|
2017-06-30 13:58:14 +00:00
|
|
|
"strings"
|
2017-11-30 16:14:18 +00:00
|
|
|
"time"
|
2017-06-30 13:58:14 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
type Dashboard struct {
|
2018-06-11 08:02:46 +00:00
|
|
|
Client string
|
|
|
|
Addr string
|
|
|
|
Key string
|
|
|
|
ctor RequestCtor
|
|
|
|
doer RequestDoer
|
|
|
|
logger RequestLogger
|
|
|
|
errorHandler func(error)
|
2017-06-30 13:58:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func New(client, addr, key string) *Dashboard {
|
2018-06-11 08:02:46 +00:00
|
|
|
return NewCustom(client, addr, key, http.NewRequest, http.DefaultClient.Do, nil, nil)
|
|
|
|
}
|
|
|
|
|
|
|
|
type (
|
|
|
|
RequestCtor func(method, url string, body io.Reader) (*http.Request, error)
|
|
|
|
RequestDoer func(req *http.Request) (*http.Response, error)
|
|
|
|
RequestLogger func(msg string, args ...interface{})
|
|
|
|
)
|
|
|
|
|
|
|
|
func NewCustom(client, addr, key string, ctor RequestCtor, doer RequestDoer,
|
|
|
|
logger RequestLogger, errorHandler func(error)) *Dashboard {
|
2017-06-30 13:58:14 +00:00
|
|
|
return &Dashboard{
|
2018-06-11 08:02:46 +00:00
|
|
|
Client: client,
|
|
|
|
Addr: addr,
|
|
|
|
Key: key,
|
|
|
|
ctor: ctor,
|
|
|
|
doer: doer,
|
|
|
|
logger: logger,
|
|
|
|
errorHandler: errorHandler,
|
2017-06-30 13:58:14 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Build describes all aspects of a kernel build.
|
|
|
|
type Build struct {
|
2019-03-22 17:38:28 +00:00
|
|
|
Manager string
|
|
|
|
ID string
|
|
|
|
OS string
|
|
|
|
Arch string
|
|
|
|
VMArch string
|
|
|
|
SyzkallerCommit string
|
|
|
|
SyzkallerCommitDate time.Time
|
|
|
|
CompilerID string
|
|
|
|
KernelRepo string
|
|
|
|
KernelBranch string
|
|
|
|
KernelCommit string
|
|
|
|
KernelCommitTitle string
|
|
|
|
KernelCommitDate time.Time
|
|
|
|
KernelConfig []byte
|
|
|
|
Commits []string // see BuilderPoll
|
|
|
|
FixCommits []Commit
|
2017-12-25 11:07:06 +00:00
|
|
|
}
|
|
|
|
|
2019-02-14 09:35:03 +00:00
|
|
|
type Commit struct {
|
dashboard/app, syz-ci: bisection support
This adds bulk of support for bisection to dashboard/app and syz-ci:
- APIs to send bisection jobs and accept results
- syz-ci logic to execute bisection jobs
- formatting of emails with results
- showing of results on dashboard
Some difficulties we have to overcome:
- since linux is frequently build/boot broken, lots of bisections are inconclusive,
need to present such results too
- git bisect is poorly suitable for automation, have to resort to output parsing (is output stable?)
- git bisect turns out to fail (exit with non-0 status) when bisection is inconclusive
(multiple potential cause commits)
- older syzkaller revisions can't be built with newer (broken) kernel header, e.g.:
ebtables.h:197:19: error: invalid conversion from ‘void*’ to ‘ebt_entry_target*’
- newer compilers produce more warnings and break old syzkaller builds, e.g.:
kvm.S.h:6:12: error: ‘kvm_asm64_vm86’ defined but not used [-Werror=unused-const-variable=]
- figuring relevant emails to CC from a commit is non-trivial:
besides commit author, there can be some emails in commit tags, or not,
which tags to use is an interesting question (some may include irrelevant emails)
we can also run get_maintainers.pl on the commit, but this can produce too wide
list if commit touches lots of files, it can also produce too small list,
and then we need to resort to blame
- for inconclusive bisection we probably don't need to include emails referenced
in the commits (there can be too many of these commits)
- need to be careful to exclude own syzbot email from commit CC list,
now syzbot emails are referenced in some commits (Reported-by/Tested-by/etc)
(can cause some kind of infinite recursion)
- lots of commits reference stable mailing list,
we should not include it in CC because it's referenced for backports rather then bug reports
- since we add new Bug entity fields which we use in queries,
whole datastore need to be upgrades to add the new field to index
- we must not discard the crash that was used for bisection
(treat it as a reported crash)
- bisection results need 2 forms of reports:
one when we add bisection results to already reported bug
another when we report a bug first time with bisection results
- when reporting a bug with bisection results we need to use the crash
that was used for bisection
- some fraction of bisections will probably fail with various errors
and we will need some mechanism to retry bisection after the root cause is resolved
this is not implemented yet
- linux-next is problematic for 2 reasons:
fix bisection can't possibly run on linux-next as commits are not reachable from HEAD
lots of commits are missing in linux-next (even in linux-next-history)
e.g. we have some c63e9e91a254a52 which is now missing in linux-next/linux-next-history
- older kernels can't be build with fresh gcc/binutils/perl/make/glibc
for now we have to stop at v3.9 (this only requires switching gcc several times along the way)
- kernels past v4.11 do not build with gcc 7 and 8 (undefined reference to `____ilog2_NaN')
- v4.1 and back have only compiler-gcc5.h
- v3.17 and back have only compiler-gcc4.h
- v3.6 and back do not have make olddefconfig
- compat socket calls can't be bisected past "x86/entry/syscalls: Wire up 32-bit
direct socket calls" (v4.10) because of
https://syzkaller.appspot.com/bug?id=b5b150e322d5f48c869bcf1528cdbee08d1421cb
- v2.6.28 and below does not work with modern make:
*** mixed implicit and normal rules: deprecated syntax
- v3.8 build fails:
Can't use 'defined(@array)' (Maybe you should just omit the defined()?) at kernel/timeconst.pl line 373.
kernel/Makefile:134: recipe for target 'kernel/timeconst.h' failed
- make 3.81 works for v2.6.28.
3.81 almost works with current HEAD, you need to run make twice because first run spuriously fails with:
- v2.6.28 with gcc-4.9.4 broken with:
include/linux/kvm.h:240:9: error: duplicate member ‘padding’
- but even defconfig fails:
VDSO arch/x86/vdso/vdso.so.dbg
gcc: error: elf_x86_64: No such file or directory
gcc: error: unrecognized command line option ‘-m’
It seems that we also need old binutils.
- for v3.8 and below we need perl-5.14.4.
Unfortunately this or any manually built perl doesn't work for later kernels:
Can't locate strict.pm in @INC
- kernels starting from 4.14 and older are boot broken:
https://lkml.org/lkml/2018/9/7/648
- kernels older than 4.12 are broken during netdev setup
(fixed by commit 675c8da049fd6556eb2d6cdd745fe812752f07a8)
Update #501
2019-03-02 08:45:27 +00:00
|
|
|
Hash string
|
|
|
|
Title string
|
|
|
|
Author string
|
|
|
|
AuthorName string
|
|
|
|
CC []string
|
|
|
|
BugIDs []string // ID's extracted from Reported-by tags
|
|
|
|
Date time.Time
|
2017-06-30 13:58:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (dash *Dashboard) UploadBuild(build *Build) error {
|
2018-06-11 08:02:46 +00:00
|
|
|
return dash.Query("upload_build", build, nil)
|
2017-06-30 13:58:14 +00:00
|
|
|
}
|
|
|
|
|
2017-07-27 15:02:47 +00:00
|
|
|
// BuilderPoll request is done by kernel builder before uploading a new build
|
2017-12-25 11:07:06 +00:00
|
|
|
// with UploadBuild request. Response contains list of commit titles that
|
|
|
|
// dashboard is interested in (i.e. commits that fix open bugs) and email that
|
|
|
|
// appears in Reported-by tags for bug ID extraction. When uploading a new build
|
|
|
|
// builder will pass subset of the commit titles that are present in the build
|
|
|
|
// in Build.Commits field and list of {bug ID, commit title} pairs extracted
|
|
|
|
// from git log.
|
2017-07-27 15:02:47 +00:00
|
|
|
|
|
|
|
type BuilderPollReq struct {
|
|
|
|
Manager string
|
|
|
|
}
|
|
|
|
|
|
|
|
type BuilderPollResp struct {
|
|
|
|
PendingCommits []string
|
2017-12-25 11:07:06 +00:00
|
|
|
ReportEmail string
|
2017-07-27 15:02:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (dash *Dashboard) BuilderPoll(manager string) (*BuilderPollResp, error) {
|
|
|
|
req := &BuilderPollReq{
|
|
|
|
Manager: manager,
|
|
|
|
}
|
|
|
|
resp := new(BuilderPollResp)
|
2018-06-11 08:02:46 +00:00
|
|
|
err := dash.Query("builder_poll", req, resp)
|
2017-07-27 15:02:47 +00:00
|
|
|
return resp, err
|
|
|
|
}
|
|
|
|
|
2017-11-10 13:02:34 +00:00
|
|
|
// Jobs workflow:
|
|
|
|
// - syz-ci sends JobPollReq periodically to check for new jobs,
|
|
|
|
// request contains list of managers that this syz-ci runs.
|
|
|
|
// - dashboard replies with JobPollResp that contains job details,
|
|
|
|
// if no new jobs available ID is set to empty string.
|
|
|
|
// - when syz-ci finishes the job, it sends JobDoneReq which contains
|
|
|
|
// job execution result (Build, Crash or Error details),
|
|
|
|
// ID must match JobPollResp.ID.
|
|
|
|
|
|
|
|
type JobPollReq struct {
|
2019-11-27 15:40:04 +00:00
|
|
|
Managers map[string]ManagerJobs
|
|
|
|
}
|
|
|
|
|
|
|
|
type ManagerJobs struct {
|
|
|
|
TestPatches bool
|
|
|
|
BisectCause bool
|
|
|
|
BisectFix bool
|
2017-11-10 13:02:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
type JobPollResp struct {
|
2019-03-22 09:37:50 +00:00
|
|
|
ID string
|
|
|
|
Type JobType
|
|
|
|
Manager string
|
|
|
|
KernelRepo string
|
|
|
|
KernelBranch string
|
|
|
|
KernelCommit string
|
|
|
|
KernelCommitTitle string
|
|
|
|
KernelCommitDate time.Time
|
|
|
|
KernelConfig []byte
|
|
|
|
SyzkallerCommit string
|
|
|
|
Patch []byte
|
|
|
|
ReproOpts []byte
|
|
|
|
ReproSyz []byte
|
|
|
|
ReproC []byte
|
2017-11-10 13:02:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
type JobDoneReq struct {
|
|
|
|
ID string
|
|
|
|
Build Build
|
|
|
|
Error []byte
|
dashboard/app, syz-ci: bisection support
This adds bulk of support for bisection to dashboard/app and syz-ci:
- APIs to send bisection jobs and accept results
- syz-ci logic to execute bisection jobs
- formatting of emails with results
- showing of results on dashboard
Some difficulties we have to overcome:
- since linux is frequently build/boot broken, lots of bisections are inconclusive,
need to present such results too
- git bisect is poorly suitable for automation, have to resort to output parsing (is output stable?)
- git bisect turns out to fail (exit with non-0 status) when bisection is inconclusive
(multiple potential cause commits)
- older syzkaller revisions can't be built with newer (broken) kernel header, e.g.:
ebtables.h:197:19: error: invalid conversion from ‘void*’ to ‘ebt_entry_target*’
- newer compilers produce more warnings and break old syzkaller builds, e.g.:
kvm.S.h:6:12: error: ‘kvm_asm64_vm86’ defined but not used [-Werror=unused-const-variable=]
- figuring relevant emails to CC from a commit is non-trivial:
besides commit author, there can be some emails in commit tags, or not,
which tags to use is an interesting question (some may include irrelevant emails)
we can also run get_maintainers.pl on the commit, but this can produce too wide
list if commit touches lots of files, it can also produce too small list,
and then we need to resort to blame
- for inconclusive bisection we probably don't need to include emails referenced
in the commits (there can be too many of these commits)
- need to be careful to exclude own syzbot email from commit CC list,
now syzbot emails are referenced in some commits (Reported-by/Tested-by/etc)
(can cause some kind of infinite recursion)
- lots of commits reference stable mailing list,
we should not include it in CC because it's referenced for backports rather then bug reports
- since we add new Bug entity fields which we use in queries,
whole datastore need to be upgrades to add the new field to index
- we must not discard the crash that was used for bisection
(treat it as a reported crash)
- bisection results need 2 forms of reports:
one when we add bisection results to already reported bug
another when we report a bug first time with bisection results
- when reporting a bug with bisection results we need to use the crash
that was used for bisection
- some fraction of bisections will probably fail with various errors
and we will need some mechanism to retry bisection after the root cause is resolved
this is not implemented yet
- linux-next is problematic for 2 reasons:
fix bisection can't possibly run on linux-next as commits are not reachable from HEAD
lots of commits are missing in linux-next (even in linux-next-history)
e.g. we have some c63e9e91a254a52 which is now missing in linux-next/linux-next-history
- older kernels can't be build with fresh gcc/binutils/perl/make/glibc
for now we have to stop at v3.9 (this only requires switching gcc several times along the way)
- kernels past v4.11 do not build with gcc 7 and 8 (undefined reference to `____ilog2_NaN')
- v4.1 and back have only compiler-gcc5.h
- v3.17 and back have only compiler-gcc4.h
- v3.6 and back do not have make olddefconfig
- compat socket calls can't be bisected past "x86/entry/syscalls: Wire up 32-bit
direct socket calls" (v4.10) because of
https://syzkaller.appspot.com/bug?id=b5b150e322d5f48c869bcf1528cdbee08d1421cb
- v2.6.28 and below does not work with modern make:
*** mixed implicit and normal rules: deprecated syntax
- v3.8 build fails:
Can't use 'defined(@array)' (Maybe you should just omit the defined()?) at kernel/timeconst.pl line 373.
kernel/Makefile:134: recipe for target 'kernel/timeconst.h' failed
- make 3.81 works for v2.6.28.
3.81 almost works with current HEAD, you need to run make twice because first run spuriously fails with:
- v2.6.28 with gcc-4.9.4 broken with:
include/linux/kvm.h:240:9: error: duplicate member ‘padding’
- but even defconfig fails:
VDSO arch/x86/vdso/vdso.so.dbg
gcc: error: elf_x86_64: No such file or directory
gcc: error: unrecognized command line option ‘-m’
It seems that we also need old binutils.
- for v3.8 and below we need perl-5.14.4.
Unfortunately this or any manually built perl doesn't work for later kernels:
Can't locate strict.pm in @INC
- kernels starting from 4.14 and older are boot broken:
https://lkml.org/lkml/2018/9/7/648
- kernels older than 4.12 are broken during netdev setup
(fixed by commit 675c8da049fd6556eb2d6cdd745fe812752f07a8)
Update #501
2019-03-02 08:45:27 +00:00
|
|
|
Log []byte // bisection log
|
2017-11-10 13:02:34 +00:00
|
|
|
CrashTitle string
|
|
|
|
CrashLog []byte
|
|
|
|
CrashReport []byte
|
dashboard/app, syz-ci: bisection support
This adds bulk of support for bisection to dashboard/app and syz-ci:
- APIs to send bisection jobs and accept results
- syz-ci logic to execute bisection jobs
- formatting of emails with results
- showing of results on dashboard
Some difficulties we have to overcome:
- since linux is frequently build/boot broken, lots of bisections are inconclusive,
need to present such results too
- git bisect is poorly suitable for automation, have to resort to output parsing (is output stable?)
- git bisect turns out to fail (exit with non-0 status) when bisection is inconclusive
(multiple potential cause commits)
- older syzkaller revisions can't be built with newer (broken) kernel header, e.g.:
ebtables.h:197:19: error: invalid conversion from ‘void*’ to ‘ebt_entry_target*’
- newer compilers produce more warnings and break old syzkaller builds, e.g.:
kvm.S.h:6:12: error: ‘kvm_asm64_vm86’ defined but not used [-Werror=unused-const-variable=]
- figuring relevant emails to CC from a commit is non-trivial:
besides commit author, there can be some emails in commit tags, or not,
which tags to use is an interesting question (some may include irrelevant emails)
we can also run get_maintainers.pl on the commit, but this can produce too wide
list if commit touches lots of files, it can also produce too small list,
and then we need to resort to blame
- for inconclusive bisection we probably don't need to include emails referenced
in the commits (there can be too many of these commits)
- need to be careful to exclude own syzbot email from commit CC list,
now syzbot emails are referenced in some commits (Reported-by/Tested-by/etc)
(can cause some kind of infinite recursion)
- lots of commits reference stable mailing list,
we should not include it in CC because it's referenced for backports rather then bug reports
- since we add new Bug entity fields which we use in queries,
whole datastore need to be upgrades to add the new field to index
- we must not discard the crash that was used for bisection
(treat it as a reported crash)
- bisection results need 2 forms of reports:
one when we add bisection results to already reported bug
another when we report a bug first time with bisection results
- when reporting a bug with bisection results we need to use the crash
that was used for bisection
- some fraction of bisections will probably fail with various errors
and we will need some mechanism to retry bisection after the root cause is resolved
this is not implemented yet
- linux-next is problematic for 2 reasons:
fix bisection can't possibly run on linux-next as commits are not reachable from HEAD
lots of commits are missing in linux-next (even in linux-next-history)
e.g. we have some c63e9e91a254a52 which is now missing in linux-next/linux-next-history
- older kernels can't be build with fresh gcc/binutils/perl/make/glibc
for now we have to stop at v3.9 (this only requires switching gcc several times along the way)
- kernels past v4.11 do not build with gcc 7 and 8 (undefined reference to `____ilog2_NaN')
- v4.1 and back have only compiler-gcc5.h
- v3.17 and back have only compiler-gcc4.h
- v3.6 and back do not have make olddefconfig
- compat socket calls can't be bisected past "x86/entry/syscalls: Wire up 32-bit
direct socket calls" (v4.10) because of
https://syzkaller.appspot.com/bug?id=b5b150e322d5f48c869bcf1528cdbee08d1421cb
- v2.6.28 and below does not work with modern make:
*** mixed implicit and normal rules: deprecated syntax
- v3.8 build fails:
Can't use 'defined(@array)' (Maybe you should just omit the defined()?) at kernel/timeconst.pl line 373.
kernel/Makefile:134: recipe for target 'kernel/timeconst.h' failed
- make 3.81 works for v2.6.28.
3.81 almost works with current HEAD, you need to run make twice because first run spuriously fails with:
- v2.6.28 with gcc-4.9.4 broken with:
include/linux/kvm.h:240:9: error: duplicate member ‘padding’
- but even defconfig fails:
VDSO arch/x86/vdso/vdso.so.dbg
gcc: error: elf_x86_64: No such file or directory
gcc: error: unrecognized command line option ‘-m’
It seems that we also need old binutils.
- for v3.8 and below we need perl-5.14.4.
Unfortunately this or any manually built perl doesn't work for later kernels:
Can't locate strict.pm in @INC
- kernels starting from 4.14 and older are boot broken:
https://lkml.org/lkml/2018/9/7/648
- kernels older than 4.12 are broken during netdev setup
(fixed by commit 675c8da049fd6556eb2d6cdd745fe812752f07a8)
Update #501
2019-03-02 08:45:27 +00:00
|
|
|
// Bisection results:
|
|
|
|
// If there is 0 commits:
|
|
|
|
// - still happens on HEAD for fix bisection
|
|
|
|
// - already happened on the oldest release
|
|
|
|
// If there is 1 commits: bisection result (cause or fix).
|
|
|
|
// If there are more than 1: suspected commits due to skips (broken build/boot).
|
|
|
|
Commits []Commit
|
2019-11-06 16:59:11 +00:00
|
|
|
Flags JobDoneFlags
|
2017-11-10 13:02:34 +00:00
|
|
|
}
|
|
|
|
|
dashboard/app, syz-ci: bisection support
This adds bulk of support for bisection to dashboard/app and syz-ci:
- APIs to send bisection jobs and accept results
- syz-ci logic to execute bisection jobs
- formatting of emails with results
- showing of results on dashboard
Some difficulties we have to overcome:
- since linux is frequently build/boot broken, lots of bisections are inconclusive,
need to present such results too
- git bisect is poorly suitable for automation, have to resort to output parsing (is output stable?)
- git bisect turns out to fail (exit with non-0 status) when bisection is inconclusive
(multiple potential cause commits)
- older syzkaller revisions can't be built with newer (broken) kernel header, e.g.:
ebtables.h:197:19: error: invalid conversion from ‘void*’ to ‘ebt_entry_target*’
- newer compilers produce more warnings and break old syzkaller builds, e.g.:
kvm.S.h:6:12: error: ‘kvm_asm64_vm86’ defined but not used [-Werror=unused-const-variable=]
- figuring relevant emails to CC from a commit is non-trivial:
besides commit author, there can be some emails in commit tags, or not,
which tags to use is an interesting question (some may include irrelevant emails)
we can also run get_maintainers.pl on the commit, but this can produce too wide
list if commit touches lots of files, it can also produce too small list,
and then we need to resort to blame
- for inconclusive bisection we probably don't need to include emails referenced
in the commits (there can be too many of these commits)
- need to be careful to exclude own syzbot email from commit CC list,
now syzbot emails are referenced in some commits (Reported-by/Tested-by/etc)
(can cause some kind of infinite recursion)
- lots of commits reference stable mailing list,
we should not include it in CC because it's referenced for backports rather then bug reports
- since we add new Bug entity fields which we use in queries,
whole datastore need to be upgrades to add the new field to index
- we must not discard the crash that was used for bisection
(treat it as a reported crash)
- bisection results need 2 forms of reports:
one when we add bisection results to already reported bug
another when we report a bug first time with bisection results
- when reporting a bug with bisection results we need to use the crash
that was used for bisection
- some fraction of bisections will probably fail with various errors
and we will need some mechanism to retry bisection after the root cause is resolved
this is not implemented yet
- linux-next is problematic for 2 reasons:
fix bisection can't possibly run on linux-next as commits are not reachable from HEAD
lots of commits are missing in linux-next (even in linux-next-history)
e.g. we have some c63e9e91a254a52 which is now missing in linux-next/linux-next-history
- older kernels can't be build with fresh gcc/binutils/perl/make/glibc
for now we have to stop at v3.9 (this only requires switching gcc several times along the way)
- kernels past v4.11 do not build with gcc 7 and 8 (undefined reference to `____ilog2_NaN')
- v4.1 and back have only compiler-gcc5.h
- v3.17 and back have only compiler-gcc4.h
- v3.6 and back do not have make olddefconfig
- compat socket calls can't be bisected past "x86/entry/syscalls: Wire up 32-bit
direct socket calls" (v4.10) because of
https://syzkaller.appspot.com/bug?id=b5b150e322d5f48c869bcf1528cdbee08d1421cb
- v2.6.28 and below does not work with modern make:
*** mixed implicit and normal rules: deprecated syntax
- v3.8 build fails:
Can't use 'defined(@array)' (Maybe you should just omit the defined()?) at kernel/timeconst.pl line 373.
kernel/Makefile:134: recipe for target 'kernel/timeconst.h' failed
- make 3.81 works for v2.6.28.
3.81 almost works with current HEAD, you need to run make twice because first run spuriously fails with:
- v2.6.28 with gcc-4.9.4 broken with:
include/linux/kvm.h:240:9: error: duplicate member ‘padding’
- but even defconfig fails:
VDSO arch/x86/vdso/vdso.so.dbg
gcc: error: elf_x86_64: No such file or directory
gcc: error: unrecognized command line option ‘-m’
It seems that we also need old binutils.
- for v3.8 and below we need perl-5.14.4.
Unfortunately this or any manually built perl doesn't work for later kernels:
Can't locate strict.pm in @INC
- kernels starting from 4.14 and older are boot broken:
https://lkml.org/lkml/2018/9/7/648
- kernels older than 4.12 are broken during netdev setup
(fixed by commit 675c8da049fd6556eb2d6cdd745fe812752f07a8)
Update #501
2019-03-02 08:45:27 +00:00
|
|
|
type JobType int
|
|
|
|
|
|
|
|
const (
|
|
|
|
JobTestPatch JobType = iota
|
|
|
|
JobBisectCause
|
|
|
|
JobBisectFix
|
|
|
|
)
|
|
|
|
|
2019-11-06 16:59:11 +00:00
|
|
|
type JobDoneFlags int64
|
|
|
|
|
|
|
|
const (
|
2019-11-27 13:05:14 +00:00
|
|
|
BisectResultMerge JobDoneFlags = 1 << iota // bisected to a merge commit
|
|
|
|
BisectResultNoop // commit does not affect resulting kernel binary
|
|
|
|
BisectResultRelease // commit is a kernel release
|
2019-11-06 16:59:11 +00:00
|
|
|
)
|
|
|
|
|
2019-03-20 11:00:34 +00:00
|
|
|
func (dash *Dashboard) JobPoll(req *JobPollReq) (*JobPollResp, error) {
|
2017-11-10 13:02:34 +00:00
|
|
|
resp := new(JobPollResp)
|
2018-06-11 08:02:46 +00:00
|
|
|
err := dash.Query("job_poll", req, resp)
|
2017-11-10 13:02:34 +00:00
|
|
|
return resp, err
|
|
|
|
}
|
|
|
|
|
|
|
|
func (dash *Dashboard) JobDone(req *JobDoneReq) error {
|
2018-06-11 08:02:46 +00:00
|
|
|
return dash.Query("job_done", req, nil)
|
2017-11-10 13:02:34 +00:00
|
|
|
}
|
|
|
|
|
2017-11-29 12:23:42 +00:00
|
|
|
type BuildErrorReq struct {
|
|
|
|
Build Build
|
|
|
|
Crash Crash
|
|
|
|
}
|
|
|
|
|
|
|
|
func (dash *Dashboard) ReportBuildError(req *BuildErrorReq) error {
|
2018-06-11 08:02:46 +00:00
|
|
|
return dash.Query("report_build_error", req, nil)
|
2017-11-29 12:23:42 +00:00
|
|
|
}
|
|
|
|
|
2019-02-14 09:35:03 +00:00
|
|
|
type CommitPollResp struct {
|
|
|
|
ReportEmail string
|
|
|
|
Repos []Repo
|
|
|
|
Commits []string
|
|
|
|
}
|
|
|
|
|
|
|
|
type CommitPollResultReq struct {
|
|
|
|
Commits []Commit
|
|
|
|
}
|
|
|
|
|
|
|
|
type Repo struct {
|
|
|
|
URL string
|
|
|
|
Branch string
|
|
|
|
}
|
|
|
|
|
|
|
|
func (dash *Dashboard) CommitPoll() (*CommitPollResp, error) {
|
|
|
|
resp := new(CommitPollResp)
|
|
|
|
err := dash.Query("commit_poll", nil, resp)
|
|
|
|
return resp, err
|
|
|
|
}
|
|
|
|
|
|
|
|
func (dash *Dashboard) UploadCommits(commits []Commit) error {
|
|
|
|
if len(commits) == 0 {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
return dash.Query("upload_commits", &CommitPollResultReq{commits}, nil)
|
|
|
|
}
|
|
|
|
|
2017-06-30 13:58:14 +00:00
|
|
|
// Crash describes a single kernel crash (potentially with repro).
|
|
|
|
type Crash struct {
|
|
|
|
BuildID string // refers to Build.ID
|
|
|
|
Title string
|
2017-11-21 18:11:54 +00:00
|
|
|
Corrupted bool // report is corrupted (corrupted title, no stacks, etc)
|
2017-06-30 13:58:14 +00:00
|
|
|
Maintainers []string
|
|
|
|
Log []byte
|
|
|
|
Report []byte
|
|
|
|
// The following is optional and is filled only after repro.
|
|
|
|
ReproOpts []byte
|
|
|
|
ReproSyz []byte
|
|
|
|
ReproC []byte
|
|
|
|
}
|
|
|
|
|
2017-08-10 17:29:42 +00:00
|
|
|
type ReportCrashResp struct {
|
|
|
|
NeedRepro bool
|
2017-06-30 13:58:14 +00:00
|
|
|
}
|
|
|
|
|
2017-08-10 17:29:42 +00:00
|
|
|
func (dash *Dashboard) ReportCrash(crash *Crash) (*ReportCrashResp, error) {
|
|
|
|
resp := new(ReportCrashResp)
|
2018-06-11 08:02:46 +00:00
|
|
|
err := dash.Query("report_crash", crash, resp)
|
2017-08-10 17:29:42 +00:00
|
|
|
return resp, err
|
|
|
|
}
|
|
|
|
|
2018-03-08 17:48:26 +00:00
|
|
|
// CrashID is a short summary of a crash for repro queries.
|
2017-08-10 17:29:42 +00:00
|
|
|
type CrashID struct {
|
2017-11-22 09:14:48 +00:00
|
|
|
BuildID string
|
|
|
|
Title string
|
|
|
|
Corrupted bool
|
2017-06-30 13:58:14 +00:00
|
|
|
}
|
|
|
|
|
2017-08-10 17:29:42 +00:00
|
|
|
type NeedReproResp struct {
|
|
|
|
NeedRepro bool
|
|
|
|
}
|
|
|
|
|
|
|
|
// NeedRepro checks if dashboard needs a repro for this crash or not.
|
|
|
|
func (dash *Dashboard) NeedRepro(crash *CrashID) (bool, error) {
|
|
|
|
resp := new(NeedReproResp)
|
2018-06-11 08:02:46 +00:00
|
|
|
err := dash.Query("need_repro", crash, resp)
|
2017-08-10 17:29:42 +00:00
|
|
|
return resp.NeedRepro, err
|
|
|
|
}
|
|
|
|
|
|
|
|
// ReportFailedRepro notifies dashboard about a failed repro attempt for the crash.
|
|
|
|
func (dash *Dashboard) ReportFailedRepro(crash *CrashID) error {
|
2018-06-11 08:02:46 +00:00
|
|
|
return dash.Query("report_failed_repro", crash, nil)
|
2017-06-30 13:58:14 +00:00
|
|
|
}
|
|
|
|
|
2017-07-21 07:43:01 +00:00
|
|
|
type LogEntry struct {
|
|
|
|
Name string
|
|
|
|
Text string
|
|
|
|
}
|
|
|
|
|
|
|
|
// Centralized logging on dashboard.
|
|
|
|
func (dash *Dashboard) LogError(name, msg string, args ...interface{}) {
|
|
|
|
req := &LogEntry{
|
|
|
|
Name: name,
|
|
|
|
Text: fmt.Sprintf(msg, args...),
|
|
|
|
}
|
2018-06-11 08:02:46 +00:00
|
|
|
dash.Query("log_error", req, nil)
|
2017-07-21 07:43:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// BugReport describes a single bug.
|
|
|
|
// Used by dashboard external reporting.
|
|
|
|
type BugReport struct {
|
2019-03-12 12:57:52 +00:00
|
|
|
Type ReportType
|
2018-01-17 18:43:04 +00:00
|
|
|
Namespace string
|
|
|
|
Config []byte
|
|
|
|
ID string
|
|
|
|
JobID string
|
|
|
|
ExtID string // arbitrary reporting ID forwarded from BugUpdate.ExtID
|
2019-03-12 12:57:52 +00:00
|
|
|
First bool // Set for first report for this bug (Type == ReportNew).
|
2019-02-21 17:18:18 +00:00
|
|
|
Moderation bool
|
2018-01-17 18:43:04 +00:00
|
|
|
Title string
|
2019-03-12 12:57:52 +00:00
|
|
|
Link string // link to the bug on dashboard
|
|
|
|
CreditEmail string // email for the Reported-by tag
|
2018-01-17 18:43:04 +00:00
|
|
|
Maintainers []string
|
|
|
|
CC []string // additional CC emails
|
|
|
|
OS string
|
|
|
|
Arch string
|
|
|
|
VMArch string
|
2019-03-12 12:57:52 +00:00
|
|
|
UserSpaceArch string // user-space arch as kernel developers know it (rather than Go names)
|
2018-01-17 18:43:04 +00:00
|
|
|
CompilerID string
|
|
|
|
KernelRepo string
|
|
|
|
KernelRepoAlias string
|
|
|
|
KernelBranch string
|
|
|
|
KernelCommit string
|
|
|
|
KernelCommitTitle string
|
|
|
|
KernelCommitDate time.Time
|
|
|
|
KernelConfig []byte
|
2018-03-23 15:05:16 +00:00
|
|
|
KernelConfigLink string
|
2018-01-17 18:43:04 +00:00
|
|
|
Log []byte
|
2018-03-23 15:05:16 +00:00
|
|
|
LogLink string
|
2018-01-17 18:43:04 +00:00
|
|
|
Report []byte
|
2018-03-23 15:05:16 +00:00
|
|
|
ReportLink string
|
2018-01-17 18:43:04 +00:00
|
|
|
ReproC []byte
|
2018-03-23 15:05:16 +00:00
|
|
|
ReproCLink string
|
2018-01-17 18:43:04 +00:00
|
|
|
ReproSyz []byte
|
2018-03-23 15:05:16 +00:00
|
|
|
ReproSyzLink string
|
2018-01-17 18:43:04 +00:00
|
|
|
CrashID int64 // returned back in BugUpdate
|
2018-01-17 20:50:57 +00:00
|
|
|
NumCrashes int64
|
|
|
|
HappenedOn []string // list of kernel repo aliases
|
2017-11-10 13:02:34 +00:00
|
|
|
|
2019-03-12 12:57:52 +00:00
|
|
|
CrashTitle string // job execution crash title
|
|
|
|
Error []byte // job execution error
|
|
|
|
ErrorLink string
|
|
|
|
ErrorTruncated bool // full Error text is too large and was truncated
|
|
|
|
PatchLink string
|
dashboard/app, syz-ci: bisection support
This adds bulk of support for bisection to dashboard/app and syz-ci:
- APIs to send bisection jobs and accept results
- syz-ci logic to execute bisection jobs
- formatting of emails with results
- showing of results on dashboard
Some difficulties we have to overcome:
- since linux is frequently build/boot broken, lots of bisections are inconclusive,
need to present such results too
- git bisect is poorly suitable for automation, have to resort to output parsing (is output stable?)
- git bisect turns out to fail (exit with non-0 status) when bisection is inconclusive
(multiple potential cause commits)
- older syzkaller revisions can't be built with newer (broken) kernel header, e.g.:
ebtables.h:197:19: error: invalid conversion from ‘void*’ to ‘ebt_entry_target*’
- newer compilers produce more warnings and break old syzkaller builds, e.g.:
kvm.S.h:6:12: error: ‘kvm_asm64_vm86’ defined but not used [-Werror=unused-const-variable=]
- figuring relevant emails to CC from a commit is non-trivial:
besides commit author, there can be some emails in commit tags, or not,
which tags to use is an interesting question (some may include irrelevant emails)
we can also run get_maintainers.pl on the commit, but this can produce too wide
list if commit touches lots of files, it can also produce too small list,
and then we need to resort to blame
- for inconclusive bisection we probably don't need to include emails referenced
in the commits (there can be too many of these commits)
- need to be careful to exclude own syzbot email from commit CC list,
now syzbot emails are referenced in some commits (Reported-by/Tested-by/etc)
(can cause some kind of infinite recursion)
- lots of commits reference stable mailing list,
we should not include it in CC because it's referenced for backports rather then bug reports
- since we add new Bug entity fields which we use in queries,
whole datastore need to be upgrades to add the new field to index
- we must not discard the crash that was used for bisection
(treat it as a reported crash)
- bisection results need 2 forms of reports:
one when we add bisection results to already reported bug
another when we report a bug first time with bisection results
- when reporting a bug with bisection results we need to use the crash
that was used for bisection
- some fraction of bisections will probably fail with various errors
and we will need some mechanism to retry bisection after the root cause is resolved
this is not implemented yet
- linux-next is problematic for 2 reasons:
fix bisection can't possibly run on linux-next as commits are not reachable from HEAD
lots of commits are missing in linux-next (even in linux-next-history)
e.g. we have some c63e9e91a254a52 which is now missing in linux-next/linux-next-history
- older kernels can't be build with fresh gcc/binutils/perl/make/glibc
for now we have to stop at v3.9 (this only requires switching gcc several times along the way)
- kernels past v4.11 do not build with gcc 7 and 8 (undefined reference to `____ilog2_NaN')
- v4.1 and back have only compiler-gcc5.h
- v3.17 and back have only compiler-gcc4.h
- v3.6 and back do not have make olddefconfig
- compat socket calls can't be bisected past "x86/entry/syscalls: Wire up 32-bit
direct socket calls" (v4.10) because of
https://syzkaller.appspot.com/bug?id=b5b150e322d5f48c869bcf1528cdbee08d1421cb
- v2.6.28 and below does not work with modern make:
*** mixed implicit and normal rules: deprecated syntax
- v3.8 build fails:
Can't use 'defined(@array)' (Maybe you should just omit the defined()?) at kernel/timeconst.pl line 373.
kernel/Makefile:134: recipe for target 'kernel/timeconst.h' failed
- make 3.81 works for v2.6.28.
3.81 almost works with current HEAD, you need to run make twice because first run spuriously fails with:
- v2.6.28 with gcc-4.9.4 broken with:
include/linux/kvm.h:240:9: error: duplicate member ‘padding’
- but even defconfig fails:
VDSO arch/x86/vdso/vdso.so.dbg
gcc: error: elf_x86_64: No such file or directory
gcc: error: unrecognized command line option ‘-m’
It seems that we also need old binutils.
- for v3.8 and below we need perl-5.14.4.
Unfortunately this or any manually built perl doesn't work for later kernels:
Can't locate strict.pm in @INC
- kernels starting from 4.14 and older are boot broken:
https://lkml.org/lkml/2018/9/7/648
- kernels older than 4.12 are broken during netdev setup
(fixed by commit 675c8da049fd6556eb2d6cdd745fe812752f07a8)
Update #501
2019-03-02 08:45:27 +00:00
|
|
|
BisectCause *BisectResult
|
|
|
|
BisectFix *BisectResult
|
|
|
|
}
|
|
|
|
|
|
|
|
type BisectResult struct {
|
|
|
|
Commit *Commit // for conclusive bisection
|
|
|
|
Commits []*Commit // for inconclusive bisection
|
|
|
|
LogLink string
|
|
|
|
CrashLogLink string
|
|
|
|
CrashReportLink string
|
2019-08-08 19:35:23 +00:00
|
|
|
Fix bool
|
2017-07-21 07:43:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
type BugUpdate struct {
|
2019-03-19 15:37:21 +00:00
|
|
|
ID string // copied from BugReport
|
|
|
|
JobID string // copied from BugReport
|
2019-02-21 17:18:18 +00:00
|
|
|
ExtID string
|
|
|
|
Link string
|
|
|
|
Status BugStatus
|
|
|
|
ReproLevel ReproLevel
|
|
|
|
DupOf string
|
|
|
|
OnHold bool // If set for open bugs, don't upstream this bug.
|
|
|
|
Notification bool // Reply to a notification.
|
|
|
|
FixCommits []string // Titles of commits that fix this bug.
|
|
|
|
CC []string // Additional emails to add to CC list in future emails.
|
|
|
|
CrashID int64
|
2017-07-21 07:43:01 +00:00
|
|
|
}
|
|
|
|
|
2017-07-25 18:25:05 +00:00
|
|
|
type BugUpdateReply struct {
|
2017-10-23 07:58:09 +00:00
|
|
|
// Bug update can fail for 2 reason:
|
|
|
|
// - update does not pass logical validataion, in this case OK=false
|
|
|
|
// - internal/datastore error, in this case Error=true
|
|
|
|
OK bool
|
|
|
|
Error bool
|
|
|
|
Text string
|
2017-07-25 18:25:05 +00:00
|
|
|
}
|
|
|
|
|
2017-12-08 16:23:26 +00:00
|
|
|
type PollBugsRequest struct {
|
2017-07-21 07:43:01 +00:00
|
|
|
Type string
|
|
|
|
}
|
|
|
|
|
2017-12-08 16:23:26 +00:00
|
|
|
type PollBugsResponse struct {
|
2017-07-21 07:43:01 +00:00
|
|
|
Reports []*BugReport
|
|
|
|
}
|
|
|
|
|
2019-02-21 17:18:18 +00:00
|
|
|
type BugNotification struct {
|
|
|
|
Type BugNotif
|
|
|
|
Namespace string
|
|
|
|
Config []byte
|
|
|
|
ID string
|
|
|
|
ExtID string // arbitrary reporting ID forwarded from BugUpdate.ExtID
|
|
|
|
Title string
|
|
|
|
Text string // meaning depends on Type
|
|
|
|
CC []string // additional CC emails
|
|
|
|
Maintainers []string
|
|
|
|
// Public is what we want all involved people to see (e.g. if we notify about a wrong commit title,
|
|
|
|
// people need to see it and provide the right title). Not public is what we want to send only
|
|
|
|
// to a minimal set of recipients (our mailing list) (e.g. notification about an obsoleted bug
|
|
|
|
// is mostly "for the record").
|
|
|
|
Public bool
|
|
|
|
}
|
|
|
|
|
|
|
|
type PollNotificationsRequest struct {
|
|
|
|
Type string
|
|
|
|
}
|
|
|
|
|
|
|
|
type PollNotificationsResponse struct {
|
|
|
|
Notifications []*BugNotification
|
|
|
|
}
|
|
|
|
|
2017-12-08 16:23:26 +00:00
|
|
|
type PollClosedRequest struct {
|
|
|
|
IDs []string
|
|
|
|
}
|
|
|
|
|
|
|
|
type PollClosedResponse struct {
|
|
|
|
IDs []string
|
|
|
|
}
|
|
|
|
|
2018-06-11 08:02:46 +00:00
|
|
|
func (dash *Dashboard) ReportingPollBugs(typ string) (*PollBugsResponse, error) {
|
|
|
|
req := &PollBugsRequest{
|
|
|
|
Type: typ,
|
|
|
|
}
|
|
|
|
resp := new(PollBugsResponse)
|
|
|
|
if err := dash.Query("reporting_poll_bugs", req, resp); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
return resp, nil
|
|
|
|
}
|
|
|
|
|
2019-02-21 17:18:18 +00:00
|
|
|
func (dash *Dashboard) ReportingPollNotifications(typ string) (*PollNotificationsResponse, error) {
|
|
|
|
req := &PollNotificationsRequest{
|
|
|
|
Type: typ,
|
|
|
|
}
|
|
|
|
resp := new(PollNotificationsResponse)
|
|
|
|
if err := dash.Query("reporting_poll_notifs", req, resp); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
return resp, nil
|
|
|
|
}
|
|
|
|
|
2018-06-11 08:02:46 +00:00
|
|
|
func (dash *Dashboard) ReportingPollClosed(ids []string) ([]string, error) {
|
|
|
|
req := &PollClosedRequest{
|
|
|
|
IDs: ids,
|
|
|
|
}
|
|
|
|
resp := new(PollClosedResponse)
|
|
|
|
if err := dash.Query("reporting_poll_closed", req, resp); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
return resp.IDs, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (dash *Dashboard) ReportingUpdate(upd *BugUpdate) (*BugUpdateReply, error) {
|
|
|
|
resp := new(BugUpdateReply)
|
|
|
|
if err := dash.Query("reporting_update", upd, resp); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
return resp, nil
|
|
|
|
}
|
|
|
|
|
2017-11-30 16:14:18 +00:00
|
|
|
type ManagerStatsReq struct {
|
|
|
|
Name string
|
2017-12-04 10:58:55 +00:00
|
|
|
Addr string
|
|
|
|
|
2017-11-30 16:14:18 +00:00
|
|
|
// Current level:
|
|
|
|
UpTime time.Duration
|
|
|
|
Corpus uint64
|
|
|
|
Cover uint64
|
|
|
|
|
|
|
|
// Delta since last sync:
|
|
|
|
FuzzingTime time.Duration
|
|
|
|
Crashes uint64
|
|
|
|
Execs uint64
|
|
|
|
}
|
|
|
|
|
|
|
|
func (dash *Dashboard) UploadManagerStats(req *ManagerStatsReq) error {
|
2018-06-11 08:02:46 +00:00
|
|
|
return dash.Query("manager_stats", req, nil)
|
2017-11-30 16:14:18 +00:00
|
|
|
}
|
|
|
|
|
2019-10-07 15:50:24 +00:00
|
|
|
type BugListResp struct {
|
|
|
|
List []string
|
|
|
|
}
|
|
|
|
|
|
|
|
func (dash *Dashboard) BugList() (*BugListResp, error) {
|
|
|
|
resp := new(BugListResp)
|
|
|
|
err := dash.Query("bug_list", nil, resp)
|
|
|
|
return resp, err
|
|
|
|
}
|
|
|
|
|
|
|
|
type LoadBugReq struct {
|
|
|
|
ID string
|
|
|
|
}
|
|
|
|
|
|
|
|
type LoadBugResp struct {
|
|
|
|
ID string
|
|
|
|
Title string
|
|
|
|
Status string
|
|
|
|
SyzkallerCommit string
|
|
|
|
Arch string
|
|
|
|
ReproOpts []byte
|
|
|
|
ReproSyz []byte
|
|
|
|
ReproC []byte
|
|
|
|
}
|
|
|
|
|
|
|
|
func (dash *Dashboard) LoadBug(id string) (*LoadBugResp, error) {
|
|
|
|
req := LoadBugReq{id}
|
|
|
|
resp := new(LoadBugResp)
|
|
|
|
err := dash.Query("load_bug", req, resp)
|
|
|
|
return resp, err
|
|
|
|
}
|
|
|
|
|
2017-07-21 07:43:01 +00:00
|
|
|
type (
|
|
|
|
BugStatus int
|
2019-02-21 17:18:18 +00:00
|
|
|
BugNotif int
|
2017-07-21 07:43:01 +00:00
|
|
|
ReproLevel int
|
2019-03-12 12:57:52 +00:00
|
|
|
ReportType int
|
2017-07-21 07:43:01 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
|
|
|
BugStatusOpen BugStatus = iota
|
|
|
|
BugStatusUpstream
|
|
|
|
BugStatusInvalid
|
|
|
|
BugStatusDup
|
2017-08-17 17:09:07 +00:00
|
|
|
BugStatusUpdate // aux info update (i.e. ExtID/Link/CC)
|
2019-03-21 17:18:14 +00:00
|
|
|
BugStatusUnCC // don't CC sender on any future communication
|
2017-07-21 07:43:01 +00:00
|
|
|
)
|
|
|
|
|
2019-02-21 17:18:18 +00:00
|
|
|
const (
|
|
|
|
// Upstream bug into next reporting.
|
|
|
|
// If the action succeeds, reporting sends BugStatusUpstream update.
|
|
|
|
BugNotifUpstream BugNotif = iota
|
|
|
|
// Bug needs to be closed as obsoleted.
|
|
|
|
// If the action succeeds, reporting sends BugStatusInvalid update.
|
|
|
|
BugNotifObsoleted
|
|
|
|
// Bug fixing commit can't be discovered (wrong commit title).
|
|
|
|
BugNotifBadCommit
|
|
|
|
)
|
|
|
|
|
2017-07-21 07:43:01 +00:00
|
|
|
const (
|
|
|
|
ReproLevelNone ReproLevel = iota
|
|
|
|
ReproLevelSyz
|
|
|
|
ReproLevelC
|
|
|
|
)
|
|
|
|
|
2019-03-12 12:57:52 +00:00
|
|
|
const (
|
dashboard/app, syz-ci: bisection support
This adds bulk of support for bisection to dashboard/app and syz-ci:
- APIs to send bisection jobs and accept results
- syz-ci logic to execute bisection jobs
- formatting of emails with results
- showing of results on dashboard
Some difficulties we have to overcome:
- since linux is frequently build/boot broken, lots of bisections are inconclusive,
need to present such results too
- git bisect is poorly suitable for automation, have to resort to output parsing (is output stable?)
- git bisect turns out to fail (exit with non-0 status) when bisection is inconclusive
(multiple potential cause commits)
- older syzkaller revisions can't be built with newer (broken) kernel header, e.g.:
ebtables.h:197:19: error: invalid conversion from ‘void*’ to ‘ebt_entry_target*’
- newer compilers produce more warnings and break old syzkaller builds, e.g.:
kvm.S.h:6:12: error: ‘kvm_asm64_vm86’ defined but not used [-Werror=unused-const-variable=]
- figuring relevant emails to CC from a commit is non-trivial:
besides commit author, there can be some emails in commit tags, or not,
which tags to use is an interesting question (some may include irrelevant emails)
we can also run get_maintainers.pl on the commit, but this can produce too wide
list if commit touches lots of files, it can also produce too small list,
and then we need to resort to blame
- for inconclusive bisection we probably don't need to include emails referenced
in the commits (there can be too many of these commits)
- need to be careful to exclude own syzbot email from commit CC list,
now syzbot emails are referenced in some commits (Reported-by/Tested-by/etc)
(can cause some kind of infinite recursion)
- lots of commits reference stable mailing list,
we should not include it in CC because it's referenced for backports rather then bug reports
- since we add new Bug entity fields which we use in queries,
whole datastore need to be upgrades to add the new field to index
- we must not discard the crash that was used for bisection
(treat it as a reported crash)
- bisection results need 2 forms of reports:
one when we add bisection results to already reported bug
another when we report a bug first time with bisection results
- when reporting a bug with bisection results we need to use the crash
that was used for bisection
- some fraction of bisections will probably fail with various errors
and we will need some mechanism to retry bisection after the root cause is resolved
this is not implemented yet
- linux-next is problematic for 2 reasons:
fix bisection can't possibly run on linux-next as commits are not reachable from HEAD
lots of commits are missing in linux-next (even in linux-next-history)
e.g. we have some c63e9e91a254a52 which is now missing in linux-next/linux-next-history
- older kernels can't be build with fresh gcc/binutils/perl/make/glibc
for now we have to stop at v3.9 (this only requires switching gcc several times along the way)
- kernels past v4.11 do not build with gcc 7 and 8 (undefined reference to `____ilog2_NaN')
- v4.1 and back have only compiler-gcc5.h
- v3.17 and back have only compiler-gcc4.h
- v3.6 and back do not have make olddefconfig
- compat socket calls can't be bisected past "x86/entry/syscalls: Wire up 32-bit
direct socket calls" (v4.10) because of
https://syzkaller.appspot.com/bug?id=b5b150e322d5f48c869bcf1528cdbee08d1421cb
- v2.6.28 and below does not work with modern make:
*** mixed implicit and normal rules: deprecated syntax
- v3.8 build fails:
Can't use 'defined(@array)' (Maybe you should just omit the defined()?) at kernel/timeconst.pl line 373.
kernel/Makefile:134: recipe for target 'kernel/timeconst.h' failed
- make 3.81 works for v2.6.28.
3.81 almost works with current HEAD, you need to run make twice because first run spuriously fails with:
- v2.6.28 with gcc-4.9.4 broken with:
include/linux/kvm.h:240:9: error: duplicate member ‘padding’
- but even defconfig fails:
VDSO arch/x86/vdso/vdso.so.dbg
gcc: error: elf_x86_64: No such file or directory
gcc: error: unrecognized command line option ‘-m’
It seems that we also need old binutils.
- for v3.8 and below we need perl-5.14.4.
Unfortunately this or any manually built perl doesn't work for later kernels:
Can't locate strict.pm in @INC
- kernels starting from 4.14 and older are boot broken:
https://lkml.org/lkml/2018/9/7/648
- kernels older than 4.12 are broken during netdev setup
(fixed by commit 675c8da049fd6556eb2d6cdd745fe812752f07a8)
Update #501
2019-03-02 08:45:27 +00:00
|
|
|
ReportNew ReportType = iota // First report for this bug in the reporting stage.
|
|
|
|
ReportRepro // Found repro for an already reported bug.
|
|
|
|
ReportTestPatch // Patch testing result.
|
|
|
|
ReportBisectCause // Cause bisection result for an already reported bug.
|
|
|
|
ReportBisectFix // Fix bisection result for an already reported bug.
|
2019-03-12 12:57:52 +00:00
|
|
|
)
|
|
|
|
|
2018-06-11 08:02:46 +00:00
|
|
|
func (dash *Dashboard) Query(method string, req, reply interface{}) error {
|
|
|
|
if dash.logger != nil {
|
|
|
|
dash.logger("API(%v): %#v", method, req)
|
|
|
|
}
|
|
|
|
err := dash.queryImpl(method, req, reply)
|
|
|
|
if err != nil {
|
|
|
|
if dash.logger != nil {
|
|
|
|
dash.logger("API(%v): ERROR: %v", method, err)
|
|
|
|
}
|
|
|
|
if dash.errorHandler != nil {
|
|
|
|
dash.errorHandler(err)
|
|
|
|
}
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if dash.logger != nil {
|
|
|
|
dash.logger("API(%v): REPLY: %#v", method, reply)
|
|
|
|
}
|
|
|
|
return nil
|
2017-07-21 10:43:09 +00:00
|
|
|
}
|
|
|
|
|
2018-06-11 08:02:46 +00:00
|
|
|
func (dash *Dashboard) queryImpl(method string, req, reply interface{}) error {
|
2017-07-25 18:25:53 +00:00
|
|
|
if reply != nil {
|
|
|
|
// json decoding behavior is somewhat surprising
|
|
|
|
// (see // https://github.com/golang/go/issues/21092).
|
|
|
|
// To avoid any surprises, we zero the reply.
|
|
|
|
typ := reflect.TypeOf(reply)
|
|
|
|
if typ.Kind() != reflect.Ptr {
|
|
|
|
return fmt.Errorf("resp must be a pointer")
|
|
|
|
}
|
|
|
|
reflect.ValueOf(reply).Elem().Set(reflect.New(typ.Elem()).Elem())
|
|
|
|
}
|
2017-06-30 13:58:14 +00:00
|
|
|
values := make(url.Values)
|
2018-06-11 08:02:46 +00:00
|
|
|
values.Add("client", dash.Client)
|
|
|
|
values.Add("key", dash.Key)
|
2017-06-30 13:58:14 +00:00
|
|
|
values.Add("method", method)
|
|
|
|
if req != nil {
|
|
|
|
data, err := json.Marshal(req)
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("failed to marshal request: %v", err)
|
|
|
|
}
|
2018-03-08 12:00:10 +00:00
|
|
|
buf := new(bytes.Buffer)
|
|
|
|
gz := gzip.NewWriter(buf)
|
|
|
|
if _, err := gz.Write(data); err != nil {
|
|
|
|
return err
|
2017-06-30 13:58:14 +00:00
|
|
|
}
|
2018-03-08 12:00:10 +00:00
|
|
|
if err := gz.Close(); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
values.Add("payload", buf.String())
|
2017-06-30 13:58:14 +00:00
|
|
|
}
|
2018-06-11 08:02:46 +00:00
|
|
|
r, err := dash.ctor("POST", fmt.Sprintf("%v/api", dash.Addr), strings.NewReader(values.Encode()))
|
2017-06-30 13:58:14 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2018-03-08 12:00:10 +00:00
|
|
|
r.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
2018-06-11 08:02:46 +00:00
|
|
|
resp, err := dash.doer(r)
|
2017-06-30 13:58:14 +00:00
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("http request failed: %v", err)
|
|
|
|
}
|
|
|
|
defer resp.Body.Close()
|
|
|
|
if resp.StatusCode != http.StatusOK {
|
|
|
|
data, _ := ioutil.ReadAll(resp.Body)
|
|
|
|
return fmt.Errorf("request failed with %v: %s", resp.Status, data)
|
|
|
|
}
|
|
|
|
if reply != nil {
|
|
|
|
if err := json.NewDecoder(resp.Body).Decode(reply); err != nil {
|
|
|
|
return fmt.Errorf("failed to unmarshal response: %v", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|