@@ -6473,6 +6473,7 @@ static int check_helper_call(struct bpf_verifier_env *env, struct bpf_insn *insn
64736473 int * insn_idx_p )
64746474{
64756475 const struct bpf_func_proto * fn = NULL ;
6476+ enum bpf_return_type ret_type ;
64766477 struct bpf_reg_state * regs ;
64776478 struct bpf_call_arg_meta meta ;
64786479 int insn_idx = * insn_idx_p ;
@@ -6612,13 +6613,13 @@ static int check_helper_call(struct bpf_verifier_env *env, struct bpf_insn *insn
66126613 regs [BPF_REG_0 ].subreg_def = DEF_NOT_SUBREG ;
66136614
66146615 /* update return register (already marked as written above) */
6615- if (fn -> ret_type == RET_INTEGER ) {
6616+ ret_type = fn -> ret_type ;
6617+ if (ret_type == RET_INTEGER ) {
66166618 /* sets type to SCALAR_VALUE */
66176619 mark_reg_unknown (env , regs , BPF_REG_0 );
6618- } else if (fn -> ret_type == RET_VOID ) {
6620+ } else if (ret_type == RET_VOID ) {
66196621 regs [BPF_REG_0 ].type = NOT_INIT ;
6620- } else if (fn -> ret_type == RET_PTR_TO_MAP_VALUE_OR_NULL ||
6621- fn -> ret_type == RET_PTR_TO_MAP_VALUE ) {
6622+ } else if (base_type (ret_type ) == RET_PTR_TO_MAP_VALUE ) {
66226623 /* There is no offset yet applied, variable or fixed */
66236624 mark_reg_known_zero (env , regs , BPF_REG_0 );
66246625 /* remember map_ptr, so that check_map_access()
@@ -6632,28 +6633,27 @@ static int check_helper_call(struct bpf_verifier_env *env, struct bpf_insn *insn
66326633 }
66336634 regs [BPF_REG_0 ].map_ptr = meta .map_ptr ;
66346635 regs [BPF_REG_0 ].map_uid = meta .map_uid ;
6635- if (fn -> ret_type == RET_PTR_TO_MAP_VALUE ) {
6636+ if (type_may_be_null (ret_type )) {
6637+ regs [BPF_REG_0 ].type = PTR_TO_MAP_VALUE_OR_NULL ;
6638+ } else {
66366639 regs [BPF_REG_0 ].type = PTR_TO_MAP_VALUE ;
66376640 if (map_value_has_spin_lock (meta .map_ptr ))
66386641 regs [BPF_REG_0 ].id = ++ env -> id_gen ;
6639- } else {
6640- regs [BPF_REG_0 ].type = PTR_TO_MAP_VALUE_OR_NULL ;
66416642 }
6642- } else if (fn -> ret_type == RET_PTR_TO_SOCKET_OR_NULL ) {
6643+ } else if (base_type ( ret_type ) == RET_PTR_TO_SOCKET ) {
66436644 mark_reg_known_zero (env , regs , BPF_REG_0 );
66446645 regs [BPF_REG_0 ].type = PTR_TO_SOCKET_OR_NULL ;
6645- } else if (fn -> ret_type == RET_PTR_TO_SOCK_COMMON_OR_NULL ) {
6646+ } else if (base_type ( ret_type ) == RET_PTR_TO_SOCK_COMMON ) {
66466647 mark_reg_known_zero (env , regs , BPF_REG_0 );
66476648 regs [BPF_REG_0 ].type = PTR_TO_SOCK_COMMON_OR_NULL ;
6648- } else if (fn -> ret_type == RET_PTR_TO_TCP_SOCK_OR_NULL ) {
6649+ } else if (base_type ( ret_type ) == RET_PTR_TO_TCP_SOCK ) {
66496650 mark_reg_known_zero (env , regs , BPF_REG_0 );
66506651 regs [BPF_REG_0 ].type = PTR_TO_TCP_SOCK_OR_NULL ;
6651- } else if (fn -> ret_type == RET_PTR_TO_ALLOC_MEM_OR_NULL ) {
6652+ } else if (base_type ( ret_type ) == RET_PTR_TO_ALLOC_MEM ) {
66526653 mark_reg_known_zero (env , regs , BPF_REG_0 );
66536654 regs [BPF_REG_0 ].type = PTR_TO_MEM_OR_NULL ;
66546655 regs [BPF_REG_0 ].mem_size = meta .mem_size ;
6655- } else if (fn -> ret_type == RET_PTR_TO_MEM_OR_BTF_ID_OR_NULL ||
6656- fn -> ret_type == RET_PTR_TO_MEM_OR_BTF_ID ) {
6656+ } else if (base_type (ret_type ) == RET_PTR_TO_MEM_OR_BTF_ID ) {
66576657 const struct btf_type * t ;
66586658
66596659 mark_reg_known_zero (env , regs , BPF_REG_0 );
@@ -6672,28 +6672,28 @@ static int check_helper_call(struct bpf_verifier_env *env, struct bpf_insn *insn
66726672 return - EINVAL ;
66736673 }
66746674 regs [BPF_REG_0 ].type =
6675- fn -> ret_type == RET_PTR_TO_MEM_OR_BTF_ID ?
6676- PTR_TO_MEM : PTR_TO_MEM_OR_NULL ;
6675+ ( ret_type & PTR_MAYBE_NULL ) ?
6676+ PTR_TO_MEM_OR_NULL : PTR_TO_MEM ;
66776677 regs [BPF_REG_0 ].mem_size = tsize ;
66786678 } else {
66796679 regs [BPF_REG_0 ].type =
6680- fn -> ret_type == RET_PTR_TO_MEM_OR_BTF_ID ?
6681- PTR_TO_BTF_ID : PTR_TO_BTF_ID_OR_NULL ;
6680+ ( ret_type & PTR_MAYBE_NULL ) ?
6681+ PTR_TO_BTF_ID_OR_NULL : PTR_TO_BTF_ID ;
66826682 regs [BPF_REG_0 ].btf = meta .ret_btf ;
66836683 regs [BPF_REG_0 ].btf_id = meta .ret_btf_id ;
66846684 }
6685- } else if (fn -> ret_type == RET_PTR_TO_BTF_ID_OR_NULL ||
6686- fn -> ret_type == RET_PTR_TO_BTF_ID ) {
6685+ } else if (base_type (ret_type ) == RET_PTR_TO_BTF_ID ) {
66876686 int ret_btf_id ;
66886687
66896688 mark_reg_known_zero (env , regs , BPF_REG_0 );
6690- regs [BPF_REG_0 ].type = fn -> ret_type == RET_PTR_TO_BTF_ID ?
6691- PTR_TO_BTF_ID :
6692- PTR_TO_BTF_ID_OR_NULL ;
6689+ regs [BPF_REG_0 ].type = ( ret_type & PTR_MAYBE_NULL ) ?
6690+ PTR_TO_BTF_ID_OR_NULL :
6691+ PTR_TO_BTF_ID ;
66936692 ret_btf_id = * fn -> ret_btf_id ;
66946693 if (ret_btf_id == 0 ) {
6695- verbose (env , "invalid return type %d of func %s#%d\n" ,
6696- fn -> ret_type , func_id_name (func_id ), func_id );
6694+ verbose (env , "invalid return type %u of func %s#%d\n" ,
6695+ base_type (ret_type ), func_id_name (func_id ),
6696+ func_id );
66976697 return - EINVAL ;
66986698 }
66996699 /* current BPF helper definitions are only coming from
@@ -6702,8 +6702,8 @@ static int check_helper_call(struct bpf_verifier_env *env, struct bpf_insn *insn
67026702 regs [BPF_REG_0 ].btf = btf_vmlinux ;
67036703 regs [BPF_REG_0 ].btf_id = ret_btf_id ;
67046704 } else {
6705- verbose (env , "unknown return type %d of func %s#%d\n" ,
6706- fn -> ret_type , func_id_name (func_id ), func_id );
6705+ verbose (env , "unknown return type %u of func %s#%d\n" ,
6706+ base_type ( ret_type ) , func_id_name (func_id ), func_id );
67076707 return - EINVAL ;
67086708 }
67096709
0 commit comments