[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <1562275611-31790-6-git-send-email-jiong.wang@netronome.com>
Date: Thu, 4 Jul 2019 22:26:48 +0100
From: Jiong Wang <jiong.wang@...ronome.com>
To: alexei.starovoitov@...il.com, daniel@...earbox.net
Cc: ecree@...arflare.com, naveen.n.rao@...ux.vnet.ibm.com,
andriin@...com, jakub.kicinski@...ronome.com, bpf@...r.kernel.org,
netdev@...r.kernel.org, oss-drivers@...ronome.com,
Jiong Wang <jiong.wang@...ronome.com>
Subject: [RFC bpf-next 5/8] bpf: migrate fixup_bpf_calls to list patching infra
This patch migrate fixup_bpf_calls to new list patching
infrastructure.
Signed-off-by: Jiong Wang <jiong.wang@...ronome.com>
---
kernel/bpf/verifier.c | 94 +++++++++++++++++++++++++++------------------------
1 file changed, 49 insertions(+), 45 deletions(-)
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 2d16e85..30ed28e 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -9033,16 +9033,19 @@ static int fixup_bpf_calls(struct bpf_verifier_env *env)
{
struct bpf_prog *prog = env->prog;
struct bpf_insn *insn = prog->insnsi;
+ struct bpf_list_insn *list, *elem;
const struct bpf_func_proto *fn;
- const int insn_cnt = prog->len;
const struct bpf_map_ops *ops;
struct bpf_insn_aux_data *aux;
struct bpf_insn insn_buf[16];
- struct bpf_prog *new_prog;
struct bpf_map *map_ptr;
- int i, cnt, delta = 0;
+ int cnt, ret = 0;
- for (i = 0; i < insn_cnt; i++, insn++) {
+ list = bpf_create_list_insn(env->prog);
+ if (IS_ERR(list))
+ return PTR_ERR(list);
+ for (elem = list; elem; elem = elem->next) {
+ insn = &elem->insn;
if (insn->code == (BPF_ALU64 | BPF_MOD | BPF_X) ||
insn->code == (BPF_ALU64 | BPF_DIV | BPF_X) ||
insn->code == (BPF_ALU | BPF_MOD | BPF_X) ||
@@ -9073,13 +9076,11 @@ static int fixup_bpf_calls(struct bpf_verifier_env *env)
cnt = ARRAY_SIZE(mask_and_mod) - (is64 ? 1 : 0);
}
- new_prog = bpf_patch_insn_data(env, i + delta, patchlet, cnt);
- if (!new_prog)
- return -ENOMEM;
-
- delta += cnt - 1;
- env->prog = prog = new_prog;
- insn = new_prog->insnsi + i + delta;
+ elem = bpf_patch_list_insn(elem, patchlet, cnt);
+ if (IS_ERR(elem)) {
+ ret = PTR_ERR(elem);
+ goto free_list_ret;
+ }
continue;
}
@@ -9089,16 +9090,15 @@ static int fixup_bpf_calls(struct bpf_verifier_env *env)
cnt = env->ops->gen_ld_abs(insn, insn_buf);
if (cnt == 0 || cnt >= ARRAY_SIZE(insn_buf)) {
verbose(env, "bpf verifier is misconfigured\n");
- return -EINVAL;
+ ret = -EINVAL;
+ goto free_list_ret;
}
- new_prog = bpf_patch_insn_data(env, i + delta, insn_buf, cnt);
- if (!new_prog)
- return -ENOMEM;
-
- delta += cnt - 1;
- env->prog = prog = new_prog;
- insn = new_prog->insnsi + i + delta;
+ elem = bpf_patch_list_insn(elem, insn_buf, cnt);
+ if (IS_ERR(elem)) {
+ ret = PTR_ERR(elem);
+ goto free_list_ret;
+ }
continue;
}
@@ -9111,7 +9111,7 @@ static int fixup_bpf_calls(struct bpf_verifier_env *env)
bool issrc, isneg;
u32 off_reg;
- aux = &env->insn_aux_data[i + delta];
+ aux = &env->insn_aux_data[elem->orig_idx - 1];
if (!aux->alu_state ||
aux->alu_state == BPF_ALU_NON_POINTER)
continue;
@@ -9144,13 +9144,12 @@ static int fixup_bpf_calls(struct bpf_verifier_env *env)
*patch++ = BPF_ALU64_IMM(BPF_MUL, off_reg, -1);
cnt = patch - insn_buf;
- new_prog = bpf_patch_insn_data(env, i + delta, insn_buf, cnt);
- if (!new_prog)
- return -ENOMEM;
+ elem = bpf_patch_list_insn(elem, insn_buf, cnt);
+ if (IS_ERR(elem)) {
+ ret = PTR_ERR(elem);
+ goto free_list_ret;
+ }
- delta += cnt - 1;
- env->prog = prog = new_prog;
- insn = new_prog->insnsi + i + delta;
continue;
}
@@ -9183,7 +9182,7 @@ static int fixup_bpf_calls(struct bpf_verifier_env *env)
insn->imm = 0;
insn->code = BPF_JMP | BPF_TAIL_CALL;
- aux = &env->insn_aux_data[i + delta];
+ aux = &env->insn_aux_data[elem->orig_idx - 1];
if (!bpf_map_ptr_unpriv(aux))
continue;
@@ -9195,7 +9194,8 @@ static int fixup_bpf_calls(struct bpf_verifier_env *env)
*/
if (bpf_map_ptr_poisoned(aux)) {
verbose(env, "tail_call abusing map_ptr\n");
- return -EINVAL;
+ ret = -EINVAL;
+ goto free_list_ret;
}
map_ptr = BPF_MAP_PTR(aux->map_state);
@@ -9207,13 +9207,12 @@ static int fixup_bpf_calls(struct bpf_verifier_env *env)
map)->index_mask);
insn_buf[2] = *insn;
cnt = 3;
- new_prog = bpf_patch_insn_data(env, i + delta, insn_buf, cnt);
- if (!new_prog)
- return -ENOMEM;
+ elem = bpf_patch_list_insn(elem, insn_buf, cnt);
+ if (IS_ERR(elem)) {
+ ret = PTR_ERR(elem);
+ goto free_list_ret;
+ }
- delta += cnt - 1;
- env->prog = prog = new_prog;
- insn = new_prog->insnsi + i + delta;
continue;
}
@@ -9228,7 +9227,7 @@ static int fixup_bpf_calls(struct bpf_verifier_env *env)
insn->imm == BPF_FUNC_map_push_elem ||
insn->imm == BPF_FUNC_map_pop_elem ||
insn->imm == BPF_FUNC_map_peek_elem)) {
- aux = &env->insn_aux_data[i + delta];
+ aux = &env->insn_aux_data[elem->orig_idx - 1];
if (bpf_map_ptr_poisoned(aux))
goto patch_call_imm;
@@ -9239,17 +9238,16 @@ static int fixup_bpf_calls(struct bpf_verifier_env *env)
cnt = ops->map_gen_lookup(map_ptr, insn_buf);
if (cnt == 0 || cnt >= ARRAY_SIZE(insn_buf)) {
verbose(env, "bpf verifier is misconfigured\n");
- return -EINVAL;
+ ret = -EINVAL;
+ goto free_list_ret;
}
- new_prog = bpf_patch_insn_data(env, i + delta,
- insn_buf, cnt);
- if (!new_prog)
- return -ENOMEM;
+ elem = bpf_patch_list_insn(elem, insn_buf, cnt);
+ if (IS_ERR(elem)) {
+ ret = PTR_ERR(elem);
+ goto free_list_ret;
+ }
- delta += cnt - 1;
- env->prog = prog = new_prog;
- insn = new_prog->insnsi + i + delta;
continue;
}
@@ -9307,12 +9305,18 @@ static int fixup_bpf_calls(struct bpf_verifier_env *env)
verbose(env,
"kernel subsystem misconfigured func %s#%d\n",
func_id_name(insn->imm), insn->imm);
- return -EFAULT;
+ ret = -EFAULT;
+ goto free_list_ret;
}
insn->imm = fn->func - __bpf_call_base;
}
- return 0;
+ env = verifier_linearize_list_insn(env, list);
+ if (IS_ERR(env))
+ ret = PTR_ERR(env);
+free_list_ret:
+ bpf_destroy_list_insn(list);
+ return ret;
}
static void free_states(struct bpf_verifier_env *env)
--
2.7.4
Powered by blists - more mailing lists