@@ -550,6 +550,66 @@ u32 btf_nr_types(const struct btf *btf)
550550 return total ;
551551}
552552
553+ /* Anonymous types (with empty names) are considered greater than named types
554+ * and are sorted after them. Two anonymous types are considered equal. Named
555+ * types are compared lexicographically.
556+ */
557+ static int btf_compare_type_names (const void * a , const void * b , void * priv )
558+ {
559+ struct btf * btf = (struct btf * )priv ;
560+ const struct btf_type * ta = btf_type_by_id (btf , * (__u32 * )a );
561+ const struct btf_type * tb = btf_type_by_id (btf , * (__u32 * )b );
562+ const char * na , * nb ;
563+
564+ if (!ta -> name_off && tb -> name_off )
565+ return 1 ;
566+ if (ta -> name_off && !tb -> name_off )
567+ return -1 ;
568+ if (!ta -> name_off && !tb -> name_off )
569+ return 0 ;
570+
571+ na = btf_name_by_offset (btf , ta -> name_off );
572+ nb = btf_name_by_offset (btf , tb -> name_off );
573+ return strcmp (na , nb );
574+ }
575+
576+ /* Verifies that BTF types are sorted in ascending order according to their
577+ * names, with named types appearing before anonymous types. If the ordering
578+ * is correct, counts the number of named types and updates the BTF object's
579+ * nr_sorted_types field. Note that vmlinux and kernel module BTFs are sorted
580+ * during the building phase, so the validation logic only needs to count the
581+ * named types.
582+ */
583+ static void btf_check_sorted (struct btf * btf )
584+ {
585+ const struct btf_type * t ;
586+ int i , n , k = 0 , nr_sorted_types ;
587+ bool skip_cmp = btf_is_kernel (btf );
588+
589+ if (btf -> nr_types < 2 )
590+ return ;
591+
592+ nr_sorted_types = 0 ;
593+ n = btf_nr_types (btf ) - 1 ;
594+ for (i = btf_start_id (btf ); i < n ; i ++ ) {
595+ k = i + 1 ;
596+ if (!skip_cmp && btf_compare_type_names (& i , & k , btf ) > 0 )
597+ return ;
598+
599+ t = btf_type_by_id (btf , i );
600+ if (t -> name_off )
601+ nr_sorted_types ++ ;
602+ else if (skip_cmp )
603+ break ;
604+ }
605+
606+ t = btf_type_by_id (btf , k );
607+ if (t -> name_off )
608+ nr_sorted_types ++ ;
609+ if (nr_sorted_types )
610+ btf -> nr_sorted_types = nr_sorted_types ;
611+ }
612+
553613static s32 btf_find_by_name_kind_bsearch (const struct btf * btf , const char * name ,
554614 s32 start_id , s32 end_id )
555615{
@@ -5885,6 +5945,8 @@ static struct btf *btf_parse(const union bpf_attr *attr, bpfptr_t uattr, u32 uat
58855945 if (err )
58865946 goto errout ;
58875947
5948+ btf_check_sorted (btf );
5949+
58885950 struct_meta_tab = btf_parse_struct_metas (& env -> log , btf );
58895951 if (IS_ERR (struct_meta_tab )) {
58905952 err = PTR_ERR (struct_meta_tab );
@@ -6292,6 +6354,7 @@ static struct btf *btf_parse_base(struct btf_verifier_env *env, const char *name
62926354 if (err )
62936355 goto errout ;
62946356
6357+ btf_check_sorted (btf );
62956358 refcount_set (& btf -> refcnt , 1 );
62966359
62976360 return btf ;
@@ -6426,6 +6489,7 @@ static struct btf *btf_parse_module(const char *module_name, const void *data,
64266489 }
64276490
64286491 btf_verifier_env_free (env );
6492+ btf_check_sorted (btf );
64296493 refcount_set (& btf -> refcnt , 1 );
64306494 return btf ;
64316495
0 commit comments