lkml.org 
[lkml]   [2022]   [Mar]   [10]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.10 05/58] x86/speculation: Include unprivileged eBPF status in Spectre v2 mitigation reporting
    Date
    From: Josh Poimboeuf <jpoimboe@redhat.com>

    commit 44a3918c8245ab10c6c9719dd12e7a8d291980d8 upstream.

    With unprivileged eBPF enabled, eIBRS (without retpoline) is vulnerable
    to Spectre v2 BHB-based attacks.

    When both are enabled, print a warning message and report it in the
    'spectre_v2' sysfs vulnerabilities file.

    Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
    Signed-off-by: Borislav Petkov <bp@suse.de>
    Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
    [fllinden@amazon.com: backported to 5.10]
    Signed-off-by: Frank van der Linden <fllinden@amazon.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    ---
    arch/x86/kernel/cpu/bugs.c | 35 +++++++++++++++++++++++++++++------
    include/linux/bpf.h | 12 ++++++++++++
    kernel/sysctl.c | 7 +++++++
    3 files changed, 48 insertions(+), 6 deletions(-)

    --- a/arch/x86/kernel/cpu/bugs.c
    +++ b/arch/x86/kernel/cpu/bugs.c
    @@ -16,6 +16,7 @@
    #include <linux/prctl.h>
    #include <linux/sched/smt.h>
    #include <linux/pgtable.h>
    +#include <linux/bpf.h>

    #include <asm/spec-ctrl.h>
    #include <asm/cmdline.h>
    @@ -613,6 +614,16 @@ static inline const char *spectre_v2_mod
    static inline const char *spectre_v2_module_string(void) { return ""; }
    #endif

    +#define SPECTRE_V2_EIBRS_EBPF_MSG "WARNING: Unprivileged eBPF is enabled with eIBRS on, data leaks possible via Spectre v2 BHB attacks!\n"
    +
    +#ifdef CONFIG_BPF_SYSCALL
    +void unpriv_ebpf_notify(int new_state)
    +{
    + if (spectre_v2_enabled == SPECTRE_V2_EIBRS && !new_state)
    + pr_err(SPECTRE_V2_EIBRS_EBPF_MSG);
    +}
    +#endif
    +
    static inline bool match_option(const char *arg, int arglen, const char *opt)
    {
    int len = strlen(opt);
    @@ -957,6 +968,9 @@ static void __init spectre_v2_select_mit
    break;
    }

    + if (mode == SPECTRE_V2_EIBRS && unprivileged_ebpf_enabled())
    + pr_err(SPECTRE_V2_EIBRS_EBPF_MSG);
    +
    if (spectre_v2_in_eibrs_mode(mode)) {
    /* Force it so VMEXIT will restore correctly */
    x86_spec_ctrl_base |= SPEC_CTRL_IBRS;
    @@ -1710,6 +1724,20 @@ static char *ibpb_state(void)
    return "";
    }

    +static ssize_t spectre_v2_show_state(char *buf)
    +{
    + if (spectre_v2_enabled == SPECTRE_V2_EIBRS && unprivileged_ebpf_enabled())
    + return sprintf(buf, "Vulnerable: Unprivileged eBPF enabled\n");
    +
    + return sprintf(buf, "%s%s%s%s%s%s\n",
    + spectre_v2_strings[spectre_v2_enabled],
    + ibpb_state(),
    + boot_cpu_has(X86_FEATURE_USE_IBRS_FW) ? ", IBRS_FW" : "",
    + stibp_state(),
    + boot_cpu_has(X86_FEATURE_RSB_CTXSW) ? ", RSB filling" : "",
    + spectre_v2_module_string());
    +}
    +
    static ssize_t srbds_show_state(char *buf)
    {
    return sprintf(buf, "%s\n", srbds_strings[srbds_mitigation]);
    @@ -1735,12 +1763,7 @@ static ssize_t cpu_show_common(struct de
    return sprintf(buf, "%s\n", spectre_v1_strings[spectre_v1_mitigation]);

    case X86_BUG_SPECTRE_V2:
    - return sprintf(buf, "%s%s%s%s%s%s\n", spectre_v2_strings[spectre_v2_enabled],
    - ibpb_state(),
    - boot_cpu_has(X86_FEATURE_USE_IBRS_FW) ? ", IBRS_FW" : "",
    - stibp_state(),
    - boot_cpu_has(X86_FEATURE_RSB_CTXSW) ? ", RSB filling" : "",
    - spectre_v2_module_string());
    + return spectre_v2_show_state(buf);

    case X86_BUG_SPEC_STORE_BYPASS:
    return sprintf(buf, "%s\n", ssb_strings[ssb_mode]);
    --- a/include/linux/bpf.h
    +++ b/include/linux/bpf.h
    @@ -1485,6 +1485,12 @@ struct bpf_prog *bpf_prog_by_id(u32 id);
    struct bpf_link *bpf_link_by_id(u32 id);

    const struct bpf_func_proto *bpf_base_func_proto(enum bpf_func_id func_id);
    +
    +static inline bool unprivileged_ebpf_enabled(void)
    +{
    + return !sysctl_unprivileged_bpf_disabled;
    +}
    +
    #else /* !CONFIG_BPF_SYSCALL */
    static inline struct bpf_prog *bpf_prog_get(u32 ufd)
    {
    @@ -1679,6 +1685,12 @@ bpf_base_func_proto(enum bpf_func_id fun
    {
    return NULL;
    }
    +
    +static inline bool unprivileged_ebpf_enabled(void)
    +{
    + return false;
    +}
    +
    #endif /* CONFIG_BPF_SYSCALL */

    static inline struct bpf_prog *bpf_prog_get_type(u32 ufd,
    --- a/kernel/sysctl.c
    +++ b/kernel/sysctl.c
    @@ -234,6 +234,10 @@ static int bpf_stats_handler(struct ctl_
    return ret;
    }

    +void __weak unpriv_ebpf_notify(int new_state)
    +{
    +}
    +
    static int bpf_unpriv_handler(struct ctl_table *table, int write,
    void *buffer, size_t *lenp, loff_t *ppos)
    {
    @@ -251,6 +255,9 @@ static int bpf_unpriv_handler(struct ctl
    return -EPERM;
    *(int *)table->data = unpriv_enable;
    }
    +
    + unpriv_ebpf_notify(unpriv_enable);
    +
    return ret;
    }
    #endif /* CONFIG_BPF_SYSCALL && CONFIG_SYSCTL */

    \
     
     \ /
      Last update: 2022-03-10 15:35    [W:7.400 / U:0.004 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site