Skip to content

Commit

Permalink
powerpc/bpf: Validate branch ranges
Browse files Browse the repository at this point in the history
upstream commit 3832ba4

Add checks to ensure that we never emit branch instructions with
truncated branch offsets.

Suggested-by: Michael Ellerman <mpe@ellerman.id.au>
Signed-off-by: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com>
Tested-by: Johan Almbladh <johan.almbladh@anyfinetworks.com>
Reviewed-by: Christophe Leroy <christophe.leroy@csgroup.eu>
Acked-by: Song Liu <songliubraving@fb.com>
Acked-by: Johan Almbladh <johan.almbladh@anyfinetworks.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/71d33a6b7603ec1013c9734dd8bdd4ff5e929142.1633464148.git.naveen.n.rao@linux.vnet.ibm.com
[drop ppc32 changes]
Signed-off-by: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
rnav authored and gregkh committed Nov 18, 2021
1 parent 51cf71d commit 951fb7b
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 8 deletions.
26 changes: 20 additions & 6 deletions arch/powerpc/net/bpf_jit.h
Expand Up @@ -12,6 +12,7 @@

#include <asm/types.h>
#include <asm/ppc-opcode.h>
#include <asm/code-patching.h>

#ifdef PPC64_ELF_ABI_v1
#define FUNCTION_DESCR_SIZE 24
Expand All @@ -24,13 +25,26 @@
#define EMIT(instr) PLANT_INSTR(image, ctx->idx, instr)

/* Long jump; (unconditional 'branch') */
#define PPC_JMP(dest) EMIT(PPC_INST_BRANCH | \
(((dest) - (ctx->idx * 4)) & 0x03fffffc))
#define PPC_JMP(dest) \
do { \
long offset = (long)(dest) - (ctx->idx * 4); \
if (!is_offset_in_branch_range(offset)) { \
pr_err_ratelimited("Branch offset 0x%lx (@%u) out of range\n", offset, ctx->idx); \
return -ERANGE; \
} \
EMIT(PPC_INST_BRANCH | (offset & 0x03fffffc)); \
} while (0)
/* "cond" here covers BO:BI fields. */
#define PPC_BCC_SHORT(cond, dest) EMIT(PPC_INST_BRANCH_COND | \
(((cond) & 0x3ff) << 16) | \
(((dest) - (ctx->idx * 4)) & \
0xfffc))
#define PPC_BCC_SHORT(cond, dest) \
do { \
long offset = (long)(dest) - (ctx->idx * 4); \
if (!is_offset_in_cond_branch_range(offset)) { \
pr_err_ratelimited("Conditional branch offset 0x%lx (@%u) out of range\n", offset, ctx->idx); \
return -ERANGE; \
} \
EMIT(PPC_INST_BRANCH_COND | (((cond) & 0x3ff) << 16) | (offset & 0xfffc)); \
} while (0)

/* Sign-extended 32-bit immediate load */
#define PPC_LI32(d, i) do { \
if ((int)(uintptr_t)(i) >= -32768 && \
Expand Down
8 changes: 6 additions & 2 deletions arch/powerpc/net/bpf_jit_comp64.c
Expand Up @@ -224,7 +224,7 @@ static void bpf_jit_emit_func_call_rel(u32 *image, struct codegen_context *ctx,
EMIT(PPC_RAW_BLRL());
}

static void bpf_jit_emit_tail_call(u32 *image, struct codegen_context *ctx, u32 out)
static int bpf_jit_emit_tail_call(u32 *image, struct codegen_context *ctx, u32 out)
{
/*
* By now, the eBPF program has already setup parameters in r3, r4 and r5
Expand Down Expand Up @@ -285,7 +285,9 @@ static void bpf_jit_emit_tail_call(u32 *image, struct codegen_context *ctx, u32
bpf_jit_emit_common_epilogue(image, ctx);

EMIT(PPC_RAW_BCTR());

/* out: */
return 0;
}

/* Assemble the body code between the prologue & epilogue */
Expand Down Expand Up @@ -1010,7 +1012,9 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image,
*/
case BPF_JMP | BPF_TAIL_CALL:
ctx->seen |= SEEN_TAILCALL;
bpf_jit_emit_tail_call(image, ctx, addrs[i + 1]);
ret = bpf_jit_emit_tail_call(image, ctx, addrs[i + 1]);
if (ret < 0)
return ret;
break;

default:
Expand Down

0 comments on commit 951fb7b

Please sign in to comment.