diff options
| author | Dmitry Vyukov <dvyukov@google.com> | 2016-02-18 21:41:40 +0100 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2016-02-18 21:41:40 +0100 |
| commit | 87d7cc4d27a2ae64a48cbad48e21369448841e1f (patch) | |
| tree | 8b3b0ebaf03c09ab4e73831428e339ae4be4b53c | |
| parent | 68c7a49a96b970897db5f61dd618382b5fe18ec0 (diff) | |
| parent | 548b4a94a3e936aab2f8a519bb0e54b9ab4dc476 (diff) | |
Merge pull request #21 from daviddrysdale/doc-update
Some doc & diagnostic updates
| -rw-r--r-- | README.md | 53 | ||||
| -rw-r--r-- | structure.png | bin | 47084 -> 43259 bytes | |||
| -rw-r--r-- | syz-fuzzer/fuzzer.go | 5 | ||||
| -rw-r--r-- | syz-manager/cover.go | 6 | ||||
| -rw-r--r-- | syz-manager/manager.go | 4 |
5 files changed, 63 insertions, 5 deletions
@@ -40,6 +40,9 @@ This is all implemented in [this coverage patch](https://github.com/dvyukov/linu once the patch is applied, the kernel should be configured with `CONFIG_KCOV` plus `CONFIG_KASAN` or `CONFIG_KTSAN`. +(Note that if the kernel under test does not include support for all namespaces, the `dropprivs` +configuration value should be set to `false`.) + ### QEMU Setup Syzkaller runs its fuzzer processes inside QEMU virtual machines, so a working QEMU system is needed @@ -95,6 +98,9 @@ following keys in its top-level object: the virtual machine. - `cpu`: Number of CPUs to simulate in the VM (*not currently used*). - `mem`: Amount of memory (in MiB) for the VM; this is passed as the `-m` option to `qemu-system-x86_64`. + - `dropprivs` : Whether the executor program should try to use namespaces to drop privileges + before executing (requires a kernel built with `CONFIG_NAMESPACES`, `CONFIG_UTS_NS`, + `CONFIG_USER_NS`, `CONFIG_PID_NS` and `CONFIG_NET_NS`). - `enable_syscalls`: List of syscalls to test (optional). - `disable_syscalls`: List of system calls that should be treated as disabled (optional). - `suppressions`: List of regexps for known bugs. @@ -151,4 +157,51 @@ open_mode = S_IRUSR, S_IWUSR, S_IXUSR, S_IRGRP, S_IWGRP, S_IXGRP, S_IROTH, S_IWO The description is contained in [sys/sys.txt](sys/sys.txt) file. +## Troubleshooting + +Here are some things to check if there are problems running syzkaller. + + - Check that QEMU can successfully boot the virtual machine. For example, + if `IMAGE` is set to the VM's disk image (as per the `image` config value) + and `KERNEL` is set to the test kernel (as per the `kernel` config value) + then something like the following command should start the VM successfully: + + ```qemu-system-x86_64 -hda $IMAGE -m 256 -net nic -net user,host=10.0.2.10,hostfwd=tcp::23505-:22 -enable-kvm -kernel $KERNEL -append root=/dev/sda``` + + - Check that inbound SSH to the running virtual machine works. For example, with + a VM running and with `SSHKEY` set to the SSH identity (as per the `sshkey` config value) the + following command should connect: + + ```ssh -i $SSHKEY -p 23505 root@localhost``` + + - Check that the `CONFIG_KCOV` option is available inside the VM: + - `ls /sys/kernel/debug # Check debugfs mounted` + - `ls /sys/kernel/debug/kcov # Check kcov enabled` + - Build the test program from `Documentation/kcov.txt` and run it inside the VM. + + - Check that debug information (from the `CONFIG_DEBUG_INFO` option) is available + - Pass the hex output from the kcov test program to `addrline -a -i -f -e $VMLINUX` (where + `VMLINUX` is the vmlinux file, as per the `vmlinux` config value), to confirm + that symbols for the kernel are available. + + - Use the `-v N` command line option to increase the amount of logging output, from both + the `syz-manager` top-level program and the `syz-fuzzer` instances (which go to the + output files in the `crashes` subdirectory of the working directory). Higher values of + N give more output. + + - If logging indicates problems with the executor program (e.g. `executor failure`), + try manually running a short sequence of system calls: + - Build additional tools with `make all-tools` + - Copy `syz-executor` and `syz-execprog` into a running VM. + - In the VM run `./syz-execprog -executor ./syz-executor -debug sampleprog` where + sampleprog is a simple system call script (e.g. just containing `getpid()`). + - For example, if this reports that `clone` has failed, this probably indicates + that the test kernel does not include support for all of the required namespaces. + In this case, running the `syz-execprog` test with the `-nobody=0` option fixes the problem, + so the main configuration needs to be updated to set `dropprivs` to `false`. + + +## Disclaimer + This is not an official Google product. + diff --git a/structure.png b/structure.png Binary files differindex 4ca456957..b08a63688 100644 --- a/structure.png +++ b/structure.png diff --git a/syz-fuzzer/fuzzer.go b/syz-fuzzer/fuzzer.go index 7942a6cab..87fd6b9cb 100644 --- a/syz-fuzzer/fuzzer.go +++ b/syz-fuzzer/fuzzer.go @@ -97,7 +97,7 @@ func main() { fmt.Fprintf(os.Stderr, "-output flag must be one of none/stdout/dmesg/file\n") os.Exit(1) } - logf(0, "started") + logf(0, "fuzzer started, log level %v", *flagV) corpusCover = make([]cover.Cover, sys.CallCount) maxCover = make([]cover.Cover, sys.CallCount) @@ -496,11 +496,12 @@ retry: panic(err) } try++ + logf(4, "fuzzer detected executor failure='%v', retrying #%d\n", err, (try + 1)) debug.FreeOSMemory() time.Sleep(time.Second) goto retry } - logf(4, "result failed=%v hanged=%v:\n%v\n", failed, hanged, string(output)) + logf(2, "result failed=%v hanged=%v:\n%v\n", failed, hanged, string(output)) cov := make([]cover.Cover, len(p.Calls)) for i, c := range rawCover { cov[i] = cover.Cover(c) diff --git a/syz-manager/cover.go b/syz-manager/cover.go index bc99f3da8..efeb14795 100644 --- a/syz-manager/cover.go +++ b/syz-manager/cover.go @@ -29,7 +29,11 @@ func generateCoverHtml(w io.Writer, vmlinux string, cov []uint32) error { return err } if len(info) == 0 { - return fmt.Errorf("vmlinux does not have debug info (set CONFIG_DEBUG_INFO=y)") + if len(cov) == 0 { + return fmt.Errorf("No coverage data available") + } else { + return fmt.Errorf("'%s' does not have debug info (set CONFIG_DEBUG_INFO=y)", vmlinux) + } } var d templateData diff --git a/syz-manager/manager.go b/syz-manager/manager.go index ffb184936..075b3127a 100644 --- a/syz-manager/manager.go +++ b/syz-manager/manager.go @@ -207,8 +207,8 @@ func (mgr *Manager) runInstance(vmCfg *vm.Config, first bool) bool { leak := first && mgr.cfg.Leak // Run the fuzzer binary. - outputC, errorC, err := inst.Run(time.Hour, fmt.Sprintf("%v -executor %v -name %v -manager %v -output=%v -procs %v -leak=%v -cover=%v -nobody=%v", - fuzzerBin, executorBin, vmCfg.Name, fwdAddr, mgr.cfg.Output, mgr.cfg.Procs, leak, mgr.cfg.Cover, mgr.cfg.DropPrivs)) + outputC, errorC, err := inst.Run(time.Hour, fmt.Sprintf("%v -executor %v -name %v -manager %v -output=%v -procs %v -leak=%v -cover=%v -nobody=%v -v %d", + fuzzerBin, executorBin, vmCfg.Name, fwdAddr, mgr.cfg.Output, mgr.cfg.Procs, leak, mgr.cfg.Cover, mgr.cfg.DropPrivs, *flagV)) if err != nil { logf(0, "failed to run fuzzer: %v", err) return false |
