@@ -4377,7 +4377,7 @@ static u8 bpf_ctx_convert_map[] = {
43774377#undef BPF_LINK_TYPE
43784378
43794379static const struct btf_member *
4380- btf_get_prog_ctx_type (struct bpf_verifier_log * log , struct btf * btf ,
4380+ btf_get_prog_ctx_type (struct bpf_verifier_log * log , const struct btf * btf ,
43814381 const struct btf_type * t , enum bpf_prog_type prog_type ,
43824382 int arg )
43834383{
@@ -5362,122 +5362,135 @@ int btf_check_type_match(struct bpf_verifier_log *log, const struct bpf_prog *pr
53625362 return btf_check_func_type_match (log , btf1 , t1 , btf2 , t2 );
53635363}
53645364
5365- /* Compare BTF of a function with given bpf_reg_state.
5366- * Returns:
5367- * EFAULT - there is a verifier bug. Abort verification.
5368- * EINVAL - there is a type mismatch or BTF is not available.
5369- * 0 - BTF matches with what bpf_reg_state expects.
5370- * Only PTR_TO_CTX and SCALAR_VALUE states are recognized.
5371- */
5372- int btf_check_func_arg_match (struct bpf_verifier_env * env , int subprog ,
5373- struct bpf_reg_state * regs )
5365+ static int btf_check_func_arg_match (struct bpf_verifier_env * env ,
5366+ const struct btf * btf , u32 func_id ,
5367+ struct bpf_reg_state * regs ,
5368+ bool ptr_to_mem_ok )
53745369{
53755370 struct bpf_verifier_log * log = & env -> log ;
5376- struct bpf_prog * prog = env -> prog ;
5377- struct btf * btf = prog -> aux -> btf ;
5378- const struct btf_param * args ;
5371+ const char * func_name , * ref_tname ;
53795372 const struct btf_type * t , * ref_t ;
5380- u32 i , nargs , btf_id , type_size ;
5381- const char * tname ;
5382- bool is_global ;
5383-
5384- if (!prog -> aux -> func_info )
5385- return - EINVAL ;
5386-
5387- btf_id = prog -> aux -> func_info [subprog ].type_id ;
5388- if (!btf_id )
5389- return - EFAULT ;
5390-
5391- if (prog -> aux -> func_info_aux [subprog ].unreliable )
5392- return - EINVAL ;
5373+ const struct btf_param * args ;
5374+ u32 i , nargs ;
53935375
5394- t = btf_type_by_id (btf , btf_id );
5376+ t = btf_type_by_id (btf , func_id );
53955377 if (!t || !btf_type_is_func (t )) {
53965378 /* These checks were already done by the verifier while loading
53975379 * struct bpf_func_info
53985380 */
5399- bpf_log (log , "BTF of func#%d doesn't point to KIND_FUNC\n" ,
5400- subprog );
5381+ bpf_log (log , "BTF of func_id %u doesn't point to KIND_FUNC\n" ,
5382+ func_id );
54015383 return - EFAULT ;
54025384 }
5403- tname = btf_name_by_offset (btf , t -> name_off );
5385+ func_name = btf_name_by_offset (btf , t -> name_off );
54045386
54055387 t = btf_type_by_id (btf , t -> type );
54065388 if (!t || !btf_type_is_func_proto (t )) {
5407- bpf_log (log , "Invalid BTF of func %s\n" , tname );
5389+ bpf_log (log , "Invalid BTF of func %s\n" , func_name );
54085390 return - EFAULT ;
54095391 }
54105392 args = (const struct btf_param * )(t + 1 );
54115393 nargs = btf_type_vlen (t );
54125394 if (nargs > MAX_BPF_FUNC_REG_ARGS ) {
5413- bpf_log (log , "Function %s has %d > %d args\n" , tname , nargs ,
5395+ bpf_log (log , "Function %s has %d > %d args\n" , func_name , nargs ,
54145396 MAX_BPF_FUNC_REG_ARGS );
5415- goto out ;
5397+ return - EINVAL ;
54165398 }
54175399
5418- is_global = prog -> aux -> func_info_aux [subprog ].linkage == BTF_FUNC_GLOBAL ;
54195400 /* check that BTF function arguments match actual types that the
54205401 * verifier sees.
54215402 */
54225403 for (i = 0 ; i < nargs ; i ++ ) {
5423- struct bpf_reg_state * reg = & regs [i + 1 ];
5404+ u32 regno = i + 1 ;
5405+ struct bpf_reg_state * reg = & regs [regno ];
54245406
5425- t = btf_type_by_id (btf , args [i ].type );
5426- while (btf_type_is_modifier (t ))
5427- t = btf_type_by_id (btf , t -> type );
5428- if (btf_type_is_int (t ) || btf_type_is_enum (t )) {
5407+ t = btf_type_skip_modifiers (btf , args [i ].type , NULL );
5408+ if (btf_type_is_scalar (t )) {
54295409 if (reg -> type == SCALAR_VALUE )
54305410 continue ;
5431- bpf_log (log , "R%d is not a scalar\n" , i + 1 );
5432- goto out ;
5411+ bpf_log (log , "R%d is not a scalar\n" , regno );
5412+ return - EINVAL ;
54335413 }
5434- if (btf_type_is_ptr (t )) {
5414+
5415+ if (!btf_type_is_ptr (t )) {
5416+ bpf_log (log , "Unrecognized arg#%d type %s\n" ,
5417+ i , btf_type_str (t ));
5418+ return - EINVAL ;
5419+ }
5420+
5421+ ref_t = btf_type_skip_modifiers (btf , t -> type , NULL );
5422+ ref_tname = btf_name_by_offset (btf , ref_t -> name_off );
5423+ if (btf_get_prog_ctx_type (log , btf , t , env -> prog -> type , i )) {
54355424 /* If function expects ctx type in BTF check that caller
54365425 * is passing PTR_TO_CTX.
54375426 */
5438- if (btf_get_prog_ctx_type (log , btf , t , prog -> type , i )) {
5439- if (reg -> type != PTR_TO_CTX ) {
5440- bpf_log (log ,
5441- "arg#%d expected pointer to ctx, but got %s\n" ,
5442- i , btf_kind_str [BTF_INFO_KIND (t -> info )]);
5443- goto out ;
5444- }
5445- if (check_ctx_reg (env , reg , i + 1 ))
5446- goto out ;
5447- continue ;
5427+ if (reg -> type != PTR_TO_CTX ) {
5428+ bpf_log (log ,
5429+ "arg#%d expected pointer to ctx, but got %s\n" ,
5430+ i , btf_type_str (t ));
5431+ return - EINVAL ;
54485432 }
5433+ if (check_ctx_reg (env , reg , regno ))
5434+ return - EINVAL ;
5435+ } else if (ptr_to_mem_ok ) {
5436+ const struct btf_type * resolve_ret ;
5437+ u32 type_size ;
54495438
5450- if (!is_global )
5451- goto out ;
5452-
5453- t = btf_type_skip_modifiers (btf , t -> type , NULL );
5454-
5455- ref_t = btf_resolve_size (btf , t , & type_size );
5456- if (IS_ERR (ref_t )) {
5439+ resolve_ret = btf_resolve_size (btf , ref_t , & type_size );
5440+ if (IS_ERR (resolve_ret )) {
54575441 bpf_log (log ,
5458- "arg#%d reference type('%s %s') size cannot be determined: %ld\n" ,
5459- i , btf_type_str (t ), btf_name_by_offset ( btf , t -> name_off ) ,
5460- PTR_ERR (ref_t ));
5461- goto out ;
5442+ "arg#%d reference type('%s %s') size cannot be determined: %ld\n" ,
5443+ i , btf_type_str (ref_t ), ref_tname ,
5444+ PTR_ERR (resolve_ret ));
5445+ return - EINVAL ;
54625446 }
54635447
5464- if (check_mem_reg (env , reg , i + 1 , type_size ))
5465- goto out ;
5466-
5467- continue ;
5448+ if (check_mem_reg (env , reg , regno , type_size ))
5449+ return - EINVAL ;
5450+ } else {
5451+ return - EINVAL ;
54685452 }
5469- bpf_log (log , "Unrecognized arg#%d type %s\n" ,
5470- i , btf_kind_str [BTF_INFO_KIND (t -> info )]);
5471- goto out ;
54725453 }
5454+
54735455 return 0 ;
5474- out :
5456+ }
5457+
5458+ /* Compare BTF of a function with given bpf_reg_state.
5459+ * Returns:
5460+ * EFAULT - there is a verifier bug. Abort verification.
5461+ * EINVAL - there is a type mismatch or BTF is not available.
5462+ * 0 - BTF matches with what bpf_reg_state expects.
5463+ * Only PTR_TO_CTX and SCALAR_VALUE states are recognized.
5464+ */
5465+ int btf_check_subprog_arg_match (struct bpf_verifier_env * env , int subprog ,
5466+ struct bpf_reg_state * regs )
5467+ {
5468+ struct bpf_prog * prog = env -> prog ;
5469+ struct btf * btf = prog -> aux -> btf ;
5470+ bool is_global ;
5471+ u32 btf_id ;
5472+ int err ;
5473+
5474+ if (!prog -> aux -> func_info )
5475+ return - EINVAL ;
5476+
5477+ btf_id = prog -> aux -> func_info [subprog ].type_id ;
5478+ if (!btf_id )
5479+ return - EFAULT ;
5480+
5481+ if (prog -> aux -> func_info_aux [subprog ].unreliable )
5482+ return - EINVAL ;
5483+
5484+ is_global = prog -> aux -> func_info_aux [subprog ].linkage == BTF_FUNC_GLOBAL ;
5485+ err = btf_check_func_arg_match (env , btf , btf_id , regs , is_global );
5486+
54755487 /* Compiler optimizations can remove arguments from static functions
54765488 * or mismatched type can be passed into a global function.
54775489 * In such cases mark the function as unreliable from BTF point of view.
54785490 */
5479- prog -> aux -> func_info_aux [subprog ].unreliable = true;
5480- return - EINVAL ;
5491+ if (err )
5492+ prog -> aux -> func_info_aux [subprog ].unreliable = true;
5493+ return err ;
54815494}
54825495
54835496/* Convert BTF of a function into bpf_reg_state if possible
0 commit comments