Skip to content

Commit

Permalink
kmsan: add KMSAN hooks for kernel subsystems
Browse files Browse the repository at this point in the history
This patch provides hooks that subsystems use to notify KMSAN about
changes in the kernel state. Such changes include:
 - page operations (allocation, deletion, splitting, mapping);
 - memory allocation and deallocation;
 - entering and leaving IRQ/NMI/softirq contexts;
 - copying data between kernel, userspace and hardware.

This patch has been split away from the rest of KMSAN runtime to
simplify the review process.

Signed-off-by: Alexander Potapenko <glider@google.com>
To: Alexander Potapenko <glider@google.com>
Cc: Jens Axboe <axboe@kernel.dk>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Wolfram Sang <wsa@the-dreams.de>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Vegard Nossum <vegard.nossum@oracle.com>
Cc: Dmitry Vyukov <dvyukov@google.com>
Cc: Marco Elver <elver@google.com>
Cc: Andrey Konovalov <andreyknvl@google.com>
Cc: linux-mm@kvack.org

---

v4:
 - fix a lot of comments by Marco Elver and Andrey Konovalov:
 - clean up headers and #defines, remove debugging code
 - simplified KMSAN entry hooks
 - fixed kmsan_check_skb()

Change-Id: I99d1f34f26bef122897cb840dac8d5b34d2b6a80
  • Loading branch information
ramosian-glider committed Mar 24, 2020
1 parent 5f588b0 commit 491a67c
Show file tree
Hide file tree
Showing 3 changed files with 547 additions and 0 deletions.
93 changes: 93 additions & 0 deletions arch/x86/include/asm/kmsan.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Assembly bits to safely invoke KMSAN hooks from .S files.
*
* Copyright (C) 2017-2019 Google LLC
* Author: Alexander Potapenko <glider@google.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
*/
#ifndef _ASM_X86_KMSAN_H
#define _ASM_X86_KMSAN_H

#ifdef CONFIG_KMSAN

#ifdef __ASSEMBLY__
.macro KMSAN_PUSH_REGS
pushq %rax
pushq %rcx
pushq %rdx
pushq %rdi
pushq %rsi
pushq %r8
pushq %r9
pushq %r10
pushq %r11
.endm

.macro KMSAN_POP_REGS
popq %r11
popq %r10
popq %r9
popq %r8
popq %rsi
popq %rdi
popq %rdx
popq %rcx
popq %rax

.endm

.macro KMSAN_CALL_HOOK fname
KMSAN_PUSH_REGS
call \fname
KMSAN_POP_REGS
.endm

.macro KMSAN_CONTEXT_ENTER
KMSAN_CALL_HOOK kmsan_context_enter
.endm

.macro KMSAN_CONTEXT_EXIT
KMSAN_CALL_HOOK kmsan_context_exit
.endm

#define KMSAN_INTERRUPT_ENTER KMSAN_CONTEXT_ENTER
#define KMSAN_INTERRUPT_EXIT KMSAN_CONTEXT_EXIT

#define KMSAN_SOFTIRQ_ENTER KMSAN_CONTEXT_ENTER
#define KMSAN_SOFTIRQ_EXIT KMSAN_CONTEXT_EXIT

#define KMSAN_NMI_ENTER KMSAN_CONTEXT_ENTER
#define KMSAN_NMI_EXIT KMSAN_CONTEXT_EXIT

#define KMSAN_IST_ENTER(shift_ist) KMSAN_CONTEXT_ENTER
#define KMSAN_IST_EXIT(shift_ist) KMSAN_CONTEXT_EXIT

.macro KMSAN_UNPOISON_PT_REGS
KMSAN_CALL_HOOK kmsan_unpoison_pt_regs
.endm

#else
#error this header must be included into an assembly file
#endif

#else /* ifdef CONFIG_KMSAN */

#define KMSAN_INTERRUPT_ENTER
#define KMSAN_INTERRUPT_EXIT
#define KMSAN_SOFTIRQ_ENTER
#define KMSAN_SOFTIRQ_EXIT
#define KMSAN_NMI_ENTER
#define KMSAN_NMI_EXIT
#define KMSAN_SYSCALL_ENTER
#define KMSAN_SYSCALL_EXIT
#define KMSAN_IST_ENTER(shift_ist)
#define KMSAN_IST_EXIT(shift_ist)
#define KMSAN_UNPOISON_PT_REGS

#endif /* ifdef CONFIG_KMSAN */
#endif /* ifndef _ASM_X86_KMSAN_H */
38 changes: 38 additions & 0 deletions mm/kmsan/kmsan_entry.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// SPDX-License-Identifier: GPL-2.0
/*
* KMSAN hooks for entry_64.S
*
* Copyright (C) 2018-2019 Google LLC
* Author: Alexander Potapenko <glider@google.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
*/

#include "kmsan.h"

void kmsan_context_enter(void)
{
int level = this_cpu_inc_return(kmsan_context_level);

BUG_ON(level >= KMSAN_NESTED_CONTEXT_MAX);
}
EXPORT_SYMBOL(kmsan_context_enter);

void kmsan_context_exit(void)
{
int level = this_cpu_dec_return(kmsan_context_level);

BUG_ON(level < 0);
}
EXPORT_SYMBOL(kmsan_context_exit);

void kmsan_unpoison_pt_regs(struct pt_regs *regs)
{
if (!kmsan_ready || kmsan_in_runtime())
return;
kmsan_internal_unpoison_shadow(regs, sizeof(*regs), /*checked*/true);
}
EXPORT_SYMBOL(kmsan_unpoison_pt_regs);
Loading

0 comments on commit 491a67c

Please sign in to comment.