mirror of
https://github.com/torvalds/linux.git
synced 2024-11-11 06:31:49 +00:00
bpf: Fix net.core.bpf_jit_harden race
It is the bpf_jit_harden counterpart to commit 60b58afc96
("bpf: fix
net.core.bpf_jit_enable race"). bpf_jit_harden will be tested twice
for each subprog if there are subprogs in bpf program and constant
blinding may increase the length of program, so when running
"./test_progs -t subprogs" and toggling bpf_jit_harden between 0 and 2,
jit_subprogs may fail because constant blinding increases the length
of subprog instructions during extra passs.
So cache the value of bpf_jit_blinding_enabled() during program
allocation, and use the cached value during constant blinding, subprog
JITing and args tracking of tail call.
Signed-off-by: Hou Tao <houtao1@huawei.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Link: https://lore.kernel.org/bpf/20220309123321.2400262-4-houtao1@huawei.com
This commit is contained in:
parent
73e14451f3
commit
d2a3b7c5be
@ -566,6 +566,7 @@ struct bpf_prog {
|
|||||||
gpl_compatible:1, /* Is filter GPL compatible? */
|
gpl_compatible:1, /* Is filter GPL compatible? */
|
||||||
cb_access:1, /* Is control block accessed? */
|
cb_access:1, /* Is control block accessed? */
|
||||||
dst_needed:1, /* Do we need dst entry? */
|
dst_needed:1, /* Do we need dst entry? */
|
||||||
|
blinding_requested:1, /* needs constant blinding */
|
||||||
blinded:1, /* Was blinded */
|
blinded:1, /* Was blinded */
|
||||||
is_func:1, /* program is a bpf function */
|
is_func:1, /* program is a bpf function */
|
||||||
kprobe_override:1, /* Do we override a kprobe? */
|
kprobe_override:1, /* Do we override a kprobe? */
|
||||||
|
@ -105,6 +105,7 @@ struct bpf_prog *bpf_prog_alloc_no_stats(unsigned int size, gfp_t gfp_extra_flag
|
|||||||
fp->aux = aux;
|
fp->aux = aux;
|
||||||
fp->aux->prog = fp;
|
fp->aux->prog = fp;
|
||||||
fp->jit_requested = ebpf_jit_enabled();
|
fp->jit_requested = ebpf_jit_enabled();
|
||||||
|
fp->blinding_requested = bpf_jit_blinding_enabled(fp);
|
||||||
|
|
||||||
INIT_LIST_HEAD_RCU(&fp->aux->ksym.lnode);
|
INIT_LIST_HEAD_RCU(&fp->aux->ksym.lnode);
|
||||||
mutex_init(&fp->aux->used_maps_mutex);
|
mutex_init(&fp->aux->used_maps_mutex);
|
||||||
@ -1382,7 +1383,7 @@ struct bpf_prog *bpf_jit_blind_constants(struct bpf_prog *prog)
|
|||||||
struct bpf_insn *insn;
|
struct bpf_insn *insn;
|
||||||
int i, rewritten;
|
int i, rewritten;
|
||||||
|
|
||||||
if (!bpf_jit_blinding_enabled(prog) || prog->blinded)
|
if (!prog->blinding_requested || prog->blinded)
|
||||||
return prog;
|
return prog;
|
||||||
|
|
||||||
clone = bpf_prog_clone_create(prog, GFP_USER);
|
clone = bpf_prog_clone_create(prog, GFP_USER);
|
||||||
|
@ -13023,6 +13023,7 @@ static int jit_subprogs(struct bpf_verifier_env *env)
|
|||||||
func[i]->aux->name[0] = 'F';
|
func[i]->aux->name[0] = 'F';
|
||||||
func[i]->aux->stack_depth = env->subprog_info[i].stack_depth;
|
func[i]->aux->stack_depth = env->subprog_info[i].stack_depth;
|
||||||
func[i]->jit_requested = 1;
|
func[i]->jit_requested = 1;
|
||||||
|
func[i]->blinding_requested = prog->blinding_requested;
|
||||||
func[i]->aux->kfunc_tab = prog->aux->kfunc_tab;
|
func[i]->aux->kfunc_tab = prog->aux->kfunc_tab;
|
||||||
func[i]->aux->kfunc_btf_tab = prog->aux->kfunc_btf_tab;
|
func[i]->aux->kfunc_btf_tab = prog->aux->kfunc_btf_tab;
|
||||||
func[i]->aux->linfo = prog->aux->linfo;
|
func[i]->aux->linfo = prog->aux->linfo;
|
||||||
@ -13146,6 +13147,7 @@ out_free:
|
|||||||
out_undo_insn:
|
out_undo_insn:
|
||||||
/* cleanup main prog to be interpreted */
|
/* cleanup main prog to be interpreted */
|
||||||
prog->jit_requested = 0;
|
prog->jit_requested = 0;
|
||||||
|
prog->blinding_requested = 0;
|
||||||
for (i = 0, insn = prog->insnsi; i < prog->len; i++, insn++) {
|
for (i = 0, insn = prog->insnsi; i < prog->len; i++, insn++) {
|
||||||
if (!bpf_pseudo_call(insn))
|
if (!bpf_pseudo_call(insn))
|
||||||
continue;
|
continue;
|
||||||
@ -13239,7 +13241,6 @@ static int do_misc_fixups(struct bpf_verifier_env *env)
|
|||||||
{
|
{
|
||||||
struct bpf_prog *prog = env->prog;
|
struct bpf_prog *prog = env->prog;
|
||||||
enum bpf_attach_type eatype = prog->expected_attach_type;
|
enum bpf_attach_type eatype = prog->expected_attach_type;
|
||||||
bool expect_blinding = bpf_jit_blinding_enabled(prog);
|
|
||||||
enum bpf_prog_type prog_type = resolve_prog_type(prog);
|
enum bpf_prog_type prog_type = resolve_prog_type(prog);
|
||||||
struct bpf_insn *insn = prog->insnsi;
|
struct bpf_insn *insn = prog->insnsi;
|
||||||
const struct bpf_func_proto *fn;
|
const struct bpf_func_proto *fn;
|
||||||
@ -13403,7 +13404,7 @@ static int do_misc_fixups(struct bpf_verifier_env *env)
|
|||||||
insn->code = BPF_JMP | BPF_TAIL_CALL;
|
insn->code = BPF_JMP | BPF_TAIL_CALL;
|
||||||
|
|
||||||
aux = &env->insn_aux_data[i + delta];
|
aux = &env->insn_aux_data[i + delta];
|
||||||
if (env->bpf_capable && !expect_blinding &&
|
if (env->bpf_capable && !prog->blinding_requested &&
|
||||||
prog->jit_requested &&
|
prog->jit_requested &&
|
||||||
!bpf_map_key_poisoned(aux) &&
|
!bpf_map_key_poisoned(aux) &&
|
||||||
!bpf_map_ptr_poisoned(aux) &&
|
!bpf_map_ptr_poisoned(aux) &&
|
||||||
|
Loading…
Reference in New Issue
Block a user