Skip to content

Commit b9d44bc

Browse files
eddyz87Alexei Starovoitov
authored andcommitted
bpf: make makr_btf_ld_reg return error for unexpected reg types
Non-functional change: mark_btf_ld_reg() expects 'reg_type' parameter to be either SCALAR_VALUE or PTR_TO_BTF_ID. Next commit expands this set, so update this function to fail if unexpected type is passed. Also update callers to propagate the error. Acked-by: Kumar Kartikeya Dwivedi <[email protected]> Signed-off-by: Eduard Zingerman <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Alexei Starovoitov <[email protected]>
1 parent 03fe01d commit b9d44bc

File tree

1 file changed

+39
-20
lines changed

1 file changed

+39
-20
lines changed

kernel/bpf/verifier.c

Lines changed: 39 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2796,22 +2796,28 @@ static void mark_reg_not_init(struct bpf_verifier_env *env,
27962796
__mark_reg_not_init(env, regs + regno);
27972797
}
27982798

2799-
static void mark_btf_ld_reg(struct bpf_verifier_env *env,
2800-
struct bpf_reg_state *regs, u32 regno,
2801-
enum bpf_reg_type reg_type,
2802-
struct btf *btf, u32 btf_id,
2803-
enum bpf_type_flag flag)
2799+
static int mark_btf_ld_reg(struct bpf_verifier_env *env,
2800+
struct bpf_reg_state *regs, u32 regno,
2801+
enum bpf_reg_type reg_type,
2802+
struct btf *btf, u32 btf_id,
2803+
enum bpf_type_flag flag)
28042804
{
2805-
if (reg_type == SCALAR_VALUE) {
2805+
switch (reg_type) {
2806+
case SCALAR_VALUE:
28062807
mark_reg_unknown(env, regs, regno);
2807-
return;
2808+
return 0;
2809+
case PTR_TO_BTF_ID:
2810+
mark_reg_known_zero(env, regs, regno);
2811+
regs[regno].type = PTR_TO_BTF_ID | flag;
2812+
regs[regno].btf = btf;
2813+
regs[regno].btf_id = btf_id;
2814+
if (type_may_be_null(flag))
2815+
regs[regno].id = ++env->id_gen;
2816+
return 0;
2817+
default:
2818+
verifier_bug(env, "unexpected reg_type %d in %s\n", reg_type, __func__);
2819+
return -EFAULT;
28082820
}
2809-
mark_reg_known_zero(env, regs, regno);
2810-
regs[regno].type = PTR_TO_BTF_ID | flag;
2811-
regs[regno].btf = btf;
2812-
regs[regno].btf_id = btf_id;
2813-
if (type_may_be_null(flag))
2814-
regs[regno].id = ++env->id_gen;
28152821
}
28162822

28172823
#define DEF_NOT_SUBREG (0)
@@ -5965,6 +5971,7 @@ static int check_map_kptr_access(struct bpf_verifier_env *env, u32 regno,
59655971
struct bpf_insn *insn = &env->prog->insnsi[insn_idx];
59665972
int class = BPF_CLASS(insn->code);
59675973
struct bpf_reg_state *val_reg;
5974+
int ret;
59685975

59695976
/* Things we already checked for in check_map_access and caller:
59705977
* - Reject cases where variable offset may touch kptr
@@ -5998,8 +6005,11 @@ static int check_map_kptr_access(struct bpf_verifier_env *env, u32 regno,
59986005
/* We can simply mark the value_regno receiving the pointer
59996006
* value from map as PTR_TO_BTF_ID, with the correct type.
60006007
*/
6001-
mark_btf_ld_reg(env, cur_regs(env), value_regno, PTR_TO_BTF_ID, kptr_field->kptr.btf,
6002-
kptr_field->kptr.btf_id, btf_ld_kptr_type(env, kptr_field));
6008+
ret = mark_btf_ld_reg(env, cur_regs(env), value_regno, PTR_TO_BTF_ID,
6009+
kptr_field->kptr.btf, kptr_field->kptr.btf_id,
6010+
btf_ld_kptr_type(env, kptr_field));
6011+
if (ret < 0)
6012+
return ret;
60036013
} else if (class == BPF_STX) {
60046014
val_reg = reg_state(env, value_regno);
60056015
if (!register_is_null(val_reg) &&
@@ -7298,8 +7308,11 @@ static int check_ptr_to_btf_access(struct bpf_verifier_env *env,
72987308
clear_trusted_flags(&flag);
72997309
}
73007310

7301-
if (atype == BPF_READ && value_regno >= 0)
7302-
mark_btf_ld_reg(env, regs, value_regno, ret, reg->btf, btf_id, flag);
7311+
if (atype == BPF_READ && value_regno >= 0) {
7312+
ret = mark_btf_ld_reg(env, regs, value_regno, ret, reg->btf, btf_id, flag);
7313+
if (ret < 0)
7314+
return ret;
7315+
}
73037316

73047317
return 0;
73057318
}
@@ -7353,13 +7366,19 @@ static int check_ptr_to_map_access(struct bpf_verifier_env *env,
73537366

73547367
/* Simulate access to a PTR_TO_BTF_ID */
73557368
memset(&map_reg, 0, sizeof(map_reg));
7356-
mark_btf_ld_reg(env, &map_reg, 0, PTR_TO_BTF_ID, btf_vmlinux, *map->ops->map_btf_id, 0);
7369+
ret = mark_btf_ld_reg(env, &map_reg, 0, PTR_TO_BTF_ID,
7370+
btf_vmlinux, *map->ops->map_btf_id, 0);
7371+
if (ret < 0)
7372+
return ret;
73577373
ret = btf_struct_access(&env->log, &map_reg, off, size, atype, &btf_id, &flag, NULL);
73587374
if (ret < 0)
73597375
return ret;
73607376

7361-
if (value_regno >= 0)
7362-
mark_btf_ld_reg(env, regs, value_regno, ret, btf_vmlinux, btf_id, flag);
7377+
if (value_regno >= 0) {
7378+
ret = mark_btf_ld_reg(env, regs, value_regno, ret, btf_vmlinux, btf_id, flag);
7379+
if (ret < 0)
7380+
return ret;
7381+
}
73637382

73647383
return 0;
73657384
}

0 commit comments

Comments
 (0)