Commit 6b8cc1d1 authored by Daniel Borkmann's avatar Daniel Borkmann Committed by David S. Miller

bpf: pass original insn directly to convert_ctx_access

Currently, when calling convert_ctx_access() callback for the various
program types, we pass in insn->dst_reg, insn->src_reg, insn->off from
the original instruction. This information is needed to rewrite the
instruction that is based on the user ctx structure into a kernel
representation for the ctx. As we'd like to allow access size beyond
just BPF_W, we'd need also insn->code for that in order to decode the
original access size. Given that, lets just pass insn directly to the
convert_ctx_access() callback and work on that to not clutter the
callback with even more arguments we need to pass when everything is
already contained in insn. So lets go through that once, no functional
change.
Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
Acked-by: default avatarAlexei Starovoitov <ast@kernel.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent f811b436
...@@ -161,9 +161,10 @@ struct bpf_verifier_ops { ...@@ -161,9 +161,10 @@ struct bpf_verifier_ops {
enum bpf_reg_type *reg_type); enum bpf_reg_type *reg_type);
int (*gen_prologue)(struct bpf_insn *insn, bool direct_write, int (*gen_prologue)(struct bpf_insn *insn, bool direct_write,
const struct bpf_prog *prog); const struct bpf_prog *prog);
u32 (*convert_ctx_access)(enum bpf_access_type type, int dst_reg, u32 (*convert_ctx_access)(enum bpf_access_type type,
int src_reg, int ctx_off, const struct bpf_insn *src,
struct bpf_insn *insn, struct bpf_prog *prog); struct bpf_insn *dst,
struct bpf_prog *prog);
}; };
struct bpf_prog_type_list { struct bpf_prog_type_list {
......
...@@ -3177,8 +3177,7 @@ static int convert_ctx_accesses(struct bpf_verifier_env *env) ...@@ -3177,8 +3177,7 @@ static int convert_ctx_accesses(struct bpf_verifier_env *env)
if (env->insn_aux_data[i].ptr_type != PTR_TO_CTX) if (env->insn_aux_data[i].ptr_type != PTR_TO_CTX)
continue; continue;
cnt = ops->convert_ctx_access(type, insn->dst_reg, insn->src_reg, cnt = ops->convert_ctx_access(type, insn, insn_buf, env->prog);
insn->off, insn_buf, env->prog);
if (cnt == 0 || cnt >= ARRAY_SIZE(insn_buf)) { if (cnt == 0 || cnt >= ARRAY_SIZE(insn_buf)) {
verbose("bpf verifier is misconfigured\n"); verbose("bpf verifier is misconfigured\n");
return -EINVAL; return -EINVAL;
......
...@@ -572,28 +572,29 @@ static bool pe_prog_is_valid_access(int off, int size, enum bpf_access_type type ...@@ -572,28 +572,29 @@ static bool pe_prog_is_valid_access(int off, int size, enum bpf_access_type type
return true; return true;
} }
static u32 pe_prog_convert_ctx_access(enum bpf_access_type type, int dst_reg, static u32 pe_prog_convert_ctx_access(enum bpf_access_type type,
int src_reg, int ctx_off, const struct bpf_insn *si,
struct bpf_insn *insn_buf, struct bpf_insn *insn_buf,
struct bpf_prog *prog) struct bpf_prog *prog)
{ {
struct bpf_insn *insn = insn_buf; struct bpf_insn *insn = insn_buf;
switch (ctx_off) { switch (si->off) {
case offsetof(struct bpf_perf_event_data, sample_period): case offsetof(struct bpf_perf_event_data, sample_period):
BUILD_BUG_ON(FIELD_SIZEOF(struct perf_sample_data, period) != sizeof(u64)); BUILD_BUG_ON(FIELD_SIZEOF(struct perf_sample_data, period) != sizeof(u64));
*insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(struct bpf_perf_event_data_kern, *insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(struct bpf_perf_event_data_kern,
data), dst_reg, src_reg, data), si->dst_reg, si->src_reg,
offsetof(struct bpf_perf_event_data_kern, data)); offsetof(struct bpf_perf_event_data_kern, data));
*insn++ = BPF_LDX_MEM(BPF_DW, dst_reg, dst_reg, *insn++ = BPF_LDX_MEM(BPF_DW, si->dst_reg, si->dst_reg,
offsetof(struct perf_sample_data, period)); offsetof(struct perf_sample_data, period));
break; break;
default: default:
*insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(struct bpf_perf_event_data_kern, *insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(struct bpf_perf_event_data_kern,
regs), dst_reg, src_reg, regs), si->dst_reg, si->src_reg,
offsetof(struct bpf_perf_event_data_kern, regs)); offsetof(struct bpf_perf_event_data_kern, regs));
*insn++ = BPF_LDX_MEM(BPF_SIZEOF(long), dst_reg, dst_reg, ctx_off); *insn++ = BPF_LDX_MEM(BPF_SIZEOF(long), si->dst_reg, si->dst_reg,
si->off);
break; break;
} }
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment