Skip to content

Commit a5f7b0e

Browse files
committed
Merge git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf
Daniel Borkmann says: ==================== pull-request: bpf 2018-02-28 The following pull-request contains BPF updates for your *net* tree. The main changes are: 1) Add schedule points and reduce the number of loop iterations the test_bpf kernel module is performing in order to not hog the CPU for too long, from Eric. 2) Fix an out of bounds access in tail calls in the ppc64 BPF JIT compiler, from Daniel. 3) Fix a crash on arm64 on unaligned BPF xadd operations that could be triggered via interpreter and JIT, from Daniel. Please not that once you merge net into net-next at some point, there is a minor merge conflict in test_verifier.c since test cases had been added at the end in both trees. Resolution is trivial: keep all the test cases from both trees. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
2 parents a6d5051 + 9960d76 commit a5f7b0e

File tree

4 files changed

+88
-17
lines changed

4 files changed

+88
-17
lines changed

arch/powerpc/net/bpf_jit_comp64.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,7 @@ static void bpf_jit_emit_tail_call(u32 *image, struct codegen_context *ctx, u32
240240
* goto out;
241241
*/
242242
PPC_LWZ(b2p[TMP_REG_1], b2p_bpf_array, offsetof(struct bpf_array, map.max_entries));
243+
PPC_RLWINM(b2p_index, b2p_index, 0, 0, 31);
243244
PPC_CMPLW(b2p_index, b2p[TMP_REG_1]);
244245
PPC_BCC(COND_GE, out);
245246

kernel/bpf/verifier.c

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1356,6 +1356,13 @@ static bool is_ctx_reg(struct bpf_verifier_env *env, int regno)
13561356
return reg->type == PTR_TO_CTX;
13571357
}
13581358

1359+
static bool is_pkt_reg(struct bpf_verifier_env *env, int regno)
1360+
{
1361+
const struct bpf_reg_state *reg = cur_regs(env) + regno;
1362+
1363+
return type_is_pkt_pointer(reg->type);
1364+
}
1365+
13591366
static int check_pkt_ptr_alignment(struct bpf_verifier_env *env,
13601367
const struct bpf_reg_state *reg,
13611368
int off, int size, bool strict)
@@ -1416,10 +1423,10 @@ static int check_generic_ptr_alignment(struct bpf_verifier_env *env,
14161423
}
14171424

14181425
static int check_ptr_alignment(struct bpf_verifier_env *env,
1419-
const struct bpf_reg_state *reg,
1420-
int off, int size)
1426+
const struct bpf_reg_state *reg, int off,
1427+
int size, bool strict_alignment_once)
14211428
{
1422-
bool strict = env->strict_alignment;
1429+
bool strict = env->strict_alignment || strict_alignment_once;
14231430
const char *pointer_desc = "";
14241431

14251432
switch (reg->type) {
@@ -1576,9 +1583,9 @@ static void coerce_reg_to_size(struct bpf_reg_state *reg, int size)
15761583
* if t==write && value_regno==-1, some unknown value is stored into memory
15771584
* if t==read && value_regno==-1, don't care what we read from memory
15781585
*/
1579-
static int check_mem_access(struct bpf_verifier_env *env, int insn_idx, u32 regno, int off,
1580-
int bpf_size, enum bpf_access_type t,
1581-
int value_regno)
1586+
static int check_mem_access(struct bpf_verifier_env *env, int insn_idx, u32 regno,
1587+
int off, int bpf_size, enum bpf_access_type t,
1588+
int value_regno, bool strict_alignment_once)
15821589
{
15831590
struct bpf_reg_state *regs = cur_regs(env);
15841591
struct bpf_reg_state *reg = regs + regno;
@@ -1590,7 +1597,7 @@ static int check_mem_access(struct bpf_verifier_env *env, int insn_idx, u32 regn
15901597
return size;
15911598

15921599
/* alignment checks will add in reg->off themselves */
1593-
err = check_ptr_alignment(env, reg, off, size);
1600+
err = check_ptr_alignment(env, reg, off, size, strict_alignment_once);
15941601
if (err)
15951602
return err;
15961603

@@ -1735,21 +1742,23 @@ static int check_xadd(struct bpf_verifier_env *env, int insn_idx, struct bpf_ins
17351742
return -EACCES;
17361743
}
17371744

1738-
if (is_ctx_reg(env, insn->dst_reg)) {
1739-
verbose(env, "BPF_XADD stores into R%d context is not allowed\n",
1740-
insn->dst_reg);
1745+
if (is_ctx_reg(env, insn->dst_reg) ||
1746+
is_pkt_reg(env, insn->dst_reg)) {
1747+
verbose(env, "BPF_XADD stores into R%d %s is not allowed\n",
1748+
insn->dst_reg, is_ctx_reg(env, insn->dst_reg) ?
1749+
"context" : "packet");
17411750
return -EACCES;
17421751
}
17431752

17441753
/* check whether atomic_add can read the memory */
17451754
err = check_mem_access(env, insn_idx, insn->dst_reg, insn->off,
1746-
BPF_SIZE(insn->code), BPF_READ, -1);
1755+
BPF_SIZE(insn->code), BPF_READ, -1, true);
17471756
if (err)
17481757
return err;
17491758

17501759
/* check whether atomic_add can write into the same memory */
17511760
return check_mem_access(env, insn_idx, insn->dst_reg, insn->off,
1752-
BPF_SIZE(insn->code), BPF_WRITE, -1);
1761+
BPF_SIZE(insn->code), BPF_WRITE, -1, true);
17531762
}
17541763

17551764
/* when register 'regno' is passed into function that will read 'access_size'
@@ -2388,7 +2397,8 @@ static int check_helper_call(struct bpf_verifier_env *env, int func_id, int insn
23882397
* is inferred from register state.
23892398
*/
23902399
for (i = 0; i < meta.access_size; i++) {
2391-
err = check_mem_access(env, insn_idx, meta.regno, i, BPF_B, BPF_WRITE, -1);
2400+
err = check_mem_access(env, insn_idx, meta.regno, i, BPF_B,
2401+
BPF_WRITE, -1, false);
23922402
if (err)
23932403
return err;
23942404
}
@@ -4632,7 +4642,7 @@ static int do_check(struct bpf_verifier_env *env)
46324642
*/
46334643
err = check_mem_access(env, insn_idx, insn->src_reg, insn->off,
46344644
BPF_SIZE(insn->code), BPF_READ,
4635-
insn->dst_reg);
4645+
insn->dst_reg, false);
46364646
if (err)
46374647
return err;
46384648

@@ -4684,7 +4694,7 @@ static int do_check(struct bpf_verifier_env *env)
46844694
/* check that memory (dst_reg + off) is writeable */
46854695
err = check_mem_access(env, insn_idx, insn->dst_reg, insn->off,
46864696
BPF_SIZE(insn->code), BPF_WRITE,
4687-
insn->src_reg);
4697+
insn->src_reg, false);
46884698
if (err)
46894699
return err;
46904700

@@ -4719,7 +4729,7 @@ static int do_check(struct bpf_verifier_env *env)
47194729
/* check that memory (dst_reg + off) is writeable */
47204730
err = check_mem_access(env, insn_idx, insn->dst_reg, insn->off,
47214731
BPF_SIZE(insn->code), BPF_WRITE,
4722-
-1);
4732+
-1, false);
47234733
if (err)
47244734
return err;
47254735

lib/test_bpf.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,11 @@
2424
#include <linux/if_vlan.h>
2525
#include <linux/random.h>
2626
#include <linux/highmem.h>
27+
#include <linux/sched.h>
2728

2829
/* General test specific settings */
2930
#define MAX_SUBTESTS 3
30-
#define MAX_TESTRUNS 10000
31+
#define MAX_TESTRUNS 1000
3132
#define MAX_DATA 128
3233
#define MAX_INSNS 512
3334
#define MAX_K 0xffffFFFF
@@ -6582,6 +6583,7 @@ static __init int test_bpf(void)
65826583
struct bpf_prog *fp;
65836584
int err;
65846585

6586+
cond_resched();
65856587
if (exclude_test(i))
65866588
continue;
65876589

tools/testing/selftests/bpf/test_verifier.c

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11163,6 +11163,64 @@ static struct bpf_test tests[] = {
1116311163
.result = REJECT,
1116411164
.prog_type = BPF_PROG_TYPE_TRACEPOINT,
1116511165
},
11166+
{
11167+
"xadd/w check unaligned stack",
11168+
.insns = {
11169+
BPF_MOV64_IMM(BPF_REG_0, 1),
11170+
BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
11171+
BPF_STX_XADD(BPF_W, BPF_REG_10, BPF_REG_0, -7),
11172+
BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8),
11173+
BPF_EXIT_INSN(),
11174+
},
11175+
.result = REJECT,
11176+
.errstr = "misaligned stack access off",
11177+
.prog_type = BPF_PROG_TYPE_SCHED_CLS,
11178+
},
11179+
{
11180+
"xadd/w check unaligned map",
11181+
.insns = {
11182+
BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
11183+
BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
11184+
BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
11185+
BPF_LD_MAP_FD(BPF_REG_1, 0),
11186+
BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
11187+
BPF_FUNC_map_lookup_elem),
11188+
BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
11189+
BPF_EXIT_INSN(),
11190+
BPF_MOV64_IMM(BPF_REG_1, 1),
11191+
BPF_STX_XADD(BPF_W, BPF_REG_0, BPF_REG_1, 3),
11192+
BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0, 3),
11193+
BPF_EXIT_INSN(),
11194+
},
11195+
.fixup_map1 = { 3 },
11196+
.result = REJECT,
11197+
.errstr = "misaligned value access off",
11198+
.prog_type = BPF_PROG_TYPE_SCHED_CLS,
11199+
},
11200+
{
11201+
"xadd/w check unaligned pkt",
11202+
.insns = {
11203+
BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
11204+
offsetof(struct xdp_md, data)),
11205+
BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
11206+
offsetof(struct xdp_md, data_end)),
11207+
BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
11208+
BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
11209+
BPF_JMP_REG(BPF_JLT, BPF_REG_1, BPF_REG_3, 2),
11210+
BPF_MOV64_IMM(BPF_REG_0, 99),
11211+
BPF_JMP_IMM(BPF_JA, 0, 0, 6),
11212+
BPF_MOV64_IMM(BPF_REG_0, 1),
11213+
BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
11214+
BPF_ST_MEM(BPF_W, BPF_REG_2, 3, 0),
11215+
BPF_STX_XADD(BPF_W, BPF_REG_2, BPF_REG_0, 1),
11216+
BPF_STX_XADD(BPF_W, BPF_REG_2, BPF_REG_0, 2),
11217+
BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_2, 1),
11218+
BPF_EXIT_INSN(),
11219+
},
11220+
.result = REJECT,
11221+
.errstr = "BPF_XADD stores into R2 packet",
11222+
.prog_type = BPF_PROG_TYPE_XDP,
11223+
},
1116611224
};
1116711225

1116811226
static int probe_filter_length(const struct bpf_insn *fp)

0 commit comments

Comments
 (0)