From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Google-Smtp-Source: AH8x225zrYeyAyTytd3A7Tjtti+ixmvdeYN/NgwTNgBjyQV4J9Bh/xjbeKHwBllPyXXiL3BepED6 ARC-Seal: i=1; a=rsa-sha256; t=1516924245; cv=none; d=google.com; s=arc-20160816; b=KE3zMg7/fOKG7uNUXn3T6eeaG6O1UKdw5ZfPPG6iLJPgwTA3xiPjo72JjnxICWaBNR XcYAUn06i/+iXLd13ZwhulMNoZOiHAMM5Fhf3d9ADe1aqRuydCMEXS95lhGwp8s++bac bNrsYkkfWD3oNK2NUXu7UqzND7rW/hBFvaz8nKySHMTPwoIlevaYPqGmPODFIQVXWbb/ o65U619Xym56ERbcjzGwnV5GSLNHv28Fzs7HqA2s33HhTcOLKKxTKmDaEiqvRxkTm2Qv gPltjHwxcJBn5fBj5Azkc9+DmOwLPf3ImxFLXVbGEtJLSEQf8kitVVwid/crYvYuNbmo izgA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=message-id:date:subject:cc:to:from:arc-authentication-results; bh=ZsRchnI+lLFzJmokUMn5dwp8TMKb8mYEkEseyfKdn6o=; b=pi8m+oqGgzu5mRerR2LmzpmIrwcRr6b8gcDmVF5cRmR8b2ZkQu0nWtvCwWHD0hy1dA efWBgsAj6ozuMdO6Vh2Kun4GOB50HUDfQzrSQwin6AZrAcNkhndjkKyEvJYkK4vONjjj SA/LKTl3ytbe+WNdnHRfCqHZ5/lEylS8GbsXn3xzc/Vn4wDtDeUHYCmcIMIgih5KyMRF 2tMwbMAo/Y+9Upi+XzKelyL3pwxi0xfKLrWLnJdWBMrm6tvMZZTa3kuDUBjBMzN1ciUT VODt+RshbAqHXAmYSeYh0585jGhU7EDBMgUp1hFXARO38/hGaEFqcLC38w4wp7dR1SyV TJCg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of ak@linux.intel.com designates 192.55.52.120 as permitted sender) smtp.mailfrom=ak@linux.intel.com Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of ak@linux.intel.com designates 192.55.52.120 as permitted sender) smtp.mailfrom=ak@linux.intel.com X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.46,414,1511856000"; d="scan'208";a="14341739" From: Andi Kleen To: tglx@linutronix.de Cc: gregkh@linuxfoundation.org, dwmw@amazon.co.uk, linux-kernel@vger.kernel.org, torvalds@linux-foundation.org, x86@kernel.org, arjan@linux.intel.com, Andi Kleen , jeyu@kernel.org Subject: [PATCH v4] retpoline/module: Warn for missing retpoline in module Date: Thu, 25 Jan 2018 15:50:28 -0800 Message-Id: <20180125235028.31211-1-andi@firstfloor.org> X-Mailer: git-send-email 2.14.3 X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: =?utf-8?q?1590610357649100474?= X-GMAIL-MSGID: =?utf-8?q?1590610357649100474?= X-Mailing-List: linux-kernel@vger.kernel.org List-ID: From: Andi Kleen There's a risk that a kernel that has full retpoline mitigations becomes vulnerable when a module gets loaded that hasn't been compiled with the right compiler or the right option. We cannot fix it, but should at least warn the user when that happens. When the a module hasn't been compiled with a retpoline aware compiler, print a warning and report it in the sysfs vulnerability files For modules it is checked at compile time, however it cannot check assembler or other non compiled objects used in the module link. v2: Change warning message v3: Port to latest tree v4: Remove tainting v5: Add changes from Thomas Gleixner, refactor checking, use a separate variable Cc: jeyu@kernel.org Signed-off-by: Andi Kleen Signed-off-by: David Woodhouse --- arch/x86/kernel/cpu/bugs.c | 18 +++++++++++++++++- include/linux/module.h | 9 +++++++++ kernel/module.c | 11 +++++++++++ scripts/mod/modpost.c | 9 +++++++++ 4 files changed, 46 insertions(+), 1 deletion(-) diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c index 390b3dc3d438..8766e13efe80 100644 --- a/arch/x86/kernel/cpu/bugs.c +++ b/arch/x86/kernel/cpu/bugs.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include @@ -94,6 +95,20 @@ static const char *spectre_v2_strings[] = { static enum spectre_v2_mitigation spectre_v2_enabled = SPECTRE_V2_NONE; +static bool spectre_v2_bad_module; + +#ifdef RETPOLINE +bool retpoline_module_ok(bool has_retpoline) +{ + if (spectre_v2_enabled == SPECTRE_V2_NONE || has_retpoline) + return true; + + pr_err("system may be vunerable to spectre_v2\n"); + spectre_v2_bad_module = true; + return false; +} +#endif + static void __init spec2_print_if_insecure(const char *reason) { if (boot_cpu_has_bug(X86_BUG_SPECTRE_V2)) @@ -278,6 +293,7 @@ ssize_t cpu_show_spectre_v2(struct device *dev, if (!boot_cpu_has_bug(X86_BUG_SPECTRE_V2)) return sprintf(buf, "Not affected\n"); - return sprintf(buf, "%s\n", spectre_v2_strings[spectre_v2_enabled]); + return sprintf(buf, "%s%s\n", spectre_v2_strings[spectre_v2_enabled], + spectre_v2_bad_module ? " but vulnerable module loaded" : ""); } #endif diff --git a/include/linux/module.h b/include/linux/module.h index fe5aa3736707..b1cc541f2ddf 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -794,6 +794,15 @@ static inline void module_bug_finalize(const Elf_Ehdr *hdr, static inline void module_bug_cleanup(struct module *mod) {} #endif /* CONFIG_GENERIC_BUG */ +#ifdef RETPOLINE +extern bool retpoline_module_ok(bool has_retpoline); +#else +static inline bool retpoline_module_ok(bool has_retpoline) +{ + return true; +} +#endif + #ifdef CONFIG_MODULE_SIG static inline bool module_sig_ok(struct module *module) { diff --git a/kernel/module.c b/kernel/module.c index de66ec825992..3c6e2d9231d3 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -2855,6 +2855,15 @@ static int check_modinfo_livepatch(struct module *mod, struct load_info *info) } #endif /* CONFIG_LIVEPATCH */ +static void check_modinfo_retpoline(struct module *mod, struct load_info *info) +{ + if (retpoline_module_ok(get_modinfo(info, "retpoline"))) + return; + + pr_warn("%s: loading module not compiled with retpoline compiler.\n", + mod->name); +} + /* Sets info->hdr and info->len. */ static int copy_module_from_user(const void __user *umod, unsigned long len, struct load_info *info) @@ -3021,6 +3030,8 @@ static int check_modinfo(struct module *mod, struct load_info *info, int flags) add_taint_module(mod, TAINT_OOT_MODULE, LOCKDEP_STILL_OK); } + check_modinfo_retpoline(mod, info); + 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/scripts/mod/modpost.c b/scripts/mod/modpost.c index 98314b400a95..54deaa1066cf 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(&buf, mod); add_intree_flag(&buf, !external_module); + add_retpoline(&buf); add_staging_flag(&buf, mod->name); err |= add_versions(&buf, mod); add_depends(&buf, mod, modules); -- 2.14.3