2014-07-02 19:54:43 +07:00
|
|
|
#
|
|
|
|
# The stub may be linked into the kernel proper or into a separate boot binary,
|
|
|
|
# but in either case, it executes before the kernel does (with MMU disabled) so
|
|
|
|
# things like ftrace and stack-protector are likely to cause trouble if left
|
|
|
|
# enabled, even if doing so doesn't break the build.
|
|
|
|
#
|
|
|
|
cflags-$(CONFIG_X86_32) := -march=i386
|
|
|
|
cflags-$(CONFIG_X86_64) := -mcmodel=small
|
2016-11-03 15:53:50 +07:00
|
|
|
cflags-$(CONFIG_X86) += -m$(BITS) -D__KERNEL__ -O2 \
|
2014-07-02 19:54:43 +07:00
|
|
|
-fPIC -fno-strict-aliasing -mno-red-zone \
|
2015-12-23 16:29:28 +07:00
|
|
|
-mno-mmx -mno-sse
|
2014-07-02 19:54:43 +07:00
|
|
|
|
2017-08-19 02:49:37 +07:00
|
|
|
cflags-$(CONFIG_ARM64) := $(subst -pg,,$(KBUILD_CFLAGS)) -fpie
|
2017-01-31 20:21:42 +07:00
|
|
|
cflags-$(CONFIG_ARM) := $(subst -pg,,$(KBUILD_CFLAGS)) \
|
2014-07-02 19:54:43 +07:00
|
|
|
-fno-builtin -fpic -mno-single-pic-base
|
|
|
|
|
2015-10-09 02:02:04 +07:00
|
|
|
cflags-$(CONFIG_EFI_ARMSTUB) += -I$(srctree)/scripts/dtc/libfdt
|
|
|
|
|
2015-12-23 16:29:28 +07:00
|
|
|
KBUILD_CFLAGS := $(cflags-y) -DDISABLE_BRANCH_PROFILING \
|
2017-07-13 04:35:55 +07:00
|
|
|
-D__NO_FORTIFY \
|
2014-07-02 19:54:43 +07:00
|
|
|
$(call cc-option,-ffreestanding) \
|
|
|
|
$(call cc-option,-fno-stack-protector)
|
|
|
|
|
|
|
|
GCOV_PROFILE := n
|
kasan: add kernel address sanitizer infrastructure
Kernel Address sanitizer (KASan) is a dynamic memory error detector. It
provides fast and comprehensive solution for finding use-after-free and
out-of-bounds bugs.
KASAN uses compile-time instrumentation for checking every memory access,
therefore GCC > v4.9.2 required. v4.9.2 almost works, but has issues with
putting symbol aliases into the wrong section, which breaks kasan
instrumentation of globals.
This patch only adds infrastructure for kernel address sanitizer. It's
not available for use yet. The idea and some code was borrowed from [1].
Basic idea:
The main idea of KASAN is to use shadow memory to record whether each byte
of memory is safe to access or not, and use compiler's instrumentation to
check the shadow memory on each memory access.
Address sanitizer uses 1/8 of the memory addressable in kernel for shadow
memory and uses direct mapping with a scale and offset to translate a
memory address to its corresponding shadow address.
Here is function to translate address to corresponding shadow address:
unsigned long kasan_mem_to_shadow(unsigned long addr)
{
return (addr >> KASAN_SHADOW_SCALE_SHIFT) + KASAN_SHADOW_OFFSET;
}
where KASAN_SHADOW_SCALE_SHIFT = 3.
So for every 8 bytes there is one corresponding byte of shadow memory.
The following encoding used for each shadow byte: 0 means that all 8 bytes
of the corresponding memory region are valid for access; k (1 <= k <= 7)
means that the first k bytes are valid for access, and other (8 - k) bytes
are not; Any negative value indicates that the entire 8-bytes are
inaccessible. Different negative values used to distinguish between
different kinds of inaccessible memory (redzones, freed memory) (see
mm/kasan/kasan.h).
To be able to detect accesses to bad memory we need a special compiler.
Such compiler inserts a specific function calls (__asan_load*(addr),
__asan_store*(addr)) before each memory access of size 1, 2, 4, 8 or 16.
These functions check whether memory region is valid to access or not by
checking corresponding shadow memory. If access is not valid an error
printed.
Historical background of the address sanitizer from Dmitry Vyukov:
"We've developed the set of tools, AddressSanitizer (Asan),
ThreadSanitizer and MemorySanitizer, for user space. We actively use
them for testing inside of Google (continuous testing, fuzzing,
running prod services). To date the tools have found more than 10'000
scary bugs in Chromium, Google internal codebase and various
open-source projects (Firefox, OpenSSL, gcc, clang, ffmpeg, MySQL and
lots of others): [2] [3] [4].
The tools are part of both gcc and clang compilers.
We have not yet done massive testing under the Kernel AddressSanitizer
(it's kind of chicken and egg problem, you need it to be upstream to
start applying it extensively). To date it has found about 50 bugs.
Bugs that we've found in upstream kernel are listed in [5].
We've also found ~20 bugs in out internal version of the kernel. Also
people from Samsung and Oracle have found some.
[...]
As others noted, the main feature of AddressSanitizer is its
performance due to inline compiler instrumentation and simple linear
shadow memory. User-space Asan has ~2x slowdown on computational
programs and ~2x memory consumption increase. Taking into account that
kernel usually consumes only small fraction of CPU and memory when
running real user-space programs, I would expect that kernel Asan will
have ~10-30% slowdown and similar memory consumption increase (when we
finish all tuning).
I agree that Asan can well replace kmemcheck. We have plans to start
working on Kernel MemorySanitizer that finds uses of unitialized
memory. Asan+Msan will provide feature-parity with kmemcheck. As
others noted, Asan will unlikely replace debug slab and pagealloc that
can be enabled at runtime. Asan uses compiler instrumentation, so even
if it is disabled, it still incurs visible overheads.
Asan technology is easily portable to other architectures. Compiler
instrumentation is fully portable. Runtime has some arch-dependent
parts like shadow mapping and atomic operation interception. They are
relatively easy to port."
Comparison with other debugging features:
========================================
KMEMCHECK:
- KASan can do almost everything that kmemcheck can. KASan uses
compile-time instrumentation, which makes it significantly faster than
kmemcheck. The only advantage of kmemcheck over KASan is detection of
uninitialized memory reads.
Some brief performance testing showed that kasan could be
x500-x600 times faster than kmemcheck:
$ netperf -l 30
MIGRATED TCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to localhost (127.0.0.1) port 0 AF_INET
Recv Send Send
Socket Socket Message Elapsed
Size Size Size Time Throughput
bytes bytes bytes secs. 10^6bits/sec
no debug: 87380 16384 16384 30.00 41624.72
kasan inline: 87380 16384 16384 30.00 12870.54
kasan outline: 87380 16384 16384 30.00 10586.39
kmemcheck: 87380 16384 16384 30.03 20.23
- Also kmemcheck couldn't work on several CPUs. It always sets
number of CPUs to 1. KASan doesn't have such limitation.
DEBUG_PAGEALLOC:
- KASan is slower than DEBUG_PAGEALLOC, but KASan works on sub-page
granularity level, so it able to find more bugs.
SLUB_DEBUG (poisoning, redzones):
- SLUB_DEBUG has lower overhead than KASan.
- SLUB_DEBUG in most cases are not able to detect bad reads,
KASan able to detect both reads and writes.
- In some cases (e.g. redzone overwritten) SLUB_DEBUG detect
bugs only on allocation/freeing of object. KASan catch
bugs right before it will happen, so we always know exact
place of first bad read/write.
[1] https://code.google.com/p/address-sanitizer/wiki/AddressSanitizerForKernel
[2] https://code.google.com/p/address-sanitizer/wiki/FoundBugs
[3] https://code.google.com/p/thread-sanitizer/wiki/FoundBugs
[4] https://code.google.com/p/memory-sanitizer/wiki/FoundBugs
[5] https://code.google.com/p/address-sanitizer/wiki/AddressSanitizerForKernel#Trophies
Based on work by Andrey Konovalov.
Signed-off-by: Andrey Ryabinin <a.ryabinin@samsung.com>
Acked-by: Michal Marek <mmarek@suse.cz>
Signed-off-by: Andrey Konovalov <adech.fo@gmail.com>
Cc: Dmitry Vyukov <dvyukov@google.com>
Cc: Konstantin Serebryany <kcc@google.com>
Cc: Dmitry Chernenkov <dmitryc@google.com>
Cc: Yuri Gribov <tetra2005@gmail.com>
Cc: Konstantin Khlebnikov <koct9i@gmail.com>
Cc: Sasha Levin <sasha.levin@oracle.com>
Cc: Christoph Lameter <cl@linux.com>
Cc: Joonsoo Kim <iamjoonsoo.kim@lge.com>
Cc: Dave Hansen <dave.hansen@intel.com>
Cc: Andi Kleen <andi@firstfloor.org>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: Christoph Lameter <cl@linux.com>
Cc: Pekka Enberg <penberg@kernel.org>
Cc: David Rientjes <rientjes@google.com>
Cc: Stephen Rothwell <sfr@canb.auug.org.au>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2015-02-14 05:39:17 +07:00
|
|
|
KASAN_SANITIZE := n
|
2016-01-21 06:00:55 +07:00
|
|
|
UBSAN_SANITIZE := n
|
2016-02-29 11:22:34 +07:00
|
|
|
OBJECT_FILES_NON_STANDARD := y
|
2014-07-02 19:54:43 +07:00
|
|
|
|
kernel: add kcov code coverage
kcov provides code coverage collection for coverage-guided fuzzing
(randomized testing). Coverage-guided fuzzing is a testing technique
that uses coverage feedback to determine new interesting inputs to a
system. A notable user-space example is AFL
(http://lcamtuf.coredump.cx/afl/). However, this technique is not
widely used for kernel testing due to missing compiler and kernel
support.
kcov does not aim to collect as much coverage as possible. It aims to
collect more or less stable coverage that is function of syscall inputs.
To achieve this goal it does not collect coverage in soft/hard
interrupts and instrumentation of some inherently non-deterministic or
non-interesting parts of kernel is disbled (e.g. scheduler, locking).
Currently there is a single coverage collection mode (tracing), but the
API anticipates additional collection modes. Initially I also
implemented a second mode which exposes coverage in a fixed-size hash
table of counters (what Quentin used in his original patch). I've
dropped the second mode for simplicity.
This patch adds the necessary support on kernel side. The complimentary
compiler support was added in gcc revision 231296.
We've used this support to build syzkaller system call fuzzer, which has
found 90 kernel bugs in just 2 months:
https://github.com/google/syzkaller/wiki/Found-Bugs
We've also found 30+ bugs in our internal systems with syzkaller.
Another (yet unexplored) direction where kcov coverage would greatly
help is more traditional "blob mutation". For example, mounting a
random blob as a filesystem, or receiving a random blob over wire.
Why not gcov. Typical fuzzing loop looks as follows: (1) reset
coverage, (2) execute a bit of code, (3) collect coverage, repeat. A
typical coverage can be just a dozen of basic blocks (e.g. an invalid
input). In such context gcov becomes prohibitively expensive as
reset/collect coverage steps depend on total number of basic
blocks/edges in program (in case of kernel it is about 2M). Cost of
kcov depends only on number of executed basic blocks/edges. On top of
that, kernel requires per-thread coverage because there are always
background threads and unrelated processes that also produce coverage.
With inlined gcov instrumentation per-thread coverage is not possible.
kcov exposes kernel PCs and control flow to user-space which is
insecure. But debugfs should not be mapped as user accessible.
Based on a patch by Quentin Casasnovas.
[akpm@linux-foundation.org: make task_struct.kcov_mode have type `enum kcov_mode']
[akpm@linux-foundation.org: unbreak allmodconfig]
[akpm@linux-foundation.org: follow x86 Makefile layout standards]
Signed-off-by: Dmitry Vyukov <dvyukov@google.com>
Reviewed-by: Kees Cook <keescook@chromium.org>
Cc: syzkaller <syzkaller@googlegroups.com>
Cc: Vegard Nossum <vegard.nossum@oracle.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Tavis Ormandy <taviso@google.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Quentin Casasnovas <quentin.casasnovas@oracle.com>
Cc: Kostya Serebryany <kcc@google.com>
Cc: Eric Dumazet <edumazet@google.com>
Cc: Alexander Potapenko <glider@google.com>
Cc: Kees Cook <keescook@google.com>
Cc: Bjorn Helgaas <bhelgaas@google.com>
Cc: Sasha Levin <sasha.levin@oracle.com>
Cc: David Drysdale <drysdale@google.com>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Andrey Ryabinin <ryabinin.a.a@gmail.com>
Cc: Kirill A. Shutemov <kirill@shutemov.name>
Cc: Jiri Slaby <jslaby@suse.cz>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2016-03-23 04:27:30 +07:00
|
|
|
# Prevents link failures: __sanitizer_cov_trace_pc() is not linked in.
|
|
|
|
KCOV_INSTRUMENT := n
|
|
|
|
|
2017-02-06 18:22:43 +07:00
|
|
|
lib-y := efi-stub-helper.o gop.o secureboot.o
|
2017-08-25 22:50:15 +07:00
|
|
|
lib-$(CONFIG_RESET_ATTACK_MITIGATION) += tpm.o
|
2015-10-09 02:02:04 +07:00
|
|
|
|
|
|
|
# include the stub's generic dependencies from lib/ when building for ARM/arm64
|
|
|
|
arm-deps := fdt_rw.c fdt_ro.c fdt_wip.c fdt.c fdt_empty_tree.c fdt_sw.c sort.c
|
|
|
|
|
|
|
|
$(obj)/lib-%.o: $(srctree)/lib/%.c FORCE
|
|
|
|
$(call if_changed_rule,cc_o_c)
|
|
|
|
|
2016-11-13 04:32:32 +07:00
|
|
|
lib-$(CONFIG_EFI_ARMSTUB) += arm-stub.o fdt.o string.o random.o \
|
2015-10-09 02:02:04 +07:00
|
|
|
$(patsubst %.c,lib-%.o,$(arm-deps))
|
2014-07-02 19:54:43 +07:00
|
|
|
|
2015-09-24 10:17:54 +07:00
|
|
|
lib-$(CONFIG_ARM) += arm32-stub.o
|
2016-11-13 04:32:32 +07:00
|
|
|
lib-$(CONFIG_ARM64) += arm64-stub.o
|
2015-10-23 21:48:14 +07:00
|
|
|
CFLAGS_arm64-stub.o := -DTEXT_OFFSET=$(TEXT_OFFSET)
|
|
|
|
|
2015-01-13 03:28:20 +07:00
|
|
|
#
|
|
|
|
# arm64 puts the stub in the kernel proper, which will unnecessarily retain all
|
|
|
|
# code indefinitely unless it is annotated as __init/__initdata/__initconst etc.
|
|
|
|
# So let's apply the __init annotations at the section level, by prefixing
|
|
|
|
# the section names directly. This will ensure that even all the inline string
|
|
|
|
# literals are covered.
|
2015-10-09 02:02:04 +07:00
|
|
|
# The fact that the stub and the kernel proper are essentially the same binary
|
|
|
|
# also means that we need to be extra careful to make sure that the stub does
|
|
|
|
# not rely on any absolute symbol references, considering that the virtual
|
|
|
|
# kernel mapping that the linker uses is not active yet when the stub is
|
|
|
|
# executing. So build all C dependencies of the EFI stub into libstub, and do
|
|
|
|
# a verification pass to see if any absolute relocations exist in any of the
|
|
|
|
# object files.
|
2015-01-13 03:28:20 +07:00
|
|
|
#
|
2015-10-09 02:02:04 +07:00
|
|
|
extra-$(CONFIG_EFI_ARMSTUB) := $(lib-y)
|
|
|
|
lib-$(CONFIG_EFI_ARMSTUB) := $(patsubst %.o,%.stub.o,$(lib-y))
|
|
|
|
|
2017-01-31 20:21:42 +07:00
|
|
|
STUBCOPY_RM-y := -R *ksymtab* -R *kcrctab*
|
2015-10-09 02:02:04 +07:00
|
|
|
STUBCOPY_FLAGS-$(CONFIG_ARM64) += --prefix-alloc-sections=.init \
|
|
|
|
--prefix-symbols=__efistub_
|
|
|
|
STUBCOPY_RELOC-$(CONFIG_ARM64) := R_AARCH64_ABS
|
|
|
|
|
|
|
|
$(obj)/%.stub.o: $(obj)/%.o FORCE
|
|
|
|
$(call if_changed,stubcopy)
|
2015-01-13 03:28:20 +07:00
|
|
|
|
2017-01-31 20:21:42 +07:00
|
|
|
#
|
|
|
|
# Strip debug sections and some other sections that may legally contain
|
|
|
|
# absolute relocations, so that we can inspect the remaining sections for
|
|
|
|
# such relocations. If none are found, regenerate the output object, but
|
|
|
|
# this time, use objcopy and leave all sections in place.
|
|
|
|
#
|
2015-10-09 02:02:04 +07:00
|
|
|
quiet_cmd_stubcopy = STUBCPY $@
|
2017-01-31 20:21:42 +07:00
|
|
|
cmd_stubcopy = if $(STRIP) --strip-debug $(STUBCOPY_RM-y) -o $@ $<; \
|
|
|
|
then if $(OBJDUMP) -r $@ | grep $(STUBCOPY_RELOC-y); \
|
|
|
|
then (echo >&2 "$@: absolute symbol references not allowed in the EFI stub"; \
|
|
|
|
rm -f $@; /bin/false); \
|
|
|
|
else $(OBJCOPY) $(STUBCOPY_FLAGS-y) $< $@; fi \
|
|
|
|
else /bin/false; fi
|
2015-09-24 10:17:54 +07:00
|
|
|
|
|
|
|
#
|
|
|
|
# ARM discards the .data section because it disallows r/w data in the
|
|
|
|
# decompressor. So move our .data to .data.efistub, which is preserved
|
|
|
|
# explicitly by the decompressor linker script.
|
|
|
|
#
|
2017-01-31 20:21:42 +07:00
|
|
|
STUBCOPY_FLAGS-$(CONFIG_ARM) += --rename-section .data=.data.efistub
|
|
|
|
STUBCOPY_RM-$(CONFIG_ARM) += -R ___ksymtab+sort -R ___kcrctab+sort
|
2015-09-24 10:17:54 +07:00
|
|
|
STUBCOPY_RELOC-$(CONFIG_ARM) := R_ARM_ABS
|