Re: [PATCH v3 11/13] retpoline/taint: Taint kernel for missing retpoline in compiler

2018-01-04 Thread Justin Forbes
On Thu, Jan 4, 2018 at 8:37 AM, David Woodhouse  wrote:
> From: Andi Kleen 
>
> When the kernel or a module hasn't been compiled with a retpoline
> aware compiler, print a warning and set a taint flag.
>
> For modules it is checked at compile time, however it cannot
> check assembler or other non compiled objects used in the module link.
>
> Due to lack of better letter it uses taint option 'Z'
>

Is taint really the right thing to do here? Why not just do pr_info?


Re: [PATCH v3 11/13] retpoline/taint: Taint kernel for missing retpoline in compiler

2018-01-04 Thread Justin Forbes
On Thu, Jan 4, 2018 at 8:37 AM, David Woodhouse  wrote:
> From: Andi Kleen 
>
> When the kernel or a module hasn't been compiled with a retpoline
> aware compiler, print a warning and set a taint flag.
>
> For modules it is checked at compile time, however it cannot
> check assembler or other non compiled objects used in the module link.
>
> Due to lack of better letter it uses taint option 'Z'
>

Is taint really the right thing to do here? Why not just do pr_info?


[PATCH v3 11/13] retpoline/taint: Taint kernel for missing retpoline in compiler

2018-01-04 Thread David Woodhouse
From: Andi Kleen 

When the kernel or a module hasn't been compiled with a retpoline
aware compiler, print a warning and set a taint flag.

For modules it is checked at compile time, however it cannot
check assembler or other non compiled objects used in the module link.

Due to lack of better letter it uses taint option 'Z'

v2: Change warning message
Signed-off-by: Andi Kleen 
Signed-off-by: David Woodhouse 
---
 Documentation/admin-guide/tainted-kernels.rst |  3 +++
 arch/x86/kernel/setup.c   |  6 ++
 include/linux/kernel.h|  4 +++-
 kernel/module.c   | 11 ++-
 kernel/panic.c|  1 +
 scripts/mod/modpost.c |  9 +
 6 files changed, 32 insertions(+), 2 deletions(-)

diff --git a/Documentation/admin-guide/tainted-kernels.rst 
b/Documentation/admin-guide/tainted-kernels.rst
index 1df03b5cb02f..800261b6bd6f 100644
--- a/Documentation/admin-guide/tainted-kernels.rst
+++ b/Documentation/admin-guide/tainted-kernels.rst
@@ -52,6 +52,9 @@ characters, each representing a particular tainted value.
 
  16) ``K`` if the kernel has been live patched.
 
+ 17) ``Z`` if the x86 kernel or a module hasn't been compiled with
+ a retpoline aware compiler and may be vulnerable to data leaks.
+
 The primary reason for the **'Tainted: '** string is to tell kernel
 debuggers if this is a clean kernel or if anything unusual has
 occurred.  Tainting is permanent: even if an offending module is
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index 8af2e8d0c0a1..cc880b46b756 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -1296,6 +1296,12 @@ void __init setup_arch(char **cmdline_p)
 #endif
 
unwind_init();
+
+#ifndef RETPOLINE
+   add_taint(TAINT_NO_RETPOLINE, LOCKDEP_STILL_OK);
+   pr_warn("No support for retpoline in kernel compiler\n");
+   pr_warn("System may be vulnerable to data leaks.\n");
+#endif
 }
 
 #ifdef CONFIG_X86_32
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index ce51455e2adf..fbb4d3baffcc 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -550,7 +550,9 @@ extern enum system_states {
 #define TAINT_SOFTLOCKUP   14
 #define TAINT_LIVEPATCH15
 #define TAINT_AUX  16
-#define TAINT_FLAGS_COUNT  17
+#define TAINT_NO_RETPOLINE 17
+
+#define TAINT_FLAGS_COUNT  18
 
 struct taint_flag {
char c_true;/* character printed when tainted */
diff --git a/kernel/module.c b/kernel/module.c
index dea01ac9cb74..92db3f59a29a 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -3028,7 +3028,16 @@ static int check_modinfo(struct module *mod, struct 
load_info *info, int flags)
mod->name);
add_taint_module(mod, TAINT_OOT_MODULE, LOCKDEP_STILL_OK);
}
-
+#ifdef RETPOLINE
+   if (!get_modinfo(info, "retpoline")) {
+   if (!test_taint(TAINT_NO_RETPOLINE)) {
+   pr_warn("%s: loading module not compiled with retpoline 
compiler.\n",
+   mod->name);
+   pr_warn("Kernel may be vulnerable to data leaks.\n");
+   }
+   add_taint_module(mod, TAINT_NO_RETPOLINE, LOCKDEP_STILL_OK);
+   }
+#endif
if (get_modinfo(info, "staging")) {
add_taint_module(mod, TAINT_CRAP, LOCKDEP_STILL_OK);
pr_warn("%s: module is from the staging directory, the quality "
diff --git a/kernel/panic.c b/kernel/panic.c
index 2cfef408fec9..6686c67b6e4b 100644
--- a/kernel/panic.c
+++ b/kernel/panic.c
@@ -325,6 +325,7 @@ const struct taint_flag taint_flags[TAINT_FLAGS_COUNT] = {
{ 'L', ' ', false },/* TAINT_SOFTLOCKUP */
{ 'K', ' ', true }, /* TAINT_LIVEPATCH */
{ 'X', ' ', true }, /* TAINT_AUX */
+   { 'Z', ' ', true }, /* TAINT_NO_RETPOLINE */
 };
 
 /**
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
index f51cf977c65b..6510536c06df 100644
--- a/scripts/mod/modpost.c
+++ b/scripts/mod/modpost.c
@@ -2165,6 +2165,14 @@ static void add_intree_flag(struct buffer *b, int 
is_intree)
buf_printf(b, "\nMODULE_INFO(intree, \"Y\");\n");
 }
 
+/* Cannot check for assembler */
+static void add_retpoline(struct buffer *b)
+{
+   buf_printf(b, "\n#ifdef RETPOLINE\n");
+   buf_printf(b, "MODULE_INFO(retpoline, \"Y\");\n");
+   buf_printf(b, "#endif\n");
+}
+
 static void add_staging_flag(struct buffer *b, const char *name)
 {
static const char *staging_dir = "drivers/staging";
@@ -2506,6 +2514,7 @@ int main(int argc, char **argv)
err |= check_modname_len(mod);
add_header(, mod);
add_intree_flag(, !external_module);
+   add_retpoline();
   

[PATCH v3 11/13] retpoline/taint: Taint kernel for missing retpoline in compiler

2018-01-04 Thread David Woodhouse
From: Andi Kleen 

When the kernel or a module hasn't been compiled with a retpoline
aware compiler, print a warning and set a taint flag.

For modules it is checked at compile time, however it cannot
check assembler or other non compiled objects used in the module link.

Due to lack of better letter it uses taint option 'Z'

v2: Change warning message
Signed-off-by: Andi Kleen 
Signed-off-by: David Woodhouse 
---
 Documentation/admin-guide/tainted-kernels.rst |  3 +++
 arch/x86/kernel/setup.c   |  6 ++
 include/linux/kernel.h|  4 +++-
 kernel/module.c   | 11 ++-
 kernel/panic.c|  1 +
 scripts/mod/modpost.c |  9 +
 6 files changed, 32 insertions(+), 2 deletions(-)

diff --git a/Documentation/admin-guide/tainted-kernels.rst 
b/Documentation/admin-guide/tainted-kernels.rst
index 1df03b5cb02f..800261b6bd6f 100644
--- a/Documentation/admin-guide/tainted-kernels.rst
+++ b/Documentation/admin-guide/tainted-kernels.rst
@@ -52,6 +52,9 @@ characters, each representing a particular tainted value.
 
  16) ``K`` if the kernel has been live patched.
 
+ 17) ``Z`` if the x86 kernel or a module hasn't been compiled with
+ a retpoline aware compiler and may be vulnerable to data leaks.
+
 The primary reason for the **'Tainted: '** string is to tell kernel
 debuggers if this is a clean kernel or if anything unusual has
 occurred.  Tainting is permanent: even if an offending module is
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index 8af2e8d0c0a1..cc880b46b756 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -1296,6 +1296,12 @@ void __init setup_arch(char **cmdline_p)
 #endif
 
unwind_init();
+
+#ifndef RETPOLINE
+   add_taint(TAINT_NO_RETPOLINE, LOCKDEP_STILL_OK);
+   pr_warn("No support for retpoline in kernel compiler\n");
+   pr_warn("System may be vulnerable to data leaks.\n");
+#endif
 }
 
 #ifdef CONFIG_X86_32
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index ce51455e2adf..fbb4d3baffcc 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -550,7 +550,9 @@ extern enum system_states {
 #define TAINT_SOFTLOCKUP   14
 #define TAINT_LIVEPATCH15
 #define TAINT_AUX  16
-#define TAINT_FLAGS_COUNT  17
+#define TAINT_NO_RETPOLINE 17
+
+#define TAINT_FLAGS_COUNT  18
 
 struct taint_flag {
char c_true;/* character printed when tainted */
diff --git a/kernel/module.c b/kernel/module.c
index dea01ac9cb74..92db3f59a29a 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -3028,7 +3028,16 @@ static int check_modinfo(struct module *mod, struct 
load_info *info, int flags)
mod->name);
add_taint_module(mod, TAINT_OOT_MODULE, LOCKDEP_STILL_OK);
}
-
+#ifdef RETPOLINE
+   if (!get_modinfo(info, "retpoline")) {
+   if (!test_taint(TAINT_NO_RETPOLINE)) {
+   pr_warn("%s: loading module not compiled with retpoline 
compiler.\n",
+   mod->name);
+   pr_warn("Kernel may be vulnerable to data leaks.\n");
+   }
+   add_taint_module(mod, TAINT_NO_RETPOLINE, LOCKDEP_STILL_OK);
+   }
+#endif
if (get_modinfo(info, "staging")) {
add_taint_module(mod, TAINT_CRAP, LOCKDEP_STILL_OK);
pr_warn("%s: module is from the staging directory, the quality "
diff --git a/kernel/panic.c b/kernel/panic.c
index 2cfef408fec9..6686c67b6e4b 100644
--- a/kernel/panic.c
+++ b/kernel/panic.c
@@ -325,6 +325,7 @@ const struct taint_flag taint_flags[TAINT_FLAGS_COUNT] = {
{ 'L', ' ', false },/* TAINT_SOFTLOCKUP */
{ 'K', ' ', true }, /* TAINT_LIVEPATCH */
{ 'X', ' ', true }, /* TAINT_AUX */
+   { 'Z', ' ', true }, /* TAINT_NO_RETPOLINE */
 };
 
 /**
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
index f51cf977c65b..6510536c06df 100644
--- a/scripts/mod/modpost.c
+++ b/scripts/mod/modpost.c
@@ -2165,6 +2165,14 @@ static void add_intree_flag(struct buffer *b, int 
is_intree)
buf_printf(b, "\nMODULE_INFO(intree, \"Y\");\n");
 }
 
+/* Cannot check for assembler */
+static void add_retpoline(struct buffer *b)
+{
+   buf_printf(b, "\n#ifdef RETPOLINE\n");
+   buf_printf(b, "MODULE_INFO(retpoline, \"Y\");\n");
+   buf_printf(b, "#endif\n");
+}
+
 static void add_staging_flag(struct buffer *b, const char *name)
 {
static const char *staging_dir = "drivers/staging";
@@ -2506,6 +2514,7 @@ int main(int argc, char **argv)
err |= check_modname_len(mod);
add_header(, mod);
add_intree_flag(, !external_module);
+   add_retpoline();
add_staging_flag(, mod->name);