Source-Changes-HG archive

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

[src/trunk]: src Introduce KLEAK, a new feature that can detect kernel inform...



details:   https://anonhg.NetBSD.org/src/rev/1ba60689d2d1
branches:  trunk
changeset: 446369:1ba60689d2d1
user:      maxv <maxv%NetBSD.org@localhost>
date:      Sun Dec 02 21:00:13 2018 +0000

description:
Introduce KLEAK, a new feature that can detect kernel information leaks.

It works by tainting memory sources with marker values, letting the data
travel through the kernel, and scanning the kernel<->user frontier for
these marker values. Combined with compiler instrumentation and rotation
of the markers, it is able to yield relevant results with little effort.

We taint the pools and the stack, and scan copyout/copyoutstr. KLEAK is
supported on amd64 only for now, but it is not complicated to add more
architectures (just a matter of having the address of .text, and a stack
unwinder).

A userland tool is provided, that allows to execute a command in rounds
and monitor the leaks generated all the while.

KLEAK already detected directly 12 kernel info leaks, and prompted changes
that in total fixed 25+ leaks.

Based on an idea developed jointly with Thomas Barabosch (of Fraunhofer
FKIE).

diffstat:

 share/mk/bsd.sys.mk            |   10 +-
 sys/arch/amd64/conf/GENERIC    |    8 +-
 sys/arch/amd64/include/kleak.h |  101 +++++++++
 sys/arch/amd64/include/param.h |    5 +-
 sys/conf/files                 |    3 +-
 sys/conf/ssp.mk                |    4 +-
 sys/kern/files.kern            |    3 +-
 sys/kern/subr_kleak.c          |  440 +++++++++++++++++++++++++++++++++++++++++
 sys/kern/subr_pool.c           |   36 +++-
 sys/kern/sys_syscall.c         |    5 +-
 sys/sys/systm.h                |   15 +-
 sys/uvm/uvm_km.c               |    8 +-
 usr.sbin/kleak/Makefile        |   14 +
 usr.sbin/kleak/kleak.c         |  344 ++++++++++++++++++++++++++++++++
 14 files changed, 981 insertions(+), 15 deletions(-)

diffs (truncated from 1226 to 300 lines):

diff -r 4263bac8220e -r 1ba60689d2d1 share/mk/bsd.sys.mk
--- a/share/mk/bsd.sys.mk       Sun Dec 02 20:54:44 2018 +0000
+++ b/share/mk/bsd.sys.mk       Sun Dec 02 21:00:13 2018 +0000
@@ -1,4 +1,4 @@
-#      $NetBSD: bsd.sys.mk,v 1.286 2018/08/03 02:34:31 kamil Exp $
+#      $NetBSD: bsd.sys.mk,v 1.287 2018/12/02 21:00:13 maxv Exp $
 #
 # Build definitions used for NetBSD source tree builds.
 
@@ -232,6 +232,14 @@
 CFLAGS+=       ${CPUFLAGS}
 AFLAGS+=       ${CPUFLAGS}
 
+.if ${KLEAK:U0} > 0
+KLEAKFLAGS=    -fsanitize-coverage=trace-pc
+.for f in subr_kleak.c
+KLEAKFLAGS.${f}=       # empty
+.endfor
+CFLAGS+=       ${KLEAKFLAGS.${.IMPSRC:T}:U${KLEAKFLAGS}}
+.endif
+
 .if !defined(NOPIE) && (!defined(LDSTATIC) || ${LDSTATIC} != "-static")
 # Position Independent Executable flags
 PIE_CFLAGS?=        -fPIE
diff -r 4263bac8220e -r 1ba60689d2d1 sys/arch/amd64/conf/GENERIC
--- a/sys/arch/amd64/conf/GENERIC       Sun Dec 02 20:54:44 2018 +0000
+++ b/sys/arch/amd64/conf/GENERIC       Sun Dec 02 21:00:13 2018 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: GENERIC,v 1.508 2018/11/24 18:23:29 bouyer Exp $
+# $NetBSD: GENERIC,v 1.509 2018/12/02 21:00:13 maxv Exp $
 #
 # GENERIC machine description file
 #
@@ -22,7 +22,7 @@
 
 options        INCLUDE_CONFIG_FILE     # embed config file in kernel binary
 
-#ident         "GENERIC-$Revision: 1.508 $"
+#ident         "GENERIC-$Revision: 1.509 $"
 
 maxusers       64              # estimated number of users
 
@@ -125,6 +125,10 @@
 #options       KASAN
 #no options    SVS
 
+# Kernel Info Leak Detector.
+#makeoptions   KLEAK=1
+#options       KLEAK
+
 # Compatibility options
 # x86_64 never shipped with a.out binaries; the two options below are
 # only relevant to 32-bit i386 binaries
diff -r 4263bac8220e -r 1ba60689d2d1 sys/arch/amd64/include/kleak.h
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/arch/amd64/include/kleak.h    Sun Dec 02 21:00:13 2018 +0000
@@ -0,0 +1,101 @@
+/*     $NetBSD: kleak.h,v 1.1 2018/12/02 21:00:13 maxv Exp $   */
+
+/*
+ * Copyright (c) 2018 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Maxime Villard.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/ksyms.h>
+
+#include <amd64/pmap.h>
+#include <amd64/vmparam.h>
+
+static void
+kleak_md_init(uintptr_t *sva, uintptr_t *eva)
+{
+       extern char __rodata_start;
+       *sva = (uintptr_t)KERNTEXTOFF;
+       *eva = (uintptr_t)&__rodata_start;
+}
+
+static inline bool
+__md_unwind_end(const char *name)
+{
+       if (!strcmp(name, "syscall") ||
+           !strcmp(name, "handle_syscall") ||
+           !strncmp(name, "Xintr", 5) ||
+           !strncmp(name, "Xhandle", 7) ||
+           !strncmp(name, "Xresume", 7) ||
+           !strncmp(name, "Xstray", 6) ||
+           !strncmp(name, "Xhold", 5) ||
+           !strncmp(name, "Xrecurse", 8) ||
+           !strcmp(name, "Xdoreti") ||
+           !strncmp(name, "Xsoft", 5)) {
+               return true;
+       }
+
+       return false;
+}
+
+static void
+kleak_md_unwind(struct kleak_hit *hit)
+{
+       uint64_t *rbp, rip;
+       const char *mod;
+       const char *sym;
+       int error;
+
+       rbp = (uint64_t *)__builtin_frame_address(0);
+
+       hit->npc = 0;
+
+       while (1) {
+               /* 8(%rbp) contains the saved %rip. */
+               rip = *(rbp + 1);
+
+               if (rip < KERNBASE) {
+                       break;
+               }
+               error = ksyms_getname(&mod, &sym, (vaddr_t)rip, KSYMS_PROC);
+               if (error) {
+                       break;
+               }
+               hit->pc[hit->npc++] = rip;
+               if (__md_unwind_end(sym)) {
+                       break;
+               }
+
+               rbp = (uint64_t *)*(rbp);
+               if (rbp == 0) {
+                       break;
+               }
+
+               if (hit->npc >= KLEAK_HIT_MAXPC) {
+                       break;
+               }
+       }
+}
diff -r 4263bac8220e -r 1ba60689d2d1 sys/arch/amd64/include/param.h
--- a/sys/arch/amd64/include/param.h    Sun Dec 02 20:54:44 2018 +0000
+++ b/sys/arch/amd64/include/param.h    Sun Dec 02 21:00:13 2018 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: param.h,v 1.26 2018/08/22 12:07:43 maxv Exp $  */
+/*     $NetBSD: param.h,v 1.27 2018/12/02 21:00:13 maxv Exp $  */
 
 #ifdef __x86_64__
 
@@ -11,6 +11,7 @@
 #include <machine/cpu.h>
 #if defined(_KERNEL_OPT)
 #include "opt_kasan.h"
+#include "opt_kleak.h"
 #endif
 #endif
 
@@ -61,7 +62,7 @@
 #define        SSIZE           1               /* initial stack size/NBPG */
 #define        SINCR           1               /* increment of stack/NBPG */
 
-#ifdef KASAN
+#if defined(KASAN) || defined(KLEAK)
 #define        UPAGES          8
 #elif defined(DIAGNOSTIC)
 #define        UPAGES          5               /* pages of u-area (1 for redzone) */
diff -r 4263bac8220e -r 1ba60689d2d1 sys/conf/files
--- a/sys/conf/files    Sun Dec 02 20:54:44 2018 +0000
+++ b/sys/conf/files    Sun Dec 02 21:00:13 2018 +0000
@@ -1,4 +1,4 @@
-#      $NetBSD: files,v 1.1216 2018/11/07 07:43:07 maxv Exp $
+#      $NetBSD: files,v 1.1217 2018/12/02 21:00:13 maxv Exp $
 #      @(#)files.newconf       7.5 (Berkeley) 5/10/93
 
 version        20171118
@@ -30,6 +30,7 @@
 defflag opt_diagnostic.h       _DIAGNOSTIC
 defflag                                GPROF
 defflag                                KASAN
+defflag                                KLEAK
 
 defparam opt_copy_symtab.h     makeoptions_COPY_SYMTAB
 
diff -r 4263bac8220e -r 1ba60689d2d1 sys/conf/ssp.mk
--- a/sys/conf/ssp.mk   Sun Dec 02 20:54:44 2018 +0000
+++ b/sys/conf/ssp.mk   Sun Dec 02 21:00:13 2018 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: ssp.mk,v 1.2 2017/01/08 17:10:35 christos Exp $
+# $NetBSD: ssp.mk,v 1.3 2018/12/02 21:00:13 maxv Exp $
 
 .if ${USE_SSP:Uno} == "yes"
 COPTS.kern_ssp.c+=     -fno-stack-protector -D__SSP__
@@ -10,6 +10,8 @@
 COPTS.cpu.c+=          -fno-stack-protector
 .endif
 
+COPTS.subr_kleak.c+=   -fno-stack-protector
+
 # The following files use alloca(3) or variable array allocations.
 # Their full name is noted as documentation.
 VARSTACK= \
diff -r 4263bac8220e -r 1ba60689d2d1 sys/kern/files.kern
--- a/sys/kern/files.kern       Sun Dec 02 20:54:44 2018 +0000
+++ b/sys/kern/files.kern       Sun Dec 02 21:00:13 2018 +0000
@@ -1,4 +1,4 @@
-#      $NetBSD: files.kern,v 1.25 2018/11/15 09:38:57 maxv Exp $
+#      $NetBSD: files.kern,v 1.26 2018/12/02 21:00:13 maxv Exp $
 
 #
 # kernel sources
@@ -117,6 +117,7 @@
 file   kern/subr_iostat.c              kern
 file   kern/subr_ipi.c                 kern
 file   kern/subr_kcpuset.c             kern
+file   kern/subr_kleak.c               kleak
 defflag        opt_kmem.h                      KMEM_GUARD
                                        KMEM_SIZE
 defparam opt_kmem.h                    KMEM_GUARD_DEPTH
diff -r 4263bac8220e -r 1ba60689d2d1 sys/kern/subr_kleak.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/kern/subr_kleak.c     Sun Dec 02 21:00:13 2018 +0000
@@ -0,0 +1,440 @@
+/*     $NetBSD: subr_kleak.c,v 1.1 2018/12/02 21:00:13 maxv Exp $      */
+
+/*
+ * Copyright (c) 2018 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Maxime Villard. Based on an idea developed by Maxime Villard and
+ * Thomas Barabosch of Fraunhofer FKIE.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: subr_kleak.c,v 1.1 2018/12/02 21:00:13 maxv Exp $");
+
+#include <sys/param.h>
+#include <sys/device.h>
+#include <sys/kernel.h>
+#include <sys/param.h>
+#include <sys/conf.h>
+#include <sys/systm.h>
+#include <sys/kmem.h>
+#include <sys/sysctl.h>
+#include <sys/types.h>
+
+#include <sys/ksyms.h>
+#include <sys/callout.h>
+
+#define __RET_ADDR     __builtin_return_address(0)
+
+#undef copyout
+#undef copyoutstr
+
+static uintptr_t kleak_kernel_text __read_mostly;
+
+static bool kleak_enabled = false;
+static int kleak_nrounds = 1;  /* tunable [1:8] */
+
+static bool dummy1, dummy2, dummy3;
+



Home | Main Index | Thread Index | Old Index