diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-05-21 14:23:26 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-05-21 14:23:26 -0400 |
commit | 3b78ce4a34b761c7fe13520de822984019ff1a8f (patch) | |
tree | 63b93664a184c2d561a70c7f8d16a388750739f7 /kernel/bpf | |
parent | 6741c4bb389da103c0d79ad1961884628900bfe6 (diff) | |
parent | af86ca4e3088fe5eacf2f7e58c01fa68ca067672 (diff) |
Merge branch 'speck-v20' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Merge speculative store buffer bypass fixes from Thomas Gleixner:
- rework of the SPEC_CTRL MSR management to accomodate the new fancy
SSBD (Speculative Store Bypass Disable) bit handling.
- the CPU bug and sysfs infrastructure for the exciting new Speculative
Store Bypass 'feature'.
- support for disabling SSB via LS_CFG MSR on AMD CPUs including
Hyperthread synchronization on ZEN.
- PRCTL support for dynamic runtime control of SSB
- SECCOMP integration to automatically disable SSB for sandboxed
processes with a filter flag for opt-out.
- KVM integration to allow guests fiddling with SSBD including the new
software MSR VIRT_SPEC_CTRL to handle the LS_CFG based oddities on
AMD.
- BPF protection against SSB
.. this is just the core and x86 side, other architecture support will
come separately.
* 'speck-v20' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (49 commits)
bpf: Prevent memory disambiguation attack
x86/bugs: Rename SSBD_NO to SSB_NO
KVM: SVM: Implement VIRT_SPEC_CTRL support for SSBD
x86/speculation, KVM: Implement support for VIRT_SPEC_CTRL/LS_CFG
x86/bugs: Rework spec_ctrl base and mask logic
x86/bugs: Remove x86_spec_ctrl_set()
x86/bugs: Expose x86_spec_ctrl_base directly
x86/bugs: Unify x86_spec_ctrl_{set_guest,restore_host}
x86/speculation: Rework speculative_store_bypass_update()
x86/speculation: Add virtualized speculative store bypass disable support
x86/bugs, KVM: Extend speculation control for VIRT_SPEC_CTRL
x86/speculation: Handle HT correctly on AMD
x86/cpufeatures: Add FEATURE_ZEN
x86/cpufeatures: Disentangle SSBD enumeration
x86/cpufeatures: Disentangle MSR_SPEC_CTRL enumeration from IBRS
x86/speculation: Use synthetic bits for IBRS/IBPB/STIBP
KVM: SVM: Move spec control call after restore of GS
x86/cpu: Make alternative_msr_write work for 32-bit code
x86/bugs: Fix the parameters alignment and missing void
x86/bugs: Make cpu_show_common() static
...
Diffstat (limited to 'kernel/bpf')
-rw-r--r-- | kernel/bpf/verifier.c | 59 |
1 files changed, 56 insertions, 3 deletions
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index 5dd1dcb902bf..2ce967a63ede 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c | |||
@@ -978,7 +978,7 @@ static bool register_is_null(struct bpf_reg_state *reg) | |||
978 | */ | 978 | */ |
979 | static int check_stack_write(struct bpf_verifier_env *env, | 979 | static int check_stack_write(struct bpf_verifier_env *env, |
980 | struct bpf_func_state *state, /* func where register points to */ | 980 | struct bpf_func_state *state, /* func where register points to */ |
981 | int off, int size, int value_regno) | 981 | int off, int size, int value_regno, int insn_idx) |
982 | { | 982 | { |
983 | struct bpf_func_state *cur; /* state of the current function */ | 983 | struct bpf_func_state *cur; /* state of the current function */ |
984 | int i, slot = -off - 1, spi = slot / BPF_REG_SIZE, err; | 984 | int i, slot = -off - 1, spi = slot / BPF_REG_SIZE, err; |
@@ -1017,8 +1017,33 @@ static int check_stack_write(struct bpf_verifier_env *env, | |||
1017 | state->stack[spi].spilled_ptr = cur->regs[value_regno]; | 1017 | state->stack[spi].spilled_ptr = cur->regs[value_regno]; |
1018 | state->stack[spi].spilled_ptr.live |= REG_LIVE_WRITTEN; | 1018 | state->stack[spi].spilled_ptr.live |= REG_LIVE_WRITTEN; |
1019 | 1019 | ||
1020 | for (i = 0; i < BPF_REG_SIZE; i++) | 1020 | for (i = 0; i < BPF_REG_SIZE; i++) { |
1021 | if (state->stack[spi].slot_type[i] == STACK_MISC && | ||
1022 | !env->allow_ptr_leaks) { | ||
1023 | int *poff = &env->insn_aux_data[insn_idx].sanitize_stack_off; | ||
1024 | int soff = (-spi - 1) * BPF_REG_SIZE; | ||
1025 | |||
1026 | /* detected reuse of integer stack slot with a pointer | ||
1027 | * which means either llvm is reusing stack slot or | ||
1028 | * an attacker is trying to exploit CVE-2018-3639 | ||
1029 | * (speculative store bypass) | ||
1030 | * Have to sanitize that slot with preemptive | ||
1031 | * store of zero. | ||
1032 | */ | ||
1033 | if (*poff && *poff != soff) { | ||
1034 | /* disallow programs where single insn stores | ||
1035 | * into two different stack slots, since verifier | ||
1036 | * cannot sanitize them | ||
1037 | */ | ||
1038 | verbose(env, | ||
1039 | "insn %d cannot access two stack slots fp%d and fp%d", | ||
1040 | insn_idx, *poff, soff); | ||
1041 | return -EINVAL; | ||
1042 | } | ||
1043 | *poff = soff; | ||
1044 | } | ||
1021 | state->stack[spi].slot_type[i] = STACK_SPILL; | 1045 | state->stack[spi].slot_type[i] = STACK_SPILL; |
1046 | } | ||
1022 | } else { | 1047 | } else { |
1023 | u8 type = STACK_MISC; | 1048 | u8 type = STACK_MISC; |
1024 | 1049 | ||
@@ -1694,7 +1719,7 @@ static int check_mem_access(struct bpf_verifier_env *env, int insn_idx, u32 regn | |||
1694 | 1719 | ||
1695 | if (t == BPF_WRITE) | 1720 | if (t == BPF_WRITE) |
1696 | err = check_stack_write(env, state, off, size, | 1721 | err = check_stack_write(env, state, off, size, |
1697 | value_regno); | 1722 | value_regno, insn_idx); |
1698 | else | 1723 | else |
1699 | err = check_stack_read(env, state, off, size, | 1724 | err = check_stack_read(env, state, off, size, |
1700 | value_regno); | 1725 | value_regno); |
@@ -5169,6 +5194,34 @@ static int convert_ctx_accesses(struct bpf_verifier_env *env) | |||
5169 | else | 5194 | else |
5170 | continue; | 5195 | continue; |
5171 | 5196 | ||
5197 | if (type == BPF_WRITE && | ||
5198 | env->insn_aux_data[i + delta].sanitize_stack_off) { | ||
5199 | struct bpf_insn patch[] = { | ||
5200 | /* Sanitize suspicious stack slot with zero. | ||
5201 | * There are no memory dependencies for this store, | ||
5202 | * since it's only using frame pointer and immediate | ||
5203 | * constant of zero | ||
5204 | */ | ||
5205 | BPF_ST_MEM(BPF_DW, BPF_REG_FP, | ||
5206 | env->insn_aux_data[i + delta].sanitize_stack_off, | ||
5207 | 0), | ||
5208 | /* the original STX instruction will immediately | ||
5209 | * overwrite the same stack slot with appropriate value | ||
5210 | */ | ||
5211 | *insn, | ||
5212 | }; | ||
5213 | |||
5214 | cnt = ARRAY_SIZE(patch); | ||
5215 | new_prog = bpf_patch_insn_data(env, i + delta, patch, cnt); | ||
5216 | if (!new_prog) | ||
5217 | return -ENOMEM; | ||
5218 | |||
5219 | delta += cnt - 1; | ||
5220 | env->prog = new_prog; | ||
5221 | insn = new_prog->insnsi + i + delta; | ||
5222 | continue; | ||
5223 | } | ||
5224 | |||
5172 | if (env->insn_aux_data[i + delta].ptr_type != PTR_TO_CTX) | 5225 | if (env->insn_aux_data[i + delta].ptr_type != PTR_TO_CTX) |
5173 | continue; | 5226 | continue; |
5174 | 5227 | ||