diff options
| author | Andrey Konovalov <andreyknvl@google.com> | 2019-01-16 14:50:43 +0100 |
|---|---|---|
| committer | Andrey Konovalov <andreyknvl@gmail.com> | 2019-01-16 19:19:53 +0100 |
| commit | c2faf9b2d5b583f53d01b8b483e26b61ed72cbbf (patch) | |
| tree | 8223752709973ec927c4291fda3f3341a5ef0ea6 | |
| parent | b5df78dc5d994bc61f1ecee2c5c85313178f392e (diff) | |
all: detect extra coverage support
Based on whether the kernel supports KCOV_REMOTE_ENABLE ioctl.
| -rw-r--r-- | executor/defs.h | 10 | ||||
| -rw-r--r-- | executor/executor.cc | 13 | ||||
| -rw-r--r-- | pkg/host/host.go | 2 | ||||
| -rw-r--r-- | pkg/host/host_linux.go | 49 | ||||
| -rw-r--r-- | pkg/ipc/ipc.go | 1 | ||||
| -rw-r--r-- | pkg/runtest/run.go | 3 | ||||
| -rw-r--r-- | sys/linux/gen/386.go | 3 | ||||
| -rw-r--r-- | sys/linux/gen/amd64.go | 3 | ||||
| -rw-r--r-- | sys/linux/gen/arm.go | 3 | ||||
| -rw-r--r-- | sys/linux/gen/arm64.go | 3 | ||||
| -rw-r--r-- | sys/linux/gen/ppc64le.go | 3 | ||||
| -rw-r--r-- | sys/linux/init.go | 10 | ||||
| -rw-r--r-- | sys/linux/sys.txt | 3 | ||||
| -rw-r--r-- | sys/linux/sys_386.const | 1 | ||||
| -rw-r--r-- | sys/linux/sys_amd64.const | 1 | ||||
| -rw-r--r-- | sys/linux/sys_arm.const | 1 | ||||
| -rw-r--r-- | sys/linux/sys_arm64.const | 1 | ||||
| -rw-r--r-- | sys/linux/sys_ppc64le.const | 1 | ||||
| -rw-r--r-- | syz-fuzzer/fuzzer.go | 3 | ||||
| -rw-r--r-- | tools/syz-execprog/execprog.go | 3 |
20 files changed, 93 insertions, 24 deletions
diff --git a/executor/defs.h b/executor/defs.h index a493c2b51..fd3f039a6 100644 --- a/executor/defs.h +++ b/executor/defs.h @@ -60,7 +60,7 @@ #if GOARCH_386 #define GOARCH "386" -#define SYZ_REVISION "2add9eb5de33dbfa073790d7af2cb5a543062225" +#define SYZ_REVISION "1c5197fbb1cb70ac384135081dec18423f4e1bd1" #define SYZ_EXECUTOR_USES_FORK_SERVER 1 #define SYZ_EXECUTOR_USES_SHMEM 1 #define SYZ_PAGE_SIZE 4096 @@ -70,7 +70,7 @@ #if GOARCH_amd64 #define GOARCH "amd64" -#define SYZ_REVISION "85924b0693363419c2ea4f8588a815526691dd50" +#define SYZ_REVISION "3f0e0ea59ae728d37a8cdd5e77a5beeb718a88f6" #define SYZ_EXECUTOR_USES_FORK_SERVER 1 #define SYZ_EXECUTOR_USES_SHMEM 1 #define SYZ_PAGE_SIZE 4096 @@ -80,7 +80,7 @@ #if GOARCH_arm #define GOARCH "arm" -#define SYZ_REVISION "5fb6ba1fcab442e1305ff81004954b7ee140e165" +#define SYZ_REVISION "3391e0fa8ed2299b0beda67f40c24a913c0b6a5b" #define SYZ_EXECUTOR_USES_FORK_SERVER 1 #define SYZ_EXECUTOR_USES_SHMEM 1 #define SYZ_PAGE_SIZE 4096 @@ -90,7 +90,7 @@ #if GOARCH_arm64 #define GOARCH "arm64" -#define SYZ_REVISION "7f0cf979fc6d1fc624ee0f2187d86f90279b0574" +#define SYZ_REVISION "d0d53f46334e628e33432e1655016df33dda9386" #define SYZ_EXECUTOR_USES_FORK_SERVER 1 #define SYZ_EXECUTOR_USES_SHMEM 1 #define SYZ_PAGE_SIZE 4096 @@ -100,7 +100,7 @@ #if GOARCH_ppc64le #define GOARCH "ppc64le" -#define SYZ_REVISION "debbebfbc6525345884bd5c7595a0d8804bc46db" +#define SYZ_REVISION "e8c9edb8f62f65ca64b9679162b4e5995ad2aaa9" #define SYZ_EXECUTOR_USES_FORK_SERVER 1 #define SYZ_EXECUTOR_USES_SHMEM 1 #define SYZ_PAGE_SIZE 4096 diff --git a/executor/executor.cc b/executor/executor.cc index bb0e8defd..a0357c188 100644 --- a/executor/executor.cc +++ b/executor/executor.cc @@ -120,6 +120,7 @@ static sandbox_type flag_sandbox; static bool flag_enable_tun; static bool flag_enable_net_dev; static bool flag_enable_fault_injection; +static bool flag_extra_cover; static bool flag_collect_cover; static bool flag_dedup_cover; @@ -373,8 +374,10 @@ int main(int argc, char** argv) cover_open(&threads[i].cov, false); } cover_open(&extra_cov, true); - // Don't enable comps because we don't use them in the fuzzer yet. - cover_enable(&extra_cov, false, true); + if (flag_extra_cover) { + // Don't enable comps because we don't use them in the fuzzer yet. + cover_enable(&extra_cov, false, true); + } } int status = 0; @@ -456,6 +459,7 @@ void parse_env_flags(uint64 flags) flag_enable_tun = flags & (1 << 5); flag_enable_net_dev = flags & (1 << 6); flag_enable_fault_injection = flags & (1 << 7); + flag_extra_cover = flags & (1 << 8); } #if SYZ_EXECUTOR_USES_FORK_SERVER @@ -567,7 +571,8 @@ retry: if (flag_cover && !colliding) { if (!flag_threaded) cover_enable(&threads[0].cov, flag_collect_comps, false); - cover_reset(&extra_cov); + if (flag_extra_cover) + cover_reset(&extra_cov); } int call_index = 0; @@ -938,7 +943,7 @@ void write_call_output(thread_t* th, bool finished) void write_extra_output() { #if SYZ_EXECUTOR_USES_SHMEM - if (!flag_cover || flag_collect_comps) + if (!flag_cover || !flag_extra_cover || flag_collect_comps) return; cover_collect(&extra_cov); if (!extra_cov.size) diff --git a/pkg/host/host.go b/pkg/host/host.go index 062cae25f..d8d83916d 100644 --- a/pkg/host/host.go +++ b/pkg/host/host.go @@ -47,6 +47,7 @@ var testFallback = false const ( FeatureCoverage = iota FeatureComparisons + FeatureExtraCoverage FeatureSandboxSetuid FeatureSandboxNamespace FeatureSandboxAndroidUntrustedApp @@ -79,6 +80,7 @@ func Check(target *prog.Target) (*Features, error) { res := &Features{ FeatureCoverage: {Name: "code coverage", Reason: unsupported}, FeatureComparisons: {Name: "comparison tracing", Reason: unsupported}, + FeatureExtraCoverage: {Name: "extra coverage", Reason: unsupported}, FeatureSandboxSetuid: {Name: "setuid sandbox", Reason: unsupported}, FeatureSandboxNamespace: {Name: "namespace sandbox", Reason: unsupported}, FeatureSandboxAndroidUntrustedApp: {Name: "Android sandbox", Reason: unsupported}, diff --git a/pkg/host/host_linux.go b/pkg/host/host_linux.go index 0c65f9b0c..9e90bbd1f 100644 --- a/pkg/host/host_linux.go +++ b/pkg/host/host_linux.go @@ -24,6 +24,14 @@ import ( "github.com/google/syzkaller/sys/linux" ) +type KcovRemoteArg struct { + TraceMode uint32 + AreaSize uint32 + NumHandles uint32 + CommonHandle uint64 + // Handles []uint64 goes here. +} + func isSupported(c *prog.Syscall, target *prog.Target, sandbox string) (bool, string) { log.Logf(2, "checking support for %v", c.Name) if strings.HasPrefix(c.CallName, "syz_") { @@ -344,6 +352,7 @@ func extractStringConst(typ prog.Type) (string, bool) { func init() { checkFeature[FeatureCoverage] = checkCoverage checkFeature[FeatureComparisons] = checkComparisons + checkFeature[FeatureExtraCoverage] = checkExtraCoverage checkFeature[FeatureSandboxSetuid] = unconditionallyEnabled checkFeature[FeatureSandboxNamespace] = checkSandboxNamespace checkFeature[FeatureSandboxAndroidUntrustedApp] = checkSandboxAndroidUntrustedApp @@ -370,6 +379,14 @@ func checkCoverage() string { } func checkComparisons() (reason string) { + return checkCoverageFeature(FeatureComparisons) +} + +func checkExtraCoverage() (reason string) { + return checkCoverageFeature(FeatureExtraCoverage) +} + +func checkCoverageFeature(feature int) (reason string) { if reason = checkDebugFS(); reason != "" { return reason } @@ -402,13 +419,33 @@ func checkComparisons() (reason string) { reason = fmt.Sprintf("munmap failed: %v", err) } }() - _, _, errno = syscall.Syscall(syscall.SYS_IOCTL, - uintptr(fd), linux.KCOV_ENABLE, linux.KCOV_TRACE_CMP) - if errno != 0 { - if errno == 524 { // ENOTSUPP - return "CONFIG_KCOV_ENABLE_COMPARISONS is not enabled" + switch feature { + case FeatureComparisons: + _, _, errno = syscall.Syscall(syscall.SYS_IOCTL, + uintptr(fd), linux.KCOV_ENABLE, linux.KCOV_TRACE_CMP) + if errno != 0 { + if errno == 524 { // ENOTSUPP + return "CONFIG_KCOV_ENABLE_COMPARISONS is not enabled" + } + return fmt.Sprintf("ioctl(KCOV_TRACE_CMP) failed: %v", errno) } - return fmt.Sprintf("ioctl(KCOV_TRACE_CMP) failed: %v", errno) + case FeatureExtraCoverage: + arg := KcovRemoteArg{ + TraceMode: uint32(linux.KCOV_TRACE_CMP), + AreaSize: uint32(coverSize * unsafe.Sizeof(uintptr(0))), + NumHandles: 0, + CommonHandle: 0, + } + _, _, errno = syscall.Syscall(syscall.SYS_IOCTL, + uintptr(fd), linux.KCOV_REMOTE_ENABLE, uintptr(unsafe.Pointer(&arg))) + if errno != 0 { + if errno == 25 { // ENOTTY + return "extra coverage is not supported by the kernel" + } + return fmt.Sprintf("ioctl(KCOV_REMOTE_ENABLE) failed: %v", errno) + } + default: + panic("unknown feature in checkCoverageFeature") } defer func() { _, _, errno = syscall.Syscall(syscall.SYS_IOCTL, uintptr(fd), linux.KCOV_DISABLE, 0) diff --git a/pkg/ipc/ipc.go b/pkg/ipc/ipc.go index b3799ebfb..f54cfa8d3 100644 --- a/pkg/ipc/ipc.go +++ b/pkg/ipc/ipc.go @@ -34,6 +34,7 @@ const ( FlagEnableTun // initialize and use tun in executor FlagEnableNetDev // setup a bunch of various network devices for testing FlagEnableFault // enable fault injection support + FlagExtraCover // collect extra coverage // Executor does not know about these: FlagUseShmem // use shared memory instead of pipes for communication FlagUseForkServer // use extended protocol with handshake diff --git a/pkg/runtest/run.go b/pkg/runtest/run.go index cac5f7334..1ce1f2ea8 100644 --- a/pkg/runtest/run.go +++ b/pkg/runtest/run.go @@ -330,6 +330,9 @@ func (ctx *Context) createSyzTest(p *prog.Prog, sandbox string, threaded, cov bo cfg.Flags |= ipc.FlagSignal opts.Flags |= ipc.FlagCollectCover } + if ctx.Features[host.FeatureExtraCoverage].Enabled { + cfg.Flags |= ipc.FlagExtraCover + } if ctx.Features[host.FeatureNetworkInjection].Enabled { cfg.Flags |= ipc.FlagEnableTun } diff --git a/sys/linux/gen/386.go b/sys/linux/gen/386.go index 44c7bf5b6..9f80d523a 100644 --- a/sys/linux/gen/386.go +++ b/sys/linux/gen/386.go @@ -41979,6 +41979,7 @@ var consts_386 = []ConstValue{ {Name: "KCOV_DISABLE", Value: 25445}, {Name: "KCOV_ENABLE", Value: 25444}, {Name: "KCOV_INIT_TRACE", Value: 2147771137}, + {Name: "KCOV_REMOTE_ENABLE", Value: 1075340134}, {Name: "KCOV_TRACE_CMP", Value: 1}, {Name: "KCOV_TRACE_PC"}, {Name: "KDADDIO", Value: 19252}, @@ -46827,4 +46828,4 @@ var consts_386 = []ConstValue{ {Name: "bpf_insn_load_imm_dw", Value: 24}, } -const revision_386 = "2add9eb5de33dbfa073790d7af2cb5a543062225" +const revision_386 = "1c5197fbb1cb70ac384135081dec18423f4e1bd1" diff --git a/sys/linux/gen/amd64.go b/sys/linux/gen/amd64.go index 9ba446de1..5c248531b 100644 --- a/sys/linux/gen/amd64.go +++ b/sys/linux/gen/amd64.go @@ -42744,6 +42744,7 @@ var consts_amd64 = []ConstValue{ {Name: "KCOV_DISABLE", Value: 25445}, {Name: "KCOV_ENABLE", Value: 25444}, {Name: "KCOV_INIT_TRACE", Value: 2148033281}, + {Name: "KCOV_REMOTE_ENABLE", Value: 1075340134}, {Name: "KCOV_TRACE_CMP", Value: 1}, {Name: "KCOV_TRACE_PC"}, {Name: "KDADDIO", Value: 19252}, @@ -47617,4 +47618,4 @@ var consts_amd64 = []ConstValue{ {Name: "bpf_insn_load_imm_dw", Value: 24}, } -const revision_amd64 = "85924b0693363419c2ea4f8588a815526691dd50" +const revision_amd64 = "3f0e0ea59ae728d37a8cdd5e77a5beeb718a88f6" diff --git a/sys/linux/gen/arm.go b/sys/linux/gen/arm.go index d2d0274b1..4df935bbc 100644 --- a/sys/linux/gen/arm.go +++ b/sys/linux/gen/arm.go @@ -41871,6 +41871,7 @@ var consts_arm = []ConstValue{ {Name: "KCOV_DISABLE", Value: 25445}, {Name: "KCOV_ENABLE", Value: 25444}, {Name: "KCOV_INIT_TRACE", Value: 2147771137}, + {Name: "KCOV_REMOTE_ENABLE", Value: 1075340134}, {Name: "KCOV_TRACE_CMP", Value: 1}, {Name: "KCOV_TRACE_PC"}, {Name: "KDADDIO", Value: 19252}, @@ -46666,4 +46667,4 @@ var consts_arm = []ConstValue{ {Name: "bpf_insn_load_imm_dw", Value: 24}, } -const revision_arm = "5fb6ba1fcab442e1305ff81004954b7ee140e165" +const revision_arm = "3391e0fa8ed2299b0beda67f40c24a913c0b6a5b" diff --git a/sys/linux/gen/arm64.go b/sys/linux/gen/arm64.go index 79c452772..b2b8e8155 100644 --- a/sys/linux/gen/arm64.go +++ b/sys/linux/gen/arm64.go @@ -42190,6 +42190,7 @@ var consts_arm64 = []ConstValue{ {Name: "KCOV_DISABLE", Value: 25445}, {Name: "KCOV_ENABLE", Value: 25444}, {Name: "KCOV_INIT_TRACE", Value: 2148033281}, + {Name: "KCOV_REMOTE_ENABLE", Value: 1075340134}, {Name: "KCOV_TRACE_CMP", Value: 1}, {Name: "KCOV_TRACE_PC"}, {Name: "KDADDIO", Value: 19252}, @@ -46975,4 +46976,4 @@ var consts_arm64 = []ConstValue{ {Name: "bpf_insn_load_imm_dw", Value: 24}, } -const revision_arm64 = "7f0cf979fc6d1fc624ee0f2187d86f90279b0574" +const revision_arm64 = "d0d53f46334e628e33432e1655016df33dda9386" diff --git a/sys/linux/gen/ppc64le.go b/sys/linux/gen/ppc64le.go index d679f870b..9fd0f1500 100644 --- a/sys/linux/gen/ppc64le.go +++ b/sys/linux/gen/ppc64le.go @@ -40585,6 +40585,7 @@ var consts_ppc64le = []ConstValue{ {Name: "KCOV_DISABLE", Value: 536896357}, {Name: "KCOV_ENABLE", Value: 536896356}, {Name: "KCOV_INIT_TRACE", Value: 1074291457}, + {Name: "KCOV_REMOTE_ENABLE", Value: 1075340134}, {Name: "KCOV_TRACE_CMP", Value: 1}, {Name: "KCOV_TRACE_PC"}, {Name: "KDADDIO", Value: 19252}, @@ -44333,4 +44334,4 @@ var consts_ppc64le = []ConstValue{ {Name: "bpf_insn_load_imm_dw", Value: 24}, } -const revision_ppc64le = "debbebfbc6525345884bd5c7595a0d8804bc46db" +const revision_ppc64le = "e8c9edb8f62f65ca64b9679162b4e5995ad2aaa9" diff --git a/sys/linux/init.go b/sys/linux/init.go index c5e4c810c..e0efe22c7 100644 --- a/sys/linux/init.go +++ b/sys/linux/init.go @@ -81,6 +81,7 @@ func InitTarget(target *prog.Target) { if target.Arch == runtime.GOARCH { KCOV_INIT_TRACE = uintptr(target.GetConst("KCOV_INIT_TRACE")) KCOV_ENABLE = uintptr(target.GetConst("KCOV_ENABLE")) + KCOV_REMOTE_ENABLE = uintptr(target.GetConst("KCOV_REMOTE_ENABLE")) KCOV_DISABLE = uintptr(target.GetConst("KCOV_DISABLE")) KCOV_TRACE_CMP = uintptr(target.GetConst("KCOV_TRACE_CMP")) } @@ -88,10 +89,11 @@ func InitTarget(target *prog.Target) { var ( // This should not be here, but for now we expose this for syz-fuzzer. - KCOV_INIT_TRACE uintptr - KCOV_ENABLE uintptr - KCOV_DISABLE uintptr - KCOV_TRACE_CMP uintptr + KCOV_INIT_TRACE uintptr + KCOV_ENABLE uintptr + KCOV_REMOTE_ENABLE uintptr + KCOV_DISABLE uintptr + KCOV_TRACE_CMP uintptr ) type arch struct { diff --git a/sys/linux/sys.txt b/sys/linux/sys.txt index 2deeedae6..e9732266c 100644 --- a/sys/linux/sys.txt +++ b/sys/linux/sys.txt @@ -959,6 +959,9 @@ _ = ADJ_OFFSET, ADJ_FREQUENCY, ADJ_MAXERROR, ADJ_ESTERROR, ADJ_STATUS, ADJ_TIMEC # misc _ = KCOV_INIT_TRACE, KCOV_ENABLE, KCOV_DISABLE, KCOV_TRACE_PC, KCOV_TRACE_CMP, FIFREEZE, FAN_OPEN_PERM, FAN_ACCESS_PERM, PTRACE_TRACEME, __NR_mmap2 +# Hardcode KCOV_REMOTE_ENABLE value for amd64 until new kcov patches reach mainline. +define KCOV_REMOTE_ENABLE 1075340134 + # Not yet implemented syscalls #define __NR_umask 95 #define __NR_vhangup 153 diff --git a/sys/linux/sys_386.const b/sys/linux/sys_386.const index bffec1278..96f1db187 100644 --- a/sys/linux/sys_386.const +++ b/sys/linux/sys_386.const @@ -220,6 +220,7 @@ KCMP_VM = 1 KCOV_DISABLE = 25445 KCOV_ENABLE = 25444 KCOV_INIT_TRACE = 2147771137 +KCOV_REMOTE_ENABLE = 1075340134 KCOV_TRACE_CMP = 1 KCOV_TRACE_PC = 0 KEXEC_ARCH_386 = 196608 diff --git a/sys/linux/sys_amd64.const b/sys/linux/sys_amd64.const index a85e52ddb..696eb608d 100644 --- a/sys/linux/sys_amd64.const +++ b/sys/linux/sys_amd64.const @@ -220,6 +220,7 @@ KCMP_VM = 1 KCOV_DISABLE = 25445 KCOV_ENABLE = 25444 KCOV_INIT_TRACE = 2148033281 +KCOV_REMOTE_ENABLE = 1075340134 KCOV_TRACE_CMP = 1 KCOV_TRACE_PC = 0 KEXEC_ARCH_386 = 196608 diff --git a/sys/linux/sys_arm.const b/sys/linux/sys_arm.const index 0fafba993..dd79987f9 100644 --- a/sys/linux/sys_arm.const +++ b/sys/linux/sys_arm.const @@ -220,6 +220,7 @@ KCMP_VM = 1 KCOV_DISABLE = 25445 KCOV_ENABLE = 25444 KCOV_INIT_TRACE = 2147771137 +KCOV_REMOTE_ENABLE = 1075340134 KCOV_TRACE_CMP = 1 KCOV_TRACE_PC = 0 KEXEC_ARCH_386 = 196608 diff --git a/sys/linux/sys_arm64.const b/sys/linux/sys_arm64.const index 41966fc33..6ccf3e16d 100644 --- a/sys/linux/sys_arm64.const +++ b/sys/linux/sys_arm64.const @@ -220,6 +220,7 @@ KCMP_VM = 1 KCOV_DISABLE = 25445 KCOV_ENABLE = 25444 KCOV_INIT_TRACE = 2148033281 +KCOV_REMOTE_ENABLE = 1075340134 KCOV_TRACE_CMP = 1 KCOV_TRACE_PC = 0 KEXEC_ARCH_386 = 196608 diff --git a/sys/linux/sys_ppc64le.const b/sys/linux/sys_ppc64le.const index ef8a126b6..a3228131d 100644 --- a/sys/linux/sys_ppc64le.const +++ b/sys/linux/sys_ppc64le.const @@ -220,6 +220,7 @@ KCMP_VM = 1 KCOV_DISABLE = 536896357 KCOV_ENABLE = 536896356 KCOV_INIT_TRACE = 1074291457 +KCOV_REMOTE_ENABLE = 1075340134 KCOV_TRACE_CMP = 1 KCOV_TRACE_PC = 0 KEXEC_ARCH_386 = 196608 diff --git a/syz-fuzzer/fuzzer.go b/syz-fuzzer/fuzzer.go index b6f7e21ab..d41dfe661 100644 --- a/syz-fuzzer/fuzzer.go +++ b/syz-fuzzer/fuzzer.go @@ -187,6 +187,9 @@ func main() { if periodicCallback != nil { gateCallback = func() { periodicCallback(r.MemoryLeakFrames) } } + if r.CheckResult.Features[host.FeatureExtraCoverage].Enabled { + config.Flags |= ipc.FlagExtraCover + } if r.CheckResult.Features[host.FeatureNetworkInjection].Enabled { config.Flags |= ipc.FlagEnableTun } diff --git a/tools/syz-execprog/execprog.go b/tools/syz-execprog/execprog.go index 1a4468063..82fa00906 100644 --- a/tools/syz-execprog/execprog.go +++ b/tools/syz-execprog/execprog.go @@ -288,6 +288,9 @@ func createConfig(target *prog.Target, entries []*prog.LogEntry, features *host. } execOpts.Flags |= ipc.FlagCollectComps } + if features[host.FeatureExtraCoverage].Enabled { + config.Flags |= ipc.FlagExtraCover + } if *flagFaultCall >= 0 { config.Flags |= ipc.FlagEnableFault execOpts.Flags |= ipc.FlagInjectFault |
