summaryrefslogtreecommitdiffstats
path: root/kernel/bpf
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-05-21 14:23:26 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2018-05-21 14:23:26 -0400
commit3b78ce4a34b761c7fe13520de822984019ff1a8f (patch)
tree63b93664a184c2d561a70c7f8d16a388750739f7 /kernel/bpf
parent6741c4bb389da103c0d79ad1961884628900bfe6 (diff)
parentaf86ca4e3088fe5eacf2f7e58c01fa68ca067672 (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.c59
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 */
979static int check_stack_write(struct bpf_verifier_env *env, 979static 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