[PATCH RFC v3 00/36] Add KernelMemorySanitizer infrastructure

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

 



KernelMemorySanitizer (KMSAN) is a detector of errors related to uses of
uninitialized memory. It relies on compile-time Clang instrumentation
(similar to MSan in the userspace:
https://clang.llvm.org/docs/MemorySanitizer.html)
and tracks the state of every bit of kernel memory, being able to report
an error if uninitialized value is used in a condition, dereferenced or
copied to userspace, USB or network.

KMSAN has reported more than 200 bugs in the past two years, most of
them with the help of syzkaller (http://syzkaller.appspot.com).

The proposed patchset contains KMSAN runtime implementation together
with small changes to other subsystems needed to make KMSAN work.
The latter changes fall into several categories:
 - nice-to-have features that are independent from KMSAN but simplify
   its implementation (stackdepot changes, CONFIG_GENERIC_CSUM etc.);
 - Kconfig changes that prohibit options incompatible with KMSAN;
 - calls to KMSAN runtime functions that help KMSAN do the bookkeeping
   (e.g. tell it to allocate, copy or delete the metadata);
 - calls to KMSAN runtime functions that tell KMSAN to check memory
   escaping the kernel for uninitialized values. These are required to
   increase the number of true positive error reports;
 - calls to runtime functions that tell KMSAN to ignore certain memory
   ranges to avoid false negative reports. Most certainly there can be
   better ways to deal with every such report.

This patchset allows one to boot and run a defconfig+KMSAN kernel on a QEMU
without known major false positives. It however doesn't guarantee there
are no false positives in drivers of certain devices or less tested
subsystems, although KMSAN is actively tested on syzbot with quite a
rich config.

One may find it handy to review these patches in Gerrit:
https://linux-review.googlesource.com/c/linux/kernel/git/torvalds/linux/+/1081
I've ensured the Change-Id: tags stay away from commit descriptions.

The patchset was generated relative to Linux v5.4-rc5.

I also apologize for not sending every patch in the previous series
to all recipients of patches from that series.

Note: checkpatch.pl complains a lot about the use of BUG_ON in KMSAN
source. I don't have a strong opinion on this, but KMSAN is a debugging
tool, so any runtime invariant violation in it renders the tool useless.
Therefore it doesn't make much sense to not terminate after a bug in
KMSAN.

Alexander Potapenko (36):
  stackdepot: check depot_index before accessing the stack slab
  stackdepot: build with -fno-builtin
  kasan: stackdepot: move filter_irq_stacks() to stackdepot.c
  stackdepot: reserve 5 extra bits in depot_stack_handle_t
  kmsan: add ReST documentation
  kmsan: gfp: introduce __GFP_NO_KMSAN_SHADOW
  kmsan: introduce __no_sanitize_memory and __SANITIZE_MEMORY__
  kmsan: reduce vmalloc space
  kmsan: add KMSAN bits to struct page and struct task_struct
  kmsan: add KMSAN runtime
  kmsan: stackdepot: don't allocate KMSAN metadata for stackdepot
  kmsan: define READ_ONCE_NOCHECK()
  kmsan: make READ_ONCE_TASK_STACK() return initialized values
  kmsan: x86: sync metadata pages on page fault
  kmsan: add tests for KMSAN
  crypto: kmsan: disable accelerated configs under KMSAN
  kmsan: x86: disable UNWINDER_ORC under KMSAN
  kmsan: disable LOCK_DEBUGGING_SUPPORT
  kmsan: x86/asm: add KMSAN hooks to entry_64.S
  kmsan: x86: increase stack sizes in KMSAN builds
  kmsan: disable KMSAN instrumentation for certain kernel parts
  kmsan: mm: call KMSAN hooks from SLUB code
  kmsan: call KMSAN hooks where needed
  kmsan: disable instrumentation of certain functions
  kmsan: unpoison |tlb| in arch_tlb_gather_mmu()
  kmsan: use __msan_memcpy() where possible.
  kmsan: hooks for copy_to_user() and friends
  kmsan: enable KMSAN builds
  kmsan: handle /dev/[u]random
  kmsan: virtio: check/unpoison scatterlist in vring_map_one_sg()
  kmsan: disable strscpy() optimization under KMSAN
  kmsan: add iomap support
  kmsan: dma: unpoison memory mapped by dma_direct_map_page()
  kmsan: disable physical page merging in biovec
  kmsan: ext4: skip block merging logic in ext4_mpage_readpages for
    KMSAN
  net: kasan: kmsan: support CONFIG_GENERIC_CSUM on x86, enable it for
    KASAN/KMSAN

To: Alexander Potapenko <glider@xxxxxxxxxx>
Cc: Alexander Viro <viro@xxxxxxxxxxxxxxxxxx>
Cc: Andreas Dilger <adilger.kernel@xxxxxxxxx>
Cc: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx>
Cc: Andrey Konovalov <andreyknvl@xxxxxxxxxx>
Cc: Andrey Ryabinin <aryabinin@xxxxxxxxxxxxx>
Cc: Andy Lutomirski <luto@xxxxxxxxxx>
Cc: Ard Biesheuvel <ard.biesheuvel@xxxxxxxxxx>
Cc: Arnd Bergmann <arnd@xxxxxxxx>
Cc: Christoph Hellwig <hch@xxxxxxxxxxxxx>
Cc: Christoph Hellwig <hch@xxxxxx>
Cc: Darrick J. Wong <darrick.wong@xxxxxxxxxx>
Cc: "David S. Miller" <davem@xxxxxxxxxxxxx>
Cc: Dmitry Torokhov <dmitry.torokhov@xxxxxxxxx>
Cc: Dmitry Vyukov <dvyukov@xxxxxxxxxx>
Cc: Eric Biggers <ebiggers@xxxxxxxxxx>
Cc: Eric Dumazet <edumazet@xxxxxxxxxx>
Cc: Eric Van Hensbergen <ericvh@xxxxxxxxx>
Cc: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx>
Cc: Harry Wentland <harry.wentland@xxxxxxx>
Cc: Herbert Xu <herbert@xxxxxxxxxxxxxxxxxxx>
Cc: Ilya Leoshkevich <iii@xxxxxxxxxxxxx>
Cc: Ingo Molnar <mingo@xxxxxxx>
Cc: Jason Wang <jasowang@xxxxxxxxxx>
Cc: Jens Axboe <axboe@xxxxxxxxx>
Cc: Marek Szyprowski <m.szyprowski@xxxxxxxxxxx>
Cc: Marco Elver <elver@xxxxxxxxxx>
Cc: Mark Rutland <mark.rutland@xxxxxxx>
Cc: Martin K. Petersen <martin.petersen@xxxxxxxxxx>
Cc: Martin Schwidefsky <schwidefsky@xxxxxxxxxx>
Cc: Matthew Wilcox <willy@xxxxxxxxxxxxx>
Cc: "Michael S. Tsirkin" <mst@xxxxxxxxxx>
Cc: Michal Simek <monstr@xxxxxxxxx>
Cc: Petr Mladek <pmladek@xxxxxxxx>
Cc: Qian Cai <cai@xxxxxx>
Cc: Randy Dunlap <rdunlap@xxxxxxxxxxxxx>
Cc: Robin Murphy <robin.murphy@xxxxxxx>
Cc: Sergey Senozhatsky <sergey.senozhatsky@xxxxxxxxx>
Cc: Steven Rostedt <rostedt@xxxxxxxxxxx>
Cc: Takashi Iwai <tiwai@xxxxxxxx>
Cc: "Theodore Ts'o" <tytso@xxxxxxx>
Cc: Thomas Gleixner <tglx@xxxxxxxxxxxxx>
Cc: Vasily Gorbik <gor@xxxxxxxxxxxxx>
Cc: Vegard Nossum <vegard.nossum@xxxxxxxxxx>
Cc: Wolfram Sang <wsa@xxxxxxxxxxxxx>
Cc: linux-mm@xxxxxxxxx

 Documentation/dev-tools/index.rst       |   1 +
 Documentation/dev-tools/kmsan.rst       | 418 ++++++++++++++++++
 Makefile                                |   3 +-
 arch/x86/Kconfig                        |   5 +
 arch/x86/Kconfig.debug                  |   3 +
 arch/x86/boot/Makefile                  |   2 +
 arch/x86/boot/compressed/Makefile       |   2 +
 arch/x86/boot/compressed/misc.h         |   1 +
 arch/x86/entry/common.c                 |   1 +
 arch/x86/entry/entry_64.S               |  16 +
 arch/x86/entry/vdso/Makefile            |   3 +
 arch/x86/include/asm/checksum.h         |  10 +-
 arch/x86/include/asm/irq_regs.h         |   1 +
 arch/x86/include/asm/kmsan.h            | 117 +++++
 arch/x86/include/asm/page_64.h          |  13 +
 arch/x86/include/asm/page_64_types.h    |  12 +-
 arch/x86/include/asm/pgtable_64_types.h |  15 +
 arch/x86/include/asm/string_64.h        |   9 +-
 arch/x86/include/asm/syscall_wrapper.h  |   1 +
 arch/x86/include/asm/uaccess.h          |  12 +
 arch/x86/include/asm/unwind.h           |   9 +-
 arch/x86/kernel/Makefile                |   4 +
 arch/x86/kernel/apic/apic.c             |   1 +
 arch/x86/kernel/cpu/Makefile            |   1 +
 arch/x86/kernel/dumpstack_64.c          |   1 +
 arch/x86/kernel/process_64.c            |   5 +
 arch/x86/kernel/traps.c                 |  12 +-
 arch/x86/kernel/uprobes.c               |   7 +-
 arch/x86/lib/Makefile                   |   2 +
 arch/x86/mm/Makefile                    |   2 +
 arch/x86/mm/fault.c                     |  20 +
 arch/x86/mm/ioremap.c                   |   3 +
 arch/x86/realmode/rm/Makefile           |   2 +
 block/blk.h                             |   7 +
 crypto/Kconfig                          |  52 +++
 drivers/char/random.c                   |   6 +
 drivers/firmware/efi/libstub/Makefile   |   1 +
 drivers/usb/core/urb.c                  |   2 +
 drivers/virtio/virtio_ring.c            |  10 +-
 fs/ext4/readpage.c                      |  11 +
 include/asm-generic/cacheflush.h        |   7 +-
 include/asm-generic/uaccess.h           |  12 +-
 include/linux/compiler-clang.h          |   8 +
 include/linux/compiler-gcc.h            |   5 +
 include/linux/compiler.h                |  13 +-
 include/linux/gfp.h                     |   4 +-
 include/linux/highmem.h                 |   4 +
 include/linux/kmsan-checks.h            | 122 +++++
 include/linux/kmsan.h                   | 143 ++++++
 include/linux/mm_types.h                |   9 +
 include/linux/sched.h                   |   5 +
 include/linux/stackdepot.h              |  10 +
 include/linux/string.h                  |   2 +
 include/linux/uaccess.h                 |  32 +-
 init/main.c                             |   3 +
 kernel/Makefile                         |   1 +
 kernel/dma/direct.c                     |   1 +
 kernel/exit.c                           |   2 +
 kernel/fork.c                           |   2 +
 kernel/kthread.c                        |   2 +
 kernel/printk/printk.c                  |   6 +
 kernel/profile.c                        |   1 +
 kernel/sched/core.c                     |   6 +
 kernel/softirq.c                        |   5 +
 lib/Kconfig.debug                       |   5 +
 lib/Kconfig.kmsan                       |  22 +
 lib/Makefile                            |   6 +
 lib/iomap.c                             |  40 ++
 lib/ioremap.c                           |   5 +
 lib/iov_iter.c                          |   6 +
 lib/stackdepot.c                        |  69 ++-
 lib/string.c                            |   5 +-
 lib/test_kmsan.c                        | 231 ++++++++++
 lib/usercopy.c                          |   6 +-
 mm/Makefile                             |   1 +
 mm/compaction.c                         |   9 +
 mm/gup.c                                |   3 +
 mm/kasan/common.c                       |  23 -
 mm/kmsan/Makefile                       |   4 +
 mm/kmsan/kmsan.c                        | 563 ++++++++++++++++++++++++
 mm/kmsan/kmsan.h                        | 146 ++++++
 mm/kmsan/kmsan_entry.c                  | 118 +++++
 mm/kmsan/kmsan_hooks.c                  | 422 ++++++++++++++++++
 mm/kmsan/kmsan_init.c                   |  88 ++++
 mm/kmsan/kmsan_instr.c                  | 259 +++++++++++
 mm/kmsan/kmsan_report.c                 | 133 ++++++
 mm/kmsan/kmsan_shadow.c                 | 543 +++++++++++++++++++++++
 mm/kmsan/kmsan_shadow.h                 |  30 ++
 mm/memory.c                             |   2 +
 mm/mmu_gather.c                         |  10 +
 mm/page_alloc.c                         |  16 +
 mm/slub.c                               |  34 +-
 mm/vmalloc.c                            |  23 +-
 net/sched/sch_generic.c                 |   2 +
 scripts/Makefile.kmsan                  |  12 +
 scripts/Makefile.lib                    |   6 +
 96 files changed, 3983 insertions(+), 67 deletions(-)
 create mode 100644 Documentation/dev-tools/kmsan.rst
 create mode 100644 arch/x86/include/asm/kmsan.h
 create mode 100644 include/linux/kmsan-checks.h
 create mode 100644 include/linux/kmsan.h
 create mode 100644 lib/Kconfig.kmsan
 create mode 100644 lib/test_kmsan.c
 create mode 100644 mm/kmsan/Makefile
 create mode 100644 mm/kmsan/kmsan.c
 create mode 100644 mm/kmsan/kmsan.h
 create mode 100644 mm/kmsan/kmsan_entry.c
 create mode 100644 mm/kmsan/kmsan_hooks.c
 create mode 100644 mm/kmsan/kmsan_init.c
 create mode 100644 mm/kmsan/kmsan_instr.c
 create mode 100644 mm/kmsan/kmsan_report.c
 create mode 100644 mm/kmsan/kmsan_shadow.c
 create mode 100644 mm/kmsan/kmsan_shadow.h
 create mode 100644 scripts/Makefile.kmsan

-- 
2.24.0.432.g9d3f5f5b63-goog





[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Bugtraq]     [Linux OMAP]     [Linux MIPS]     [eCos]     [Asterisk Internet PBX]     [Linux API]

  Powered by Linux