@@ -3856,12 +3856,6 @@ static bool arg_type_is_mem_size(enum bpf_arg_type type)
3856
3856
type == ARG_CONST_SIZE_OR_ZERO ;
3857
3857
}
3858
3858
3859
- static bool arg_type_is_alloc_mem_ptr (enum bpf_arg_type type )
3860
- {
3861
- return type == ARG_PTR_TO_ALLOC_MEM ||
3862
- type == ARG_PTR_TO_ALLOC_MEM_OR_NULL ;
3863
- }
3864
-
3865
3859
static bool arg_type_is_alloc_size (enum bpf_arg_type type )
3866
3860
{
3867
3861
return type == ARG_CONST_ALLOC_SIZE_OR_ZERO ;
@@ -3910,14 +3904,121 @@ static int resolve_map_arg_type(struct bpf_verifier_env *env,
3910
3904
return 0 ;
3911
3905
}
3912
3906
3907
+ struct bpf_reg_types {
3908
+ const enum bpf_reg_type types [10 ];
3909
+ };
3910
+
3911
+ static const struct bpf_reg_types map_key_value_types = {
3912
+ .types = {
3913
+ PTR_TO_STACK ,
3914
+ PTR_TO_PACKET ,
3915
+ PTR_TO_PACKET_META ,
3916
+ PTR_TO_MAP_VALUE ,
3917
+ },
3918
+ };
3919
+
3920
+ static const struct bpf_reg_types sock_types = {
3921
+ .types = {
3922
+ PTR_TO_SOCK_COMMON ,
3923
+ PTR_TO_SOCKET ,
3924
+ PTR_TO_TCP_SOCK ,
3925
+ PTR_TO_XDP_SOCK ,
3926
+ },
3927
+ };
3928
+
3929
+ static const struct bpf_reg_types mem_types = {
3930
+ .types = {
3931
+ PTR_TO_STACK ,
3932
+ PTR_TO_PACKET ,
3933
+ PTR_TO_PACKET_META ,
3934
+ PTR_TO_MAP_VALUE ,
3935
+ PTR_TO_MEM ,
3936
+ PTR_TO_RDONLY_BUF ,
3937
+ PTR_TO_RDWR_BUF ,
3938
+ },
3939
+ };
3940
+
3941
+ static const struct bpf_reg_types int_ptr_types = {
3942
+ .types = {
3943
+ PTR_TO_STACK ,
3944
+ PTR_TO_PACKET ,
3945
+ PTR_TO_PACKET_META ,
3946
+ PTR_TO_MAP_VALUE ,
3947
+ },
3948
+ };
3949
+
3950
+ static const struct bpf_reg_types fullsock_types = {
3951
+ .types = {
3952
+ PTR_TO_SOCKET ,
3953
+ PTR_TO_BTF_ID ,
3954
+ },
3955
+ };
3956
+
3957
+ static const struct bpf_reg_types scalar_types = { .types = { SCALAR_VALUE } };
3958
+ static const struct bpf_reg_types context_types = { .types = { PTR_TO_CTX } };
3959
+ static const struct bpf_reg_types alloc_mem_types = { .types = { PTR_TO_MEM } };
3960
+ static const struct bpf_reg_types const_map_ptr_types = { .types = {CONST_PTR_TO_MAP } };
3961
+ static const struct bpf_reg_types btf_ptr_types = { .types = { PTR_TO_BTF_ID } };
3962
+ static const struct bpf_reg_types spin_lock_types = { .types = { PTR_TO_MAP_VALUE } };
3963
+
3964
+ static const struct bpf_reg_types * compatible_reg_types [] = {
3965
+ [ARG_PTR_TO_MAP_KEY ] = & map_key_value_types ,
3966
+ [ARG_PTR_TO_MAP_VALUE ] = & map_key_value_types ,
3967
+ [ARG_PTR_TO_UNINIT_MAP_VALUE ] = & map_key_value_types ,
3968
+ [ARG_PTR_TO_MAP_VALUE_OR_NULL ] = & map_key_value_types ,
3969
+ [ARG_CONST_SIZE ] = & scalar_types ,
3970
+ [ARG_CONST_SIZE_OR_ZERO ] = & scalar_types ,
3971
+ [ARG_CONST_ALLOC_SIZE_OR_ZERO ] = & scalar_types ,
3972
+ [ARG_CONST_MAP_PTR ] = & const_map_ptr_types ,
3973
+ [ARG_PTR_TO_CTX ] = & context_types ,
3974
+ [ARG_PTR_TO_CTX_OR_NULL ] = & context_types ,
3975
+ [ARG_PTR_TO_SOCK_COMMON ] = & sock_types ,
3976
+ [ARG_PTR_TO_SOCKET ] = & fullsock_types ,
3977
+ [ARG_PTR_TO_SOCKET_OR_NULL ] = & fullsock_types ,
3978
+ [ARG_PTR_TO_BTF_ID ] = & btf_ptr_types ,
3979
+ [ARG_PTR_TO_SPIN_LOCK ] = & spin_lock_types ,
3980
+ [ARG_PTR_TO_MEM ] = & mem_types ,
3981
+ [ARG_PTR_TO_MEM_OR_NULL ] = & mem_types ,
3982
+ [ARG_PTR_TO_UNINIT_MEM ] = & mem_types ,
3983
+ [ARG_PTR_TO_ALLOC_MEM ] = & alloc_mem_types ,
3984
+ [ARG_PTR_TO_ALLOC_MEM_OR_NULL ] = & alloc_mem_types ,
3985
+ [ARG_PTR_TO_INT ] = & int_ptr_types ,
3986
+ [ARG_PTR_TO_LONG ] = & int_ptr_types ,
3987
+ [__BPF_ARG_TYPE_MAX ] = NULL ,
3988
+ };
3989
+
3990
+ static int check_reg_type (struct bpf_verifier_env * env , u32 regno ,
3991
+ const struct bpf_reg_types * compatible )
3992
+ {
3993
+ struct bpf_reg_state * regs = cur_regs (env ), * reg = & regs [regno ];
3994
+ enum bpf_reg_type expected , type = reg -> type ;
3995
+ int i , j ;
3996
+
3997
+ for (i = 0 ; i < ARRAY_SIZE (compatible -> types ); i ++ ) {
3998
+ expected = compatible -> types [i ];
3999
+ if (expected == NOT_INIT )
4000
+ break ;
4001
+
4002
+ if (type == expected )
4003
+ return 0 ;
4004
+ }
4005
+
4006
+ verbose (env , "R%d type=%s expected=" , regno , reg_type_str [type ]);
4007
+ for (j = 0 ; j + 1 < i ; j ++ )
4008
+ verbose (env , "%s, " , reg_type_str [compatible -> types [j ]]);
4009
+ verbose (env , "%s\n" , reg_type_str [compatible -> types [j ]]);
4010
+ return - EACCES ;
4011
+ }
4012
+
3913
4013
static int check_func_arg (struct bpf_verifier_env * env , u32 arg ,
3914
4014
struct bpf_call_arg_meta * meta ,
3915
4015
const struct bpf_func_proto * fn )
3916
4016
{
3917
4017
u32 regno = BPF_REG_1 + arg ;
3918
4018
struct bpf_reg_state * regs = cur_regs (env ), * reg = & regs [regno ];
3919
- enum bpf_reg_type expected_type , type = reg -> type ;
3920
4019
enum bpf_arg_type arg_type = fn -> arg_type [arg ];
4020
+ const struct bpf_reg_types * compatible ;
4021
+ enum bpf_reg_type type = reg -> type ;
3921
4022
int err = 0 ;
3922
4023
3923
4024
if (arg_type == ARG_DONTCARE )
@@ -3956,72 +4057,16 @@ static int check_func_arg(struct bpf_verifier_env *env, u32 arg,
3956
4057
*/
3957
4058
goto skip_type_check ;
3958
4059
3959
- if (arg_type == ARG_PTR_TO_MAP_KEY ||
3960
- arg_type == ARG_PTR_TO_MAP_VALUE ||
3961
- arg_type == ARG_PTR_TO_UNINIT_MAP_VALUE ||
3962
- arg_type == ARG_PTR_TO_MAP_VALUE_OR_NULL ) {
3963
- expected_type = PTR_TO_STACK ;
3964
- if (!type_is_pkt_pointer (type ) &&
3965
- type != PTR_TO_MAP_VALUE &&
3966
- type != expected_type )
3967
- goto err_type ;
3968
- } else if (arg_type == ARG_CONST_SIZE ||
3969
- arg_type == ARG_CONST_SIZE_OR_ZERO ||
3970
- arg_type == ARG_CONST_ALLOC_SIZE_OR_ZERO ) {
3971
- expected_type = SCALAR_VALUE ;
3972
- if (type != expected_type )
3973
- goto err_type ;
3974
- } else if (arg_type == ARG_CONST_MAP_PTR ) {
3975
- expected_type = CONST_PTR_TO_MAP ;
3976
- if (type != expected_type )
3977
- goto err_type ;
3978
- } else if (arg_type == ARG_PTR_TO_CTX ||
3979
- arg_type == ARG_PTR_TO_CTX_OR_NULL ) {
3980
- expected_type = PTR_TO_CTX ;
3981
- if (type != expected_type )
3982
- goto err_type ;
3983
- } else if (arg_type == ARG_PTR_TO_SOCK_COMMON ) {
3984
- expected_type = PTR_TO_SOCK_COMMON ;
3985
- /* Any sk pointer can be ARG_PTR_TO_SOCK_COMMON */
3986
- if (!type_is_sk_pointer (type ))
3987
- goto err_type ;
3988
- } else if (arg_type == ARG_PTR_TO_SOCKET ||
3989
- arg_type == ARG_PTR_TO_SOCKET_OR_NULL ) {
3990
- expected_type = PTR_TO_SOCKET ;
3991
- if (type != expected_type )
3992
- goto err_type ;
3993
- } else if (arg_type == ARG_PTR_TO_BTF_ID ) {
3994
- expected_type = PTR_TO_BTF_ID ;
3995
- if (type != expected_type )
3996
- goto err_type ;
3997
- } else if (arg_type == ARG_PTR_TO_SPIN_LOCK ) {
3998
- expected_type = PTR_TO_MAP_VALUE ;
3999
- if (type != expected_type )
4000
- goto err_type ;
4001
- } else if (arg_type_is_mem_ptr (arg_type )) {
4002
- expected_type = PTR_TO_STACK ;
4003
- if (!type_is_pkt_pointer (type ) &&
4004
- type != PTR_TO_MAP_VALUE &&
4005
- type != PTR_TO_MEM &&
4006
- type != PTR_TO_RDONLY_BUF &&
4007
- type != PTR_TO_RDWR_BUF &&
4008
- type != expected_type )
4009
- goto err_type ;
4010
- } else if (arg_type_is_alloc_mem_ptr (arg_type )) {
4011
- expected_type = PTR_TO_MEM ;
4012
- if (type != expected_type )
4013
- goto err_type ;
4014
- } else if (arg_type_is_int_ptr (arg_type )) {
4015
- expected_type = PTR_TO_STACK ;
4016
- if (!type_is_pkt_pointer (type ) &&
4017
- type != PTR_TO_MAP_VALUE &&
4018
- type != expected_type )
4019
- goto err_type ;
4020
- } else {
4021
- verbose (env , "unsupported arg_type %d\n" , arg_type );
4060
+ compatible = compatible_reg_types [arg_type ];
4061
+ if (!compatible ) {
4062
+ verbose (env , "verifier internal error: unsupported arg type %d\n" , arg_type );
4022
4063
return - EFAULT ;
4023
4064
}
4024
4065
4066
+ err = check_reg_type (env , regno , compatible );
4067
+ if (err )
4068
+ return err ;
4069
+
4025
4070
if (type == PTR_TO_BTF_ID ) {
4026
4071
const u32 * btf_id = fn -> arg_btf_id [arg ];
4027
4072
@@ -4174,10 +4219,6 @@ static int check_func_arg(struct bpf_verifier_env *env, u32 arg,
4174
4219
}
4175
4220
4176
4221
return err ;
4177
- err_type :
4178
- verbose (env , "R%d type=%s expected=%s\n" , regno ,
4179
- reg_type_str [type ], reg_type_str [expected_type ]);
4180
- return - EACCES ;
4181
4222
}
4182
4223
4183
4224
static bool may_update_sockmap (struct bpf_verifier_env * env , int func_id )
0 commit comments