All of lore.kernel.org
 help / color / mirror / Atom feed
From: Peter Zijlstra <peterz@infradead.org>
To: Dmitry Vyukov <dvyukov@google.com>
Cc: Andrey Ryabinin <aryabinin@virtuozzo.com>,
	Linus Torvalds <torvalds@linux-foundation.org>,
	Thomas Gleixner <tglx@linutronix.de>,
	"H. Peter Anvin" <hpa@zytor.com>,
	Julien Thierry <julien.thierry@arm.com>,
	Will Deacon <will.deacon@arm.com>,
	Andy Lutomirski <luto@amacapital.net>,
	Ingo Molnar <mingo@kernel.org>,
	Catalin Marinas <catalin.marinas@arm.com>,
	James Morse <james.morse@arm.com>,
	valentin.schneider@arm.com, Brian Gerst <brgerst@gmail.com>,
	Josh Poimboeuf <jpoimboe@redhat.com>,
	Andy Lutomirski <luto@kernel.org>, Borislav Petkov <bp@alien8.de>,
	Denys Vlasenko <dvlasenk@redhat.com>,
	LKML <linux-kernel@vger.kernel.org>,
	Alexander Potapenko <glider@google.com>
Subject: Re: [PATCH 5/6] objtool: Add UACCESS validation
Date: Wed, 27 Feb 2019 18:28:16 +0100	[thread overview]
Message-ID: <20190227172816.GT32494@hirez.programming.kicks-ass.net> (raw)
In-Reply-To: <CACT4Y+a9yJvwzwVcjhyOkJUdMp05mxW1++EduLLa2M_buQ7OhA@mail.gmail.com>

On Wed, Feb 27, 2019 at 04:40:28PM +0100, Dmitry Vyukov wrote:
> On Wed, Feb 27, 2019 at 3:33 PM Peter Zijlstra <peterz@infradead.org> wrote:

> > Urgh, kasan_report() is definitely unsafe. Now, admitedly we should
> > 'never' hit that, but it does leave us up a creek without a paddle.

> If SMAP detects additional bugs, then it would be pity to disable it
> with KASAN (detect bugs in production but not during testing).
> 
> You mentioned that exception save/restore the UACCESS state. Is it
> possible to do the same in kasan_report? At the very least we need to
> survive report printing, what happens after that does not matter much
> (we've corrupted memory by now anyway).

Ideally we'll put all of kasan_report() in an exception, much like we do
for WARN. But there's a distinct lack of arch hooks there to play with.
I suppose I can try and create some.

On top of that we'll have to mark these __asan functions with notrace.

Maybe a little something horrible like so... completely untested.

---
 arch/x86/include/asm/bug.h   | 28 ++++++++++++++--------------
 arch/x86/include/asm/kasan.h | 11 +++++++++++
 include/asm-generic/bug.h    |  1 +
 include/linux/kasan.h        |  6 +++++-
 lib/bug.c                    |  8 +++++++-
 mm/kasan/generic.c           |  4 ++--
 mm/kasan/kasan.h             |  2 +-
 mm/kasan/report.c            |  2 +-
 8 files changed, 42 insertions(+), 20 deletions(-)

diff --git a/arch/x86/include/asm/bug.h b/arch/x86/include/asm/bug.h
index 6804d6642767..ead3e6ad4eb6 100644
--- a/arch/x86/include/asm/bug.h
+++ b/arch/x86/include/asm/bug.h
@@ -30,33 +30,33 @@
 
 #ifdef CONFIG_DEBUG_BUGVERBOSE
 
-#define _BUG_FLAGS(ins, flags)						\
+#define _BUG_FLAGS(ins, flags, ...)					\
 do {									\
 	asm volatile("1:\t" ins "\n"					\
 		     ".pushsection __bug_table,\"aw\"\n"		\
-		     "2:\t" __BUG_REL(1b) "\t# bug_entry::bug_addr\n"	\
-		     "\t"  __BUG_REL(%c0) "\t# bug_entry::file\n"	\
-		     "\t.word %c1"        "\t# bug_entry::line\n"	\
-		     "\t.word %c2"        "\t# bug_entry::flags\n"	\
-		     "\t.org 2b+%c3\n"					\
+		     "2:\t" __BUG_REL(1b)      "\t# bug_entry::bug_addr\n" \
+		     "\t"  __BUG_REL(%c[file]) "\t# bug_entry::file\n"	\
+		     "\t.word %c[line]"        "\t# bug_entry::line\n"	\
+		     "\t.word %c[flags]"       "\t# bug_entry::flags\n"	\
+		     "\t.org 2b+%c[size]\n"				\
 		     ".popsection"					\
-		     : : "i" (__FILE__), "i" (__LINE__),		\
-			 "i" (flags),					\
-			 "i" (sizeof(struct bug_entry)));		\
+		     : : [file] "i" (__FILE__), [line] "i" (__LINE__),	\
+			 [flags] "i" (flags),				\
+			 [size] "i" (sizeof(struct bug_entry)), ##__VA_ARGS__);	\
 } while (0)
 
 #else /* !CONFIG_DEBUG_BUGVERBOSE */
 
-#define _BUG_FLAGS(ins, flags)						\
+#define _BUG_FLAGS(ins, flags, ...)					\
 do {									\
 	asm volatile("1:\t" ins "\n"					\
 		     ".pushsection __bug_table,\"aw\"\n"		\
 		     "2:\t" __BUG_REL(1b) "\t# bug_entry::bug_addr\n"	\
-		     "\t.word %c0"        "\t# bug_entry::flags\n"	\
-		     "\t.org 2b+%c1\n"					\
+		     "\t.word %c[flags]"  "\t# bug_entry::flags\n"	\
+		     "\t.org 2b+%c[size]\n"				\
 		     ".popsection"					\
-		     : : "i" (flags),					\
-			 "i" (sizeof(struct bug_entry)));		\
+		     : : [flags] "i" (flags),				\
+			 [size] "i" (sizeof(struct bug_entry)), ##__VA_ARGS__);	\
 } while (0)
 
 #endif /* CONFIG_DEBUG_BUGVERBOSE */
diff --git a/arch/x86/include/asm/kasan.h b/arch/x86/include/asm/kasan.h
index 13e70da38bed..b7d563965b4d 100644
--- a/arch/x86/include/asm/kasan.h
+++ b/arch/x86/include/asm/kasan.h
@@ -2,6 +2,8 @@
 #ifndef _ASM_X86_KASAN_H
 #define _ASM_X86_KASAN_H
 
+#include <asm/bug.h>
+
 #include <linux/const.h>
 #define KASAN_SHADOW_OFFSET _AC(CONFIG_KASAN_SHADOW_OFFSET, UL)
 #define KASAN_SHADOW_SCALE_SHIFT 3
@@ -26,8 +28,17 @@
 #ifndef __ASSEMBLY__
 
 #ifdef CONFIG_KASAN
+
 void __init kasan_early_init(void);
 void __init kasan_init(void);
+
+static __always_inline void kasan_report(unsigned long addr, size_t size, bool is_write, unsigned long ip)
+{
+	unsigned long rdi = addr, rsi = size, rdx = is_write, rdx = ip;
+
+	_BUG_FLAGS(ASM_UD2, BUGFLAG_KASAN, "D" (rdi), "S" (rsi), "d" (rdx), "c" (rcx));
+}
+
 #else
 static inline void kasan_early_init(void) { }
 static inline void kasan_init(void) { }
diff --git a/include/asm-generic/bug.h b/include/asm-generic/bug.h
index 0e9bd9c83870..6c829e80ea2a 100644
--- a/include/asm-generic/bug.h
+++ b/include/asm-generic/bug.h
@@ -10,6 +10,7 @@
 #define BUGFLAG_WARNING		(1 << 0)
 #define BUGFLAG_ONCE		(1 << 1)
 #define BUGFLAG_DONE		(1 << 2)
+#define BUGFLAG_KASAN		(1 << 3)
 #define BUGFLAG_TAINT(taint)	((taint) << 8)
 #define BUG_GET_TAINT(bug)	((bug)->flags >> 8)
 #endif
diff --git a/include/linux/kasan.h b/include/linux/kasan.h
index b40ea104dd36..0ab50faedc9e 100644
--- a/include/linux/kasan.h
+++ b/include/linux/kasan.h
@@ -177,7 +177,7 @@ void kasan_init_tags(void);
 
 void *kasan_reset_tag(const void *addr);
 
-void kasan_report(unsigned long addr, size_t size,
+void __kasan_report(unsigned long addr, size_t size,
 		bool is_write, unsigned long ip);
 
 #else /* CONFIG_KASAN_SW_TAGS */
@@ -191,4 +191,8 @@ static inline void *kasan_reset_tag(const void *addr)
 
 #endif /* CONFIG_KASAN_SW_TAGS */
 
+#ifndef kasan_report
+#define kasan_report(addr, size, is_write, ip) __kasan_report(addr, size, is_write, ip)
+#endif
+
 #endif /* LINUX_KASAN_H */
diff --git a/lib/bug.c b/lib/bug.c
index 1077366f496b..c9c005a35b76 100644
--- a/lib/bug.c
+++ b/lib/bug.c
@@ -144,7 +144,7 @@ enum bug_trap_type report_bug(unsigned long bugaddr, struct pt_regs *regs)
 {
 	struct bug_entry *bug;
 	const char *file;
-	unsigned line, warning, once, done;
+	unsigned line, warning, once, done, kasan;
 
 	if (!is_valid_bugaddr(bugaddr))
 		return BUG_TRAP_TYPE_NONE;
@@ -167,6 +167,7 @@ enum bug_trap_type report_bug(unsigned long bugaddr, struct pt_regs *regs)
 		line = bug->line;
 #endif
 		warning = (bug->flags & BUGFLAG_WARNING) != 0;
+		kasan = (bug->flags & BUGFLAG_KASAN) != 0;
 		once = (bug->flags & BUGFLAG_ONCE) != 0;
 		done = (bug->flags & BUGFLAG_DONE) != 0;
 
@@ -188,6 +189,11 @@ enum bug_trap_type report_bug(unsigned long bugaddr, struct pt_regs *regs)
 		return BUG_TRAP_TYPE_WARN;
 	}
 
+	if (kasan) {
+		__kasan_report(regs->di, regs->si, regs->dx, regs->cx);
+		return BUG_TRAP_TYPE_WARN;
+	}
+
 	printk(KERN_DEFAULT CUT_HERE);
 
 	if (file)
diff --git a/mm/kasan/generic.c b/mm/kasan/generic.c
index ccb6207276e3..84be578e2591 100644
--- a/mm/kasan/generic.c
+++ b/mm/kasan/generic.c
@@ -228,7 +228,7 @@ void __asan_unregister_globals(struct kasan_global *globals, size_t size)
 EXPORT_SYMBOL(__asan_unregister_globals);
 
 #define DEFINE_ASAN_LOAD_STORE(size)					\
-	void __asan_load##size(unsigned long addr)			\
+	notrace void __asan_load##size(unsigned long addr)		\
 	{								\
 		check_memory_region_inline(addr, size, false, _RET_IP_);\
 	}								\
@@ -236,7 +236,7 @@ EXPORT_SYMBOL(__asan_unregister_globals);
 	__alias(__asan_load##size)					\
 	void __asan_load##size##_noabort(unsigned long);		\
 	EXPORT_SYMBOL(__asan_load##size##_noabort);			\
-	void __asan_store##size(unsigned long addr)			\
+	notrace void __asan_store##size(unsigned long addr)		\
 	{								\
 		check_memory_region_inline(addr, size, true, _RET_IP_);	\
 	}								\
diff --git a/mm/kasan/kasan.h b/mm/kasan/kasan.h
index ea51b2d898ec..7bc954b4fc2d 100644
--- a/mm/kasan/kasan.h
+++ b/mm/kasan/kasan.h
@@ -130,7 +130,7 @@ void check_memory_region(unsigned long addr, size_t size, bool write,
 void *find_first_bad_addr(void *addr, size_t size);
 const char *get_bug_type(struct kasan_access_info *info);
 
-void kasan_report(unsigned long addr, size_t size,
+void __kasan_report(unsigned long addr, size_t size,
 		bool is_write, unsigned long ip);
 void kasan_report_invalid_free(void *object, unsigned long ip);
 
diff --git a/mm/kasan/report.c b/mm/kasan/report.c
index ca9418fe9232..1d5050659388 100644
--- a/mm/kasan/report.c
+++ b/mm/kasan/report.c
@@ -281,7 +281,7 @@ void kasan_report_invalid_free(void *object, unsigned long ip)
 	end_report(&flags);
 }
 
-void kasan_report(unsigned long addr, size_t size,
+void __kasan_report(unsigned long addr, size_t size,
 		bool is_write, unsigned long ip)
 {
 	struct kasan_access_info info;

  reply	other threads:[~2019-02-27 17:28 UTC|newest]

Thread overview: 44+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-02-25 12:43 [PATCH 0/6] objtool: UACCESS validation Peter Zijlstra
2019-02-25 12:43 ` [PATCH 1/6] x86/uaccess: Dont evaluate argument inside AC region Peter Zijlstra
2019-02-25 15:43   ` Andy Lutomirski
2019-02-25 16:02     ` Peter Zijlstra
2019-02-25 16:36     ` Borislav Petkov
2019-02-25 16:50       ` Andy Lutomirski
2019-02-25 19:09     ` Linus Torvalds
2019-02-25 19:18       ` Borislav Petkov
2019-02-25 18:10   ` [tip:x86/urgent] x86/uaccess: Don't leak the AC flag into __put_user() value evaluation tip-bot for Andy Lutomirski
2019-02-25 19:46   ` tip-bot for Andy Lutomirski
2019-02-25 12:43 ` [PATCH 2/6] x86/ia32: Fix ia32_restore_sigcontext AC leak Peter Zijlstra
2019-02-25 15:41   ` Andy Lutomirski
2019-02-25 16:10     ` Peter Zijlstra
2019-02-25 16:29       ` Andy Lutomirski
2019-02-25 16:37         ` Peter Zijlstra
2019-02-25 16:41           ` Peter Zijlstra
2019-02-25 16:49           ` Andy Lutomirski
2019-02-25 12:43 ` [PATCH 3/6] objtool: Set insn->func for alternatives Peter Zijlstra
2019-02-25 12:43 ` [PATCH 4/6] objtool: Replace STACK_FRAME_NON_STANDARD annotation Peter Zijlstra
2019-02-25 16:11   ` Josh Poimboeuf
2019-02-25 16:17     ` Peter Zijlstra
2019-02-25 16:23       ` Josh Poimboeuf
2019-02-27 12:20     ` Peter Zijlstra
2019-02-28  0:30       ` Andy Lutomirski
2019-02-25 12:43 ` [PATCH 5/6] objtool: Add UACCESS validation Peter Zijlstra
2019-02-25 15:53   ` Andy Lutomirski
2019-02-25 16:12     ` Peter Zijlstra
2019-02-25 17:15       ` Peter Zijlstra
2019-02-25 17:34         ` Linus Torvalds
2019-02-25 17:38         ` Josh Poimboeuf
2019-02-27 14:08   ` Peter Zijlstra
2019-02-27 14:17     ` Andrey Ryabinin
2019-02-27 14:26       ` Peter Zijlstra
2019-02-27 14:33         ` Peter Zijlstra
2019-02-27 15:40           ` Dmitry Vyukov
2019-02-27 17:28             ` Peter Zijlstra [this message]
2019-02-28  9:40               ` Peter Zijlstra
2019-02-28  9:59                 ` Dmitry Vyukov
2019-02-28 10:05                   ` Dmitry Vyukov
2019-02-28 10:52                     ` Peter Zijlstra
2019-02-27 16:18     ` Linus Torvalds
2019-02-27 17:30       ` Peter Zijlstra
2019-02-27 17:36         ` Linus Torvalds
2019-02-25 12:43 ` [PATCH 6/6] objtool: Add Direction Flag validation Peter Zijlstra

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190227172816.GT32494@hirez.programming.kicks-ass.net \
    --to=peterz@infradead.org \
    --cc=aryabinin@virtuozzo.com \
    --cc=bp@alien8.de \
    --cc=brgerst@gmail.com \
    --cc=catalin.marinas@arm.com \
    --cc=dvlasenk@redhat.com \
    --cc=dvyukov@google.com \
    --cc=glider@google.com \
    --cc=hpa@zytor.com \
    --cc=james.morse@arm.com \
    --cc=jpoimboe@redhat.com \
    --cc=julien.thierry@arm.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=luto@amacapital.net \
    --cc=luto@kernel.org \
    --cc=mingo@kernel.org \
    --cc=tglx@linutronix.de \
    --cc=torvalds@linux-foundation.org \
    --cc=valentin.schneider@arm.com \
    --cc=will.deacon@arm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.