Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src Add KCOV - kernel code coverage tracing device



details:   https://anonhg.NetBSD.org/src/rev/e06f14301b2f
branches:  trunk
changeset: 449097:e06f14301b2f
user:      kamil <kamil%NetBSD.org@localhost>
date:      Sat Feb 23 03:10:05 2019 +0000

description:
Add KCOV - kernel code coverage tracing device

The KCOV driver implements collection of code coverage inside the kernel.
It can be enabled on a per process basis from userland, allowing the kernel
program counter to be collected during syscalls triggered by the same
process.

The device is oriented towards kernel fuzzers, in particular syzkaller.

Currently the only supported coverage type is -fsanitize-coverage=trace-pc.

The KCOV driver was initially developed in Linux. A driver based on the
same concept was then implemented in FreeBSD and OpenBSD.

Documentation is borrowed from OpenBSD and ATF tests from FreeBSD.

This patch has been prepared by Siddharth Muralee, improved by <maxv>
and polished by myself before importing into the mainline tree.

All ATF tests pass.

diffstat:

 distrib/sets/lists/comp/mi         |    3 +-
 distrib/sets/lists/man/mi          |    5 +-
 distrib/sets/lists/tests/module.mi |    3 +-
 etc/MAKEDEV.tmpl                   |    6 +-
 share/man/man4/Makefile            |    4 +-
 share/man/man4/kcov.4              |  133 ++++++++++++++
 share/mk/bsd.sys.mk                |   10 +-
 sys/arch/amd64/conf/GENERIC        |    8 +-
 sys/conf/files                     |    3 +-
 sys/conf/majors                    |    3 +-
 sys/conf/ssp.mk                    |    3 +-
 sys/kern/files.kern                |    3 +-
 sys/kern/subr_kcov.c               |  340 +++++++++++++++++++++++++++++++++++++
 sys/sys/Makefile                   |    4 +-
 sys/sys/kcov.h                     |   42 ++++
 tests/modules/Makefile             |    3 +-
 tests/modules/t_kcov.c             |  315 ++++++++++++++++++++++++++++++++++
 17 files changed, 872 insertions(+), 16 deletions(-)

diffs (truncated from 1105 to 300 lines):

diff -r e56f98983f2f -r e06f14301b2f distrib/sets/lists/comp/mi
--- a/distrib/sets/lists/comp/mi        Fri Feb 22 23:01:25 2019 +0000
+++ b/distrib/sets/lists/comp/mi        Sat Feb 23 03:10:05 2019 +0000
@@ -1,4 +1,4 @@
-#      $NetBSD: mi,v 1.2258 2019/02/10 04:03:03 mrg Exp $
+#      $NetBSD: mi,v 1.2259 2019/02/23 03:10:05 kamil Exp $
 #
 # Note: don't delete entries from here - mark them as "obsolete" instead.
 ./etc/mtree/set.comp                           comp-sys-root
@@ -3017,6 +3017,7 @@
 ./usr/include/sys/ipc.h                                comp-c-include
 ./usr/include/sys/joystick.h                   comp-c-include
 ./usr/include/sys/kcore.h                      comp-c-include
+./usr/include/sys/kcov.h                       comp-c-include
 ./usr/include/sys/kcpuset.h                    comp-c-include
 ./usr/include/sys/kernel.h                     comp-obsolete           obsolete
 ./usr/include/sys/keylock.h                    comp-obsolete           obsolete
diff -r e56f98983f2f -r e06f14301b2f distrib/sets/lists/man/mi
--- a/distrib/sets/lists/man/mi Fri Feb 22 23:01:25 2019 +0000
+++ b/distrib/sets/lists/man/mi Sat Feb 23 03:10:05 2019 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: mi,v 1.1637 2019/02/06 11:55:05 rin Exp $
+# $NetBSD: mi,v 1.1638 2019/02/23 03:10:05 kamil Exp $
 #
 # Note: don't delete entries from here - mark them as "obsolete" instead.
 #
@@ -1373,6 +1373,7 @@
 ./usr/share/man/cat4/jmide.0                   man-sys-catman          .cat
 ./usr/share/man/cat4/joy.0                     man-sys-catman          .cat
 ./usr/share/man/cat4/kame_ipsec.0              man-obsolete            obsolete
+./usr/share/man/cat4/kcov.0                    man-sys-catman          .cat
 ./usr/share/man/cat4/kloader.0                 man-sys-catman          .cat
 ./usr/share/man/cat4/kse.0                     man-sys-catman          .cat
 ./usr/share/man/cat4/ksyms.0                   man-sys-catman          .cat
@@ -4496,6 +4497,7 @@
 ./usr/share/man/html4/jmide.html               man-sys-htmlman         html
 ./usr/share/man/html4/joy.html                 man-sys-htmlman         html
 ./usr/share/man/html4/kame_ipsec.html          man-obsolete            obsolete
+./usr/share/man/html4/kcov.html                man-sys-htmlman         html
 ./usr/share/man/html4/kloader.html             man-sys-htmlman         html
 ./usr/share/man/html4/kse.html                 man-sys-htmlman         html
 ./usr/share/man/html4/ksyms.html               man-sys-htmlman         html
@@ -7459,6 +7461,7 @@
 ./usr/share/man/man4/jmide.4                   man-sys-man             .man
 ./usr/share/man/man4/joy.4                     man-sys-man             .man
 ./usr/share/man/man4/kame_ipsec.4              man-obsolete            obsolete
+./usr/share/man/man4/kcov.4                    man-sys-man             .man
 ./usr/share/man/man4/kloader.4                 man-sys-man             .man
 ./usr/share/man/man4/kse.4                     man-sys-man             .man
 ./usr/share/man/man4/ksyms.4                   man-sys-man             .man
diff -r e56f98983f2f -r e06f14301b2f distrib/sets/lists/tests/module.mi
--- a/distrib/sets/lists/tests/module.mi        Fri Feb 22 23:01:25 2019 +0000
+++ b/distrib/sets/lists/tests/module.mi        Sat Feb 23 03:10:05 2019 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: module.mi,v 1.16 2019/01/27 16:32:52 christos Exp $
+# $NetBSD: module.mi,v 1.17 2019/02/23 03:10:05 kamil Exp $
 #
 # These are only made for ports doing modules.
 #
@@ -17,6 +17,7 @@
 ./usr/tests/modules/k_uvm/k_uvm.kmod           tests-sys-tests         atf,rump
 ./usr/tests/modules/t_abi_uvm                  tests-sys-tests         atf,rump
 ./usr/tests/modules/t_builtin                  tests-sys-tests         atf,rump
+./usr/tests/modules/t_kcov                     tests-sys-tests         atf
 ./usr/tests/modules/t_klua_pr_52864            tests-sys-tests         atf,rump
 ./usr/tests/modules/t_modctl                   tests-sys-tests         atf,rump
 ./usr/tests/modules/t_modload                  tests-sys-tests         atf,rump
diff -r e56f98983f2f -r e06f14301b2f etc/MAKEDEV.tmpl
--- a/etc/MAKEDEV.tmpl  Fri Feb 22 23:01:25 2019 +0000
+++ b/etc/MAKEDEV.tmpl  Sat Feb 23 03:10:05 2019 +0000
@@ -1,5 +1,5 @@
 #!/bin/sh -
-#      $NetBSD: MAKEDEV.tmpl,v 1.197 2019/01/27 08:53:28 maxv Exp $
+#      $NetBSD: MAKEDEV.tmpl,v 1.198 2019/02/23 03:10:06 kamil Exp $
 #
 # Copyright (c) 2003,2007,2008 The NetBSD Foundation, Inc.
 # All rights reserved.
@@ -2208,6 +2208,10 @@
        mkdev autofs c %autofs_chr% 0 600
        ;;
 
+kcov)
+        mkdev kcov c %kcov_chr% 0
+        ;;
+
 midevend)
 %MI_DEVICES_END%
 local)
diff -r e56f98983f2f -r e06f14301b2f share/man/man4/Makefile
--- a/share/man/man4/Makefile   Fri Feb 22 23:01:25 2019 +0000
+++ b/share/man/man4/Makefile   Sat Feb 23 03:10:05 2019 +0000
@@ -1,4 +1,4 @@
-#      $NetBSD: Makefile,v 1.677 2019/02/06 11:55:05 rin Exp $
+#      $NetBSD: Makefile,v 1.678 2019/02/23 03:10:06 kamil Exp $
 #      @(#)Makefile    8.1 (Berkeley) 6/18/93
 
 MAN=   aac.4 ac97.4 acardide.4 aceride.4 acphy.4 \
@@ -36,7 +36,7 @@
        irmce.4 isp.4 ismt.4 isv.4 itesio.4 iteide.4 iwi.4 iwm.4 iwn.4 ixg.4 \
        ixpide.4 ixv.4 \
        jme.4 jmide.4 joy.4 \
-       kloader.4 kse.4 ksyms.4 kttcp.4 \
+       kcov.4 kloader.4 kse.4 ksyms.4 kttcp.4 \
        l2tp.4 lc.4 ld.4 lii.4 lo.4 lua.4 lxtphy.4 \
        mainbus.4 makphy.4 malo.4 mbe.4 mca.4 mcclock.4 md.4 mfb.4 \
        mfi.4 mfii.4 mhzc.4 \
diff -r e56f98983f2f -r e06f14301b2f share/man/man4/kcov.4
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/share/man/man4/kcov.4     Sat Feb 23 03:10:05 2019 +0000
@@ -0,0 +1,133 @@
+.\"    $NetBSD: kcov.4,v 1.1 2019/02/23 03:10:06 kamil Exp $
+.\"
+.\" Copyright (c) 2018 Anton Lindqvist <anton%openbsd.org@localhost>
+.\"
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+.\"
+.Dd November 16, 2018
+.Dt KCOV 4
+.Os
+.Sh NAME
+.Nm kcov
+.Nd kernel code coverage tracing
+.Sh SYNOPSIS
+.Cd options KCOV
+.Pp
+.In sys/kcov.h
+.Sh DESCRIPTION
+The
+.Nm
+driver implements collection of code coverage inside the kernel.
+It can be enabled on a per process basis from userland,
+allowing the kernel program counter to be collected during syscalls triggered by
+the same process.
+The collected coverage can be accessed by mapping the device
+using
+.Xr mmap 2 .
+.Pp
+By default,
+.Nm
+is not enabled but requires the compile-time configuration
+.Cd makeoptions KCOV
+.Cd options KCOV
+to be present,
+see
+.Xr options 4 .
+.Pp
+The following
+.Xr ioctl 2
+calls are provided:
+.Bl -tag -width 4n
+.It Dv KCOV_IOC_SETBUFSIZE Fa uint64_t *nentries
+Allocate a coverage buffer with a capacity of
+.Fa nentries .
+The buffer can be accessed using
+.Xr mmap 2
+whereas the returned pointer must be interpreted as an array of
+.Vt kcov_int_t
+entries. Note that kcov_int_t is volatile.
+The first entry contains the number of entries in the array,
+excluding the first entry.
+.It Dv KCOV_IOC_ENABLE Fa void
+Enable code coverage tracing for the current thread.
+.It Dv KCOV_IOC_DISABLE Fa void
+Disable code coverage tracing for the current thread.
+.El
+.Sh FILES
+.Bl -tag -width /dev/kcov -compact
+.It Pa /dev/kcov
+Default device node.
+.El
+.Sh EXAMPLES
+In the following example,
+the
+.Xr read 2
+syscall is traced and the coverage displayed, which in turn can be passed to
+.Xr addr2line 1
+in order to translate the kernel program counter into the file name and line
+number it corresponds to.
+.Bd -literal
+#include <err.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <sys/ioccom.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+
+#include <sys/kcov.h>
+
+int
+main(void)
+{
+       kcov_int_t *cover, i, n;
+       kcov_int_t size = 1024 * 100;
+       int fd;
+
+       fd = open("/dev/kcov", O_RDWR);
+       if (fd == -1)
+               err(1, "open");
+       if (ioctl(fd, KCOV_IOC_SETBUFSIZE, &size) == -1)
+               err(1, "ioctl: KCOV_IOC_SETBUFSIZE");
+       cover = mmap(NULL, size * KCOV_ENTRY_SIZE,
+           PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
+       if (cover == MAP_FAILED)
+               err(1, "mmap");
+       if (ioctl(fd, KCOV_IOC_ENABLE) == -1)
+               err(1, "ioctl: KCOV_IOC_ENABLE");
+       __atomic_store_n(&cover[0], 0, __ATOMIC_RELAXED);
+       read(-1, NULL, 0); /* syscall paths to be traced */
+       n = __atomic_load_n(&cover[0], __ATOMIC_RELAXED);
+       if (ioctl(fd, KCOV_IOC_DISABLE) == -1)
+               err(1, "ioctl: KCOV_IOC_DISABLE");
+       for (i = 0; i < cover[0]; i++)
+               printf("%p\en", (void *)cover[i + 1]);
+       if (munmap(cover, size * KCOV_ENTRY_SIZE) == -1)
+               err(1, "munmap");
+       close(fd);
+
+       return 0;
+}
+.Ed
+.Sh SEE ALSO
+.Xr options 4
+.Sh HISTORY
+The
+.Nm
+driver was initially developed in Linux. A driver based on the same concept
+was then implemented in
+.Nx 9 .
+.Sh AUTHORS
+.An Siddharth Muralee Aq Mt siddharth.muralee%gmail.com@localhost
diff -r e56f98983f2f -r e06f14301b2f share/mk/bsd.sys.mk
--- a/share/mk/bsd.sys.mk       Fri Feb 22 23:01:25 2019 +0000
+++ b/share/mk/bsd.sys.mk       Sat Feb 23 03:10:05 2019 +0000
@@ -1,4 +1,4 @@
-#      $NetBSD: bsd.sys.mk,v 1.290 2019/01/21 21:11:54 christos Exp $
+#      $NetBSD: bsd.sys.mk,v 1.291 2019/02/23 03:10:06 kamil Exp $
 #
 # Build definitions used for NetBSD source tree builds.
 
@@ -240,6 +240,14 @@
 CFLAGS+=       ${KLEAKFLAGS.${.IMPSRC:T}:U${KLEAKFLAGS}}
 .endif
 
+.if ${KCOV:U0} > 0
+KCOVFLAGS=     -fsanitize-coverage=trace-pc
+.for f in subr_kcov.c subr_lwp_specificdata.c subr_specificdata.c
+KCOVFLAGS.${f}=                # empty
+.endfor
+CFLAGS+=       ${KCOVFLAGS.${.IMPSRC:T}:U${KCOVFLAGS}}
+.endif
+
 .if !defined(NOPIE) && (!defined(LDSTATIC) || ${LDSTATIC} != "-static")
 # Position Independent Executable flags
 PIE_CFLAGS?=        -fPIE
diff -r e56f98983f2f -r e06f14301b2f sys/arch/amd64/conf/GENERIC
--- a/sys/arch/amd64/conf/GENERIC       Fri Feb 22 23:01:25 2019 +0000
+++ b/sys/arch/amd64/conf/GENERIC       Sat Feb 23 03:10:05 2019 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: GENERIC,v 1.516 2019/02/15 08:54:01 nonaka Exp $
+# $NetBSD: GENERIC,v 1.517 2019/02/23 03:10:06 kamil Exp $
 #
 # GENERIC machine description file
 #
@@ -22,7 +22,7 @@
 
 options        INCLUDE_CONFIG_FILE     # embed config file in kernel binary
 
-#ident         "GENERIC-$Revision: 1.516 $"
+#ident         "GENERIC-$Revision: 1.517 $"
 
 maxusers       64              # estimated number of users
 
@@ -130,6 +130,10 @@
 #makeoptions   KLEAK=1
 #options       KLEAK
 
+# Kernel Code Coverage Driver.
+#makeoptions   KCOV=1
+#options       KCOV
+
 # Compatibility options
 # x86_64 never shipped with a.out binaries; the two options below are
 # only relevant to 32-bit i386 binaries
diff -r e56f98983f2f -r e06f14301b2f sys/conf/files
--- a/sys/conf/files    Fri Feb 22 23:01:25 2019 +0000
+++ b/sys/conf/files    Sat Feb 23 03:10:05 2019 +0000
@@ -1,4 +1,4 @@



Home | Main Index | Thread Index | Old Index