Skip to content

Commit

Permalink
Merge branch 'bpf-ppc-div-fix'
Browse files Browse the repository at this point in the history
Naveen N. Rao says:

====================
The first patch updates DIV64 overflow tests to properly detect error
conditions. The second patch fixes powerpc64 JIT to generate the proper
unsigned division instruction for BPF_ALU64.
====================

Acked-by: Sandipan Das <[email protected]>
Signed-off-by: Daniel Borkmann <[email protected]>
  • Loading branch information
borkmann committed Jun 13, 2019
2 parents 0e26574 + 758f204 commit 09f6ac2
Show file tree
Hide file tree
Showing 4 changed files with 16 additions and 9 deletions.
1 change: 1 addition & 0 deletions arch/powerpc/include/asm/ppc-opcode.h
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,7 @@
#define PPC_INST_MADDLD 0x10000033
#define PPC_INST_DIVWU 0x7c000396
#define PPC_INST_DIVD 0x7c0003d2
#define PPC_INST_DIVDU 0x7c000392
#define PPC_INST_RLWINM 0x54000000
#define PPC_INST_RLWINM_DOT 0x54000001
#define PPC_INST_RLWIMI 0x50000000
Expand Down
2 changes: 1 addition & 1 deletion arch/powerpc/net/bpf_jit.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@
___PPC_RA(a) | IMM_L(i))
#define PPC_DIVWU(d, a, b) EMIT(PPC_INST_DIVWU | ___PPC_RT(d) | \
___PPC_RA(a) | ___PPC_RB(b))
#define PPC_DIVD(d, a, b) EMIT(PPC_INST_DIVD | ___PPC_RT(d) | \
#define PPC_DIVDU(d, a, b) EMIT(PPC_INST_DIVDU | ___PPC_RT(d) | \
___PPC_RA(a) | ___PPC_RB(b))
#define PPC_AND(d, a, b) EMIT(PPC_INST_AND | ___PPC_RA(d) | \
___PPC_RS(a) | ___PPC_RB(b))
Expand Down
8 changes: 4 additions & 4 deletions arch/powerpc/net/bpf_jit_comp64.c
Original file line number Diff line number Diff line change
Expand Up @@ -399,12 +399,12 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image,
case BPF_ALU64 | BPF_DIV | BPF_X: /* dst /= src */
case BPF_ALU64 | BPF_MOD | BPF_X: /* dst %= src */
if (BPF_OP(code) == BPF_MOD) {
PPC_DIVD(b2p[TMP_REG_1], dst_reg, src_reg);
PPC_DIVDU(b2p[TMP_REG_1], dst_reg, src_reg);
PPC_MULD(b2p[TMP_REG_1], src_reg,
b2p[TMP_REG_1]);
PPC_SUB(dst_reg, dst_reg, b2p[TMP_REG_1]);
} else
PPC_DIVD(dst_reg, dst_reg, src_reg);
PPC_DIVDU(dst_reg, dst_reg, src_reg);
break;
case BPF_ALU | BPF_MOD | BPF_K: /* (u32) dst %= (u32) imm */
case BPF_ALU | BPF_DIV | BPF_K: /* (u32) dst /= (u32) imm */
Expand Down Expand Up @@ -432,15 +432,15 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image,
break;
case BPF_ALU64:
if (BPF_OP(code) == BPF_MOD) {
PPC_DIVD(b2p[TMP_REG_2], dst_reg,
PPC_DIVDU(b2p[TMP_REG_2], dst_reg,
b2p[TMP_REG_1]);
PPC_MULD(b2p[TMP_REG_1],
b2p[TMP_REG_1],
b2p[TMP_REG_2]);
PPC_SUB(dst_reg, dst_reg,
b2p[TMP_REG_1]);
} else
PPC_DIVD(dst_reg, dst_reg,
PPC_DIVDU(dst_reg, dst_reg,
b2p[TMP_REG_1]);
break;
}
Expand Down
14 changes: 10 additions & 4 deletions tools/testing/selftests/bpf/verifier/div_overflow.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,11 @@
"DIV64 overflow, check 1",
.insns = {
BPF_MOV64_IMM(BPF_REG_1, -1),
BPF_LD_IMM64(BPF_REG_0, LLONG_MIN),
BPF_ALU64_REG(BPF_DIV, BPF_REG_0, BPF_REG_1),
BPF_LD_IMM64(BPF_REG_2, LLONG_MIN),
BPF_ALU64_REG(BPF_DIV, BPF_REG_2, BPF_REG_1),
BPF_MOV32_IMM(BPF_REG_0, 0),
BPF_JMP_REG(BPF_JEQ, BPF_REG_0, BPF_REG_2, 1),
BPF_MOV32_IMM(BPF_REG_0, 1),
BPF_EXIT_INSN(),
},
.prog_type = BPF_PROG_TYPE_SCHED_CLS,
Expand All @@ -40,8 +43,11 @@
{
"DIV64 overflow, check 2",
.insns = {
BPF_LD_IMM64(BPF_REG_0, LLONG_MIN),
BPF_ALU64_IMM(BPF_DIV, BPF_REG_0, -1),
BPF_LD_IMM64(BPF_REG_1, LLONG_MIN),
BPF_ALU64_IMM(BPF_DIV, BPF_REG_1, -1),
BPF_MOV32_IMM(BPF_REG_0, 0),
BPF_JMP_REG(BPF_JEQ, BPF_REG_0, BPF_REG_1, 1),
BPF_MOV32_IMM(BPF_REG_0, 1),
BPF_EXIT_INSN(),
},
.prog_type = BPF_PROG_TYPE_SCHED_CLS,
Expand Down

0 comments on commit 09f6ac2

Please sign in to comment.