Skip to content

Commit fc16a53

Browse files
committed
Merge git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf
Daniel Borkmann says: ==================== pull-request: bpf 2021-07-29 The following pull-request contains BPF updates for your *net* tree. We've added 9 non-merge commits during the last 14 day(s) which contain a total of 20 files changed, 446 insertions(+), 138 deletions(-). The main changes are: 1) Fix UBSAN out-of-bounds splat for showing XDP link fdinfo, from Lorenz Bauer. 2) Fix insufficient Spectre v4 mitigation in BPF runtime, from Daniel Borkmann, Piotr Krysiuk and Benedict Schlueter. 3) Batch of fixes for BPF sockmap found under stress testing, from John Fastabend. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents 89fb62f + 2039f26 commit fc16a53

File tree

20 files changed

+446
-138
lines changed

20 files changed

+446
-138
lines changed

arch/arm/net/bpf_jit_32.c

+3
Original file line numberDiff line numberDiff line change
@@ -1602,6 +1602,9 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx)
16021602
rn = arm_bpf_get_reg32(src_lo, tmp2[1], ctx);
16031603
emit_ldx_r(dst, rn, off, ctx, BPF_SIZE(code));
16041604
break;
1605+
/* speculation barrier */
1606+
case BPF_ST | BPF_NOSPEC:
1607+
break;
16051608
/* ST: *(size *)(dst + off) = imm */
16061609
case BPF_ST | BPF_MEM | BPF_W:
16071610
case BPF_ST | BPF_MEM | BPF_H:

arch/arm64/net/bpf_jit_comp.c

+13
Original file line numberDiff line numberDiff line change
@@ -823,6 +823,19 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx,
823823
return ret;
824824
break;
825825

826+
/* speculation barrier */
827+
case BPF_ST | BPF_NOSPEC:
828+
/*
829+
* Nothing required here.
830+
*
831+
* In case of arm64, we rely on the firmware mitigation of
832+
* Speculative Store Bypass as controlled via the ssbd kernel
833+
* parameter. Whenever the mitigation is enabled, it works
834+
* for all of the kernel code with no need to provide any
835+
* additional instructions.
836+
*/
837+
break;
838+
826839
/* ST: *(size *)(dst + off) = imm */
827840
case BPF_ST | BPF_MEM | BPF_W:
828841
case BPF_ST | BPF_MEM | BPF_H:

arch/mips/net/ebpf_jit.c

+3
Original file line numberDiff line numberDiff line change
@@ -1355,6 +1355,9 @@ static int build_one_insn(const struct bpf_insn *insn, struct jit_ctx *ctx,
13551355
}
13561356
break;
13571357

1358+
case BPF_ST | BPF_NOSPEC: /* speculation barrier */
1359+
break;
1360+
13581361
case BPF_ST | BPF_B | BPF_MEM:
13591362
case BPF_ST | BPF_H | BPF_MEM:
13601363
case BPF_ST | BPF_W | BPF_MEM:

arch/powerpc/net/bpf_jit_comp32.c

+6
Original file line numberDiff line numberDiff line change
@@ -737,6 +737,12 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, struct codegen_context *
737737
}
738738
break;
739739

740+
/*
741+
* BPF_ST NOSPEC (speculation barrier)
742+
*/
743+
case BPF_ST | BPF_NOSPEC:
744+
break;
745+
740746
/*
741747
* BPF_ST(X)
742748
*/

arch/powerpc/net/bpf_jit_comp64.c

+6
Original file line numberDiff line numberDiff line change
@@ -627,6 +627,12 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, struct codegen_context *
627627
}
628628
break;
629629

630+
/*
631+
* BPF_ST NOSPEC (speculation barrier)
632+
*/
633+
case BPF_ST | BPF_NOSPEC:
634+
break;
635+
630636
/*
631637
* BPF_ST(X)
632638
*/

arch/riscv/net/bpf_jit_comp32.c

+4
Original file line numberDiff line numberDiff line change
@@ -1251,6 +1251,10 @@ int bpf_jit_emit_insn(const struct bpf_insn *insn, struct rv_jit_context *ctx,
12511251
return -1;
12521252
break;
12531253

1254+
/* speculation barrier */
1255+
case BPF_ST | BPF_NOSPEC:
1256+
break;
1257+
12541258
case BPF_ST | BPF_MEM | BPF_B:
12551259
case BPF_ST | BPF_MEM | BPF_H:
12561260
case BPF_ST | BPF_MEM | BPF_W:

arch/riscv/net/bpf_jit_comp64.c

+4
Original file line numberDiff line numberDiff line change
@@ -939,6 +939,10 @@ int bpf_jit_emit_insn(const struct bpf_insn *insn, struct rv_jit_context *ctx,
939939
emit_ld(rd, 0, RV_REG_T1, ctx);
940940
break;
941941

942+
/* speculation barrier */
943+
case BPF_ST | BPF_NOSPEC:
944+
break;
945+
942946
/* ST: *(size *)(dst + off) = imm */
943947
case BPF_ST | BPF_MEM | BPF_B:
944948
emit_imm(RV_REG_T1, imm, ctx);

arch/s390/net/bpf_jit_comp.c

+5
Original file line numberDiff line numberDiff line change
@@ -1153,6 +1153,11 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp,
11531153
break;
11541154
}
11551155
break;
1156+
/*
1157+
* BPF_NOSPEC (speculation barrier)
1158+
*/
1159+
case BPF_ST | BPF_NOSPEC:
1160+
break;
11561161
/*
11571162
* BPF_ST(X)
11581163
*/

arch/sparc/net/bpf_jit_comp_64.c

+3
Original file line numberDiff line numberDiff line change
@@ -1287,6 +1287,9 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx)
12871287
return 1;
12881288
break;
12891289
}
1290+
/* speculation barrier */
1291+
case BPF_ST | BPF_NOSPEC:
1292+
break;
12901293
/* ST: *(size *)(dst + off) = imm */
12911294
case BPF_ST | BPF_MEM | BPF_W:
12921295
case BPF_ST | BPF_MEM | BPF_H:

arch/x86/net/bpf_jit_comp.c

+7
Original file line numberDiff line numberDiff line change
@@ -1219,6 +1219,13 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image,
12191219
}
12201220
break;
12211221

1222+
/* speculation barrier */
1223+
case BPF_ST | BPF_NOSPEC:
1224+
if (boot_cpu_has(X86_FEATURE_XMM2))
1225+
/* Emit 'lfence' */
1226+
EMIT3(0x0F, 0xAE, 0xE8);
1227+
break;
1228+
12221229
/* ST: *(u8*)(dst_reg + off) = imm */
12231230
case BPF_ST | BPF_MEM | BPF_B:
12241231
if (is_ereg(dst_reg))

arch/x86/net/bpf_jit_comp32.c

+6
Original file line numberDiff line numberDiff line change
@@ -1886,6 +1886,12 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image,
18861886
i++;
18871887
break;
18881888
}
1889+
/* speculation barrier */
1890+
case BPF_ST | BPF_NOSPEC:
1891+
if (boot_cpu_has(X86_FEATURE_XMM2))
1892+
/* Emit 'lfence' */
1893+
EMIT3(0x0F, 0xAE, 0xE8);
1894+
break;
18891895
/* ST: *(u8*)(dst_reg + off) = imm */
18901896
case BPF_ST | BPF_MEM | BPF_H:
18911897
case BPF_ST | BPF_MEM | BPF_B:

include/linux/bpf_types.h

+1
Original file line numberDiff line numberDiff line change
@@ -134,4 +134,5 @@ BPF_LINK_TYPE(BPF_LINK_TYPE_CGROUP, cgroup)
134134
BPF_LINK_TYPE(BPF_LINK_TYPE_ITER, iter)
135135
#ifdef CONFIG_NET
136136
BPF_LINK_TYPE(BPF_LINK_TYPE_NETNS, netns)
137+
BPF_LINK_TYPE(BPF_LINK_TYPE_XDP, xdp)
137138
#endif

include/linux/bpf_verifier.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -340,8 +340,8 @@ struct bpf_insn_aux_data {
340340
};
341341
u64 map_key_state; /* constant (32 bit) key tracking for maps */
342342
int ctx_field_size; /* the ctx field size for load insn, maybe 0 */
343-
int sanitize_stack_off; /* stack slot to be cleared */
344343
u32 seen; /* this insn was processed by the verifier at env->pass_cnt */
344+
bool sanitize_stack_spill; /* subject to Spectre v4 sanitation */
345345
bool zext_dst; /* this insn zero extends dst reg */
346346
u8 alu_state; /* used in combination with alu_limit */
347347

@@ -414,6 +414,7 @@ struct bpf_verifier_env {
414414
u32 used_map_cnt; /* number of used maps */
415415
u32 used_btf_cnt; /* number of used BTF objects */
416416
u32 id_gen; /* used to generate unique reg IDs */
417+
bool explore_alu_limits;
417418
bool allow_ptr_leaks;
418419
bool allow_uninit_stack;
419420
bool allow_ptr_to_map_access;

include/linux/filter.h

+15
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,11 @@ struct ctl_table_header;
7373
/* unused opcode to mark call to interpreter with arguments */
7474
#define BPF_CALL_ARGS 0xe0
7575

76+
/* unused opcode to mark speculation barrier for mitigating
77+
* Speculative Store Bypass
78+
*/
79+
#define BPF_NOSPEC 0xc0
80+
7681
/* As per nm, we expose JITed images as text (code) section for
7782
* kallsyms. That way, tools like perf can find it to match
7883
* addresses.
@@ -390,6 +395,16 @@ static inline bool insn_is_zext(const struct bpf_insn *insn)
390395
.off = 0, \
391396
.imm = 0 })
392397

398+
/* Speculation barrier */
399+
400+
#define BPF_ST_NOSPEC() \
401+
((struct bpf_insn) { \
402+
.code = BPF_ST | BPF_NOSPEC, \
403+
.dst_reg = 0, \
404+
.src_reg = 0, \
405+
.off = 0, \
406+
.imm = 0 })
407+
393408
/* Internal classic blocks for direct assignment */
394409

395410
#define __BPF_STMT(CODE, K) \

include/linux/skmsg.h

+35-19
Original file line numberDiff line numberDiff line change
@@ -285,11 +285,45 @@ static inline struct sk_psock *sk_psock(const struct sock *sk)
285285
return rcu_dereference_sk_user_data(sk);
286286
}
287287

288+
static inline void sk_psock_set_state(struct sk_psock *psock,
289+
enum sk_psock_state_bits bit)
290+
{
291+
set_bit(bit, &psock->state);
292+
}
293+
294+
static inline void sk_psock_clear_state(struct sk_psock *psock,
295+
enum sk_psock_state_bits bit)
296+
{
297+
clear_bit(bit, &psock->state);
298+
}
299+
300+
static inline bool sk_psock_test_state(const struct sk_psock *psock,
301+
enum sk_psock_state_bits bit)
302+
{
303+
return test_bit(bit, &psock->state);
304+
}
305+
306+
static inline void sock_drop(struct sock *sk, struct sk_buff *skb)
307+
{
308+
sk_drops_add(sk, skb);
309+
kfree_skb(skb);
310+
}
311+
312+
static inline void drop_sk_msg(struct sk_psock *psock, struct sk_msg *msg)
313+
{
314+
if (msg->skb)
315+
sock_drop(psock->sk, msg->skb);
316+
kfree(msg);
317+
}
318+
288319
static inline void sk_psock_queue_msg(struct sk_psock *psock,
289320
struct sk_msg *msg)
290321
{
291322
spin_lock_bh(&psock->ingress_lock);
292-
list_add_tail(&msg->list, &psock->ingress_msg);
323+
if (sk_psock_test_state(psock, SK_PSOCK_TX_ENABLED))
324+
list_add_tail(&msg->list, &psock->ingress_msg);
325+
else
326+
drop_sk_msg(psock, msg);
293327
spin_unlock_bh(&psock->ingress_lock);
294328
}
295329

@@ -406,24 +440,6 @@ static inline void sk_psock_restore_proto(struct sock *sk,
406440
psock->psock_update_sk_prot(sk, psock, true);
407441
}
408442

409-
static inline void sk_psock_set_state(struct sk_psock *psock,
410-
enum sk_psock_state_bits bit)
411-
{
412-
set_bit(bit, &psock->state);
413-
}
414-
415-
static inline void sk_psock_clear_state(struct sk_psock *psock,
416-
enum sk_psock_state_bits bit)
417-
{
418-
clear_bit(bit, &psock->state);
419-
}
420-
421-
static inline bool sk_psock_test_state(const struct sk_psock *psock,
422-
enum sk_psock_state_bits bit)
423-
{
424-
return test_bit(bit, &psock->state);
425-
}
426-
427443
static inline struct sk_psock *sk_psock_get(struct sock *sk)
428444
{
429445
struct sk_psock *psock;

kernel/bpf/core.c

+18-1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@
3232
#include <linux/perf_event.h>
3333
#include <linux/extable.h>
3434
#include <linux/log2.h>
35+
36+
#include <asm/barrier.h>
3537
#include <asm/unaligned.h>
3638

3739
/* Registers */
@@ -1377,6 +1379,7 @@ static u64 ___bpf_prog_run(u64 *regs, const struct bpf_insn *insn)
13771379
/* Non-UAPI available opcodes. */
13781380
[BPF_JMP | BPF_CALL_ARGS] = &&JMP_CALL_ARGS,
13791381
[BPF_JMP | BPF_TAIL_CALL] = &&JMP_TAIL_CALL,
1382+
[BPF_ST | BPF_NOSPEC] = &&ST_NOSPEC,
13801383
[BPF_LDX | BPF_PROBE_MEM | BPF_B] = &&LDX_PROBE_MEM_B,
13811384
[BPF_LDX | BPF_PROBE_MEM | BPF_H] = &&LDX_PROBE_MEM_H,
13821385
[BPF_LDX | BPF_PROBE_MEM | BPF_W] = &&LDX_PROBE_MEM_W,
@@ -1621,7 +1624,21 @@ static u64 ___bpf_prog_run(u64 *regs, const struct bpf_insn *insn)
16211624
COND_JMP(s, JSGE, >=)
16221625
COND_JMP(s, JSLE, <=)
16231626
#undef COND_JMP
1624-
/* STX and ST and LDX*/
1627+
/* ST, STX and LDX*/
1628+
ST_NOSPEC:
1629+
/* Speculation barrier for mitigating Speculative Store Bypass.
1630+
* In case of arm64, we rely on the firmware mitigation as
1631+
* controlled via the ssbd kernel parameter. Whenever the
1632+
* mitigation is enabled, it works for all of the kernel code
1633+
* with no need to provide any additional instructions here.
1634+
* In case of x86, we use 'lfence' insn for mitigation. We
1635+
* reuse preexisting logic from Spectre v1 mitigation that
1636+
* happens to produce the required code on x86 for v4 as well.
1637+
*/
1638+
#ifdef CONFIG_X86
1639+
barrier_nospec();
1640+
#endif
1641+
CONT;
16251642
#define LDST(SIZEOP, SIZE) \
16261643
STX_MEM_##SIZEOP: \
16271644
*(SIZE *)(unsigned long) (DST + insn->off) = SRC; \

kernel/bpf/disasm.c

+9-7
Original file line numberDiff line numberDiff line change
@@ -206,15 +206,17 @@ void print_bpf_insn(const struct bpf_insn_cbs *cbs,
206206
verbose(cbs->private_data, "BUG_%02x\n", insn->code);
207207
}
208208
} else if (class == BPF_ST) {
209-
if (BPF_MODE(insn->code) != BPF_MEM) {
209+
if (BPF_MODE(insn->code) == BPF_MEM) {
210+
verbose(cbs->private_data, "(%02x) *(%s *)(r%d %+d) = %d\n",
211+
insn->code,
212+
bpf_ldst_string[BPF_SIZE(insn->code) >> 3],
213+
insn->dst_reg,
214+
insn->off, insn->imm);
215+
} else if (BPF_MODE(insn->code) == 0xc0 /* BPF_NOSPEC, no UAPI */) {
216+
verbose(cbs->private_data, "(%02x) nospec\n", insn->code);
217+
} else {
210218
verbose(cbs->private_data, "BUG_st_%02x\n", insn->code);
211-
return;
212219
}
213-
verbose(cbs->private_data, "(%02x) *(%s *)(r%d %+d) = %d\n",
214-
insn->code,
215-
bpf_ldst_string[BPF_SIZE(insn->code) >> 3],
216-
insn->dst_reg,
217-
insn->off, insn->imm);
218220
} else if (class == BPF_LDX) {
219221
if (BPF_MODE(insn->code) != BPF_MEM) {
220222
verbose(cbs->private_data, "BUG_ldx_%02x\n", insn->code);

0 commit comments

Comments
 (0)