btf.c (448cc2fb3a7b327823a9afd374808c37b8e6194f) | btf.c (8293eb995f349aed28006792cad4cb48091919dd) |
---|---|
1/* SPDX-License-Identifier: GPL-2.0 */ 2/* Copyright (c) 2018 Facebook */ 3 4#include <uapi/linux/btf.h> 5#include <uapi/linux/bpf.h> 6#include <uapi/linux/bpf_perf_event.h> 7#include <uapi/linux/types.h> 8#include <linux/seq_file.h> --- 268 unchanged lines hidden (view full) --- 277 [BTF_KIND_CONST] = "CONST", 278 [BTF_KIND_RESTRICT] = "RESTRICT", 279 [BTF_KIND_FUNC] = "FUNC", 280 [BTF_KIND_FUNC_PROTO] = "FUNC_PROTO", 281 [BTF_KIND_VAR] = "VAR", 282 [BTF_KIND_DATASEC] = "DATASEC", 283 [BTF_KIND_FLOAT] = "FLOAT", 284 [BTF_KIND_DECL_TAG] = "DECL_TAG", | 1/* SPDX-License-Identifier: GPL-2.0 */ 2/* Copyright (c) 2018 Facebook */ 3 4#include <uapi/linux/btf.h> 5#include <uapi/linux/bpf.h> 6#include <uapi/linux/bpf_perf_event.h> 7#include <uapi/linux/types.h> 8#include <linux/seq_file.h> --- 268 unchanged lines hidden (view full) --- 277 [BTF_KIND_CONST] = "CONST", 278 [BTF_KIND_RESTRICT] = "RESTRICT", 279 [BTF_KIND_FUNC] = "FUNC", 280 [BTF_KIND_FUNC_PROTO] = "FUNC_PROTO", 281 [BTF_KIND_VAR] = "VAR", 282 [BTF_KIND_DATASEC] = "DATASEC", 283 [BTF_KIND_FLOAT] = "FLOAT", 284 [BTF_KIND_DECL_TAG] = "DECL_TAG", |
285 [BTF_KIND_TYPE_TAG] = "TYPE_TAG", |
|
285}; 286 287const char *btf_type_str(const struct btf_type *t) 288{ 289 return btf_kind_str[BTF_INFO_KIND(t->info)]; 290} 291 292/* Chunk size we use in safe copy of data to be shown. */ --- 120 unchanged lines hidden (view full) --- 413 * ptr does not fall into this bucket 414 * because its size is always sizeof(void *). 415 */ 416 switch (BTF_INFO_KIND(t->info)) { 417 case BTF_KIND_TYPEDEF: 418 case BTF_KIND_VOLATILE: 419 case BTF_KIND_CONST: 420 case BTF_KIND_RESTRICT: | 286}; 287 288const char *btf_type_str(const struct btf_type *t) 289{ 290 return btf_kind_str[BTF_INFO_KIND(t->info)]; 291} 292 293/* Chunk size we use in safe copy of data to be shown. */ --- 120 unchanged lines hidden (view full) --- 414 * ptr does not fall into this bucket 415 * because its size is always sizeof(void *). 416 */ 417 switch (BTF_INFO_KIND(t->info)) { 418 case BTF_KIND_TYPEDEF: 419 case BTF_KIND_VOLATILE: 420 case BTF_KIND_CONST: 421 case BTF_KIND_RESTRICT: |
422 case BTF_KIND_TYPE_TAG: |
|
421 return true; 422 } 423 424 return false; 425} 426 427bool btf_type_is_void(const struct btf_type *t) 428{ --- 1303 unchanged lines hidden (view full) --- 1732 size = sizeof(void *); 1733 goto resolved; 1734 1735 /* Modifiers */ 1736 case BTF_KIND_TYPEDEF: 1737 case BTF_KIND_VOLATILE: 1738 case BTF_KIND_CONST: 1739 case BTF_KIND_RESTRICT: | 423 return true; 424 } 425 426 return false; 427} 428 429bool btf_type_is_void(const struct btf_type *t) 430{ --- 1303 unchanged lines hidden (view full) --- 1734 size = sizeof(void *); 1735 goto resolved; 1736 1737 /* Modifiers */ 1738 case BTF_KIND_TYPEDEF: 1739 case BTF_KIND_VOLATILE: 1740 case BTF_KIND_CONST: 1741 case BTF_KIND_RESTRICT: |
1742 case BTF_KIND_TYPE_TAG: |
|
1740 id = type->type; 1741 type = btf_type_by_id(btf, type->type); 1742 break; 1743 1744 case BTF_KIND_ARRAY: 1745 if (!array_type) 1746 array_type = type; 1747 array = btf_type_array(type); --- 592 unchanged lines hidden (view full) --- 2340 2341 return 0; 2342} 2343 2344static int btf_ref_type_check_meta(struct btf_verifier_env *env, 2345 const struct btf_type *t, 2346 u32 meta_left) 2347{ | 1743 id = type->type; 1744 type = btf_type_by_id(btf, type->type); 1745 break; 1746 1747 case BTF_KIND_ARRAY: 1748 if (!array_type) 1749 array_type = type; 1750 array = btf_type_array(type); --- 592 unchanged lines hidden (view full) --- 2343 2344 return 0; 2345} 2346 2347static int btf_ref_type_check_meta(struct btf_verifier_env *env, 2348 const struct btf_type *t, 2349 u32 meta_left) 2350{ |
2351 const char *value; 2352 |
|
2348 if (btf_type_vlen(t)) { 2349 btf_verifier_log_type(env, t, "vlen != 0"); 2350 return -EINVAL; 2351 } 2352 2353 if (btf_type_kflag(t)) { 2354 btf_verifier_log_type(env, t, "Invalid btf_info kind_flag"); 2355 return -EINVAL; 2356 } 2357 2358 if (!BTF_TYPE_ID_VALID(t->type)) { 2359 btf_verifier_log_type(env, t, "Invalid type_id"); 2360 return -EINVAL; 2361 } 2362 | 2353 if (btf_type_vlen(t)) { 2354 btf_verifier_log_type(env, t, "vlen != 0"); 2355 return -EINVAL; 2356 } 2357 2358 if (btf_type_kflag(t)) { 2359 btf_verifier_log_type(env, t, "Invalid btf_info kind_flag"); 2360 return -EINVAL; 2361 } 2362 2363 if (!BTF_TYPE_ID_VALID(t->type)) { 2364 btf_verifier_log_type(env, t, "Invalid type_id"); 2365 return -EINVAL; 2366 } 2367 |
2363 /* typedef type must have a valid name, and other ref types, | 2368 /* typedef/type_tag type must have a valid name, and other ref types, |
2364 * volatile, const, restrict, should have a null name. 2365 */ 2366 if (BTF_INFO_KIND(t->info) == BTF_KIND_TYPEDEF) { 2367 if (!t->name_off || 2368 !btf_name_valid_identifier(env->btf, t->name_off)) { 2369 btf_verifier_log_type(env, t, "Invalid name"); 2370 return -EINVAL; 2371 } | 2369 * volatile, const, restrict, should have a null name. 2370 */ 2371 if (BTF_INFO_KIND(t->info) == BTF_KIND_TYPEDEF) { 2372 if (!t->name_off || 2373 !btf_name_valid_identifier(env->btf, t->name_off)) { 2374 btf_verifier_log_type(env, t, "Invalid name"); 2375 return -EINVAL; 2376 } |
2377 } else if (BTF_INFO_KIND(t->info) == BTF_KIND_TYPE_TAG) { 2378 value = btf_name_by_offset(env->btf, t->name_off); 2379 if (!value || !value[0]) { 2380 btf_verifier_log_type(env, t, "Invalid name"); 2381 return -EINVAL; 2382 } |
|
2372 } else { 2373 if (t->name_off) { 2374 btf_verifier_log_type(env, t, "Invalid name"); 2375 return -EINVAL; 2376 } 2377 } 2378 2379 btf_verifier_log_type(env, t, NULL); --- 573 unchanged lines hidden (view full) --- 2953 } 2954 /* A member cannot be in type void */ 2955 if (!member->type || !BTF_TYPE_ID_VALID(member->type)) { 2956 btf_verifier_log_member(env, t, member, 2957 "Invalid type_id"); 2958 return -EINVAL; 2959 } 2960 | 2383 } else { 2384 if (t->name_off) { 2385 btf_verifier_log_type(env, t, "Invalid name"); 2386 return -EINVAL; 2387 } 2388 } 2389 2390 btf_verifier_log_type(env, t, NULL); --- 573 unchanged lines hidden (view full) --- 2964 } 2965 /* A member cannot be in type void */ 2966 if (!member->type || !BTF_TYPE_ID_VALID(member->type)) { 2967 btf_verifier_log_member(env, t, member, 2968 "Invalid type_id"); 2969 return -EINVAL; 2970 } 2971 |
2961 offset = btf_member_bit_offset(t, member); | 2972 offset = __btf_member_bit_offset(t, member); |
2962 if (is_union && offset) { 2963 btf_verifier_log_member(env, t, member, 2964 "Invalid member bits_offset"); 2965 return -EINVAL; 2966 } 2967 2968 /* 2969 * ">" instead of ">=" because the last member could be --- 108 unchanged lines hidden (view full) --- 3078 continue; 3079 if (member_type->size != sz) 3080 continue; 3081 if (strcmp(__btf_name_by_offset(btf, member_type->name_off), name)) 3082 continue; 3083 if (off != -ENOENT) 3084 /* only one such field is allowed */ 3085 return -E2BIG; | 2973 if (is_union && offset) { 2974 btf_verifier_log_member(env, t, member, 2975 "Invalid member bits_offset"); 2976 return -EINVAL; 2977 } 2978 2979 /* 2980 * ">" instead of ">=" because the last member could be --- 108 unchanged lines hidden (view full) --- 3089 continue; 3090 if (member_type->size != sz) 3091 continue; 3092 if (strcmp(__btf_name_by_offset(btf, member_type->name_off), name)) 3093 continue; 3094 if (off != -ENOENT) 3095 /* only one such field is allowed */ 3096 return -E2BIG; |
3086 off = btf_member_bit_offset(t, member); | 3097 off = __btf_member_bit_offset(t, member); |
3087 if (off % 8) 3088 /* valid C code cannot generate such BTF */ 3089 return -EINVAL; 3090 off /= 8; 3091 if (off % align) 3092 return -EINVAL; 3093 } 3094 return off; --- 73 unchanged lines hidden (view full) --- 3168 member->type); 3169 const struct btf_kind_operations *ops; 3170 u32 member_offset, bitfield_size; 3171 u32 bytes_offset; 3172 u8 bits8_offset; 3173 3174 btf_show_start_member(show, member); 3175 | 3098 if (off % 8) 3099 /* valid C code cannot generate such BTF */ 3100 return -EINVAL; 3101 off /= 8; 3102 if (off % align) 3103 return -EINVAL; 3104 } 3105 return off; --- 73 unchanged lines hidden (view full) --- 3179 member->type); 3180 const struct btf_kind_operations *ops; 3181 u32 member_offset, bitfield_size; 3182 u32 bytes_offset; 3183 u8 bits8_offset; 3184 3185 btf_show_start_member(show, member); 3186 |
3176 member_offset = btf_member_bit_offset(t, member); 3177 bitfield_size = btf_member_bitfield_size(t, member); | 3187 member_offset = __btf_member_bit_offset(t, member); 3188 bitfield_size = __btf_member_bitfield_size(t, member); |
3178 bytes_offset = BITS_ROUNDDOWN_BYTES(member_offset); 3179 bits8_offset = BITS_PER_BYTE_MASKED(member_offset); 3180 if (bitfield_size) { 3181 safe_data = btf_show_start_type(show, member_type, 3182 member->type, 3183 data + bytes_offset); 3184 if (safe_data) 3185 btf_bitfield_show(safe_data, --- 868 unchanged lines hidden (view full) --- 4054 [BTF_KIND_CONST] = &modifier_ops, 4055 [BTF_KIND_RESTRICT] = &modifier_ops, 4056 [BTF_KIND_FUNC] = &func_ops, 4057 [BTF_KIND_FUNC_PROTO] = &func_proto_ops, 4058 [BTF_KIND_VAR] = &var_ops, 4059 [BTF_KIND_DATASEC] = &datasec_ops, 4060 [BTF_KIND_FLOAT] = &float_ops, 4061 [BTF_KIND_DECL_TAG] = &decl_tag_ops, | 3189 bytes_offset = BITS_ROUNDDOWN_BYTES(member_offset); 3190 bits8_offset = BITS_PER_BYTE_MASKED(member_offset); 3191 if (bitfield_size) { 3192 safe_data = btf_show_start_type(show, member_type, 3193 member->type, 3194 data + bytes_offset); 3195 if (safe_data) 3196 btf_bitfield_show(safe_data, --- 868 unchanged lines hidden (view full) --- 4065 [BTF_KIND_CONST] = &modifier_ops, 4066 [BTF_KIND_RESTRICT] = &modifier_ops, 4067 [BTF_KIND_FUNC] = &func_ops, 4068 [BTF_KIND_FUNC_PROTO] = &func_proto_ops, 4069 [BTF_KIND_VAR] = &var_ops, 4070 [BTF_KIND_DATASEC] = &datasec_ops, 4071 [BTF_KIND_FLOAT] = &float_ops, 4072 [BTF_KIND_DECL_TAG] = &decl_tag_ops, |
4073 [BTF_KIND_TYPE_TAG] = &modifier_ops, |
|
4062}; 4063 4064static s32 btf_check_meta(struct btf_verifier_env *env, 4065 const struct btf_type *t, 4066 u32 meta_left) 4067{ 4068 u32 saved_meta_left = meta_left; 4069 s32 var_meta_size; --- 973 unchanged lines hidden (view full) --- 5043 NULL); 5044 if (!btf_type_is_array(mtype)) 5045 goto error; 5046 5047 array_elem = (struct btf_array *)(mtype + 1); 5048 if (array_elem->nelems != 0) 5049 goto error; 5050 | 4074}; 4075 4076static s32 btf_check_meta(struct btf_verifier_env *env, 4077 const struct btf_type *t, 4078 u32 meta_left) 4079{ 4080 u32 saved_meta_left = meta_left; 4081 s32 var_meta_size; --- 973 unchanged lines hidden (view full) --- 5055 NULL); 5056 if (!btf_type_is_array(mtype)) 5057 goto error; 5058 5059 array_elem = (struct btf_array *)(mtype + 1); 5060 if (array_elem->nelems != 0) 5061 goto error; 5062 |
5051 moff = btf_member_bit_offset(t, member) / 8; | 5063 moff = __btf_member_bit_offset(t, member) / 8; |
5052 if (off < moff) 5053 goto error; 5054 5055 /* Only allow structure for now, can be relaxed for 5056 * other types later. 5057 */ 5058 t = btf_type_skip_modifiers(btf, array_elem->type, 5059 NULL); --- 6 unchanged lines hidden (view full) --- 5066error: 5067 bpf_log(log, "access beyond struct %s at off %u size %u\n", 5068 tname, off, size); 5069 return -EACCES; 5070 } 5071 5072 for_each_member(i, t, member) { 5073 /* offset of the field in bytes */ | 5064 if (off < moff) 5065 goto error; 5066 5067 /* Only allow structure for now, can be relaxed for 5068 * other types later. 5069 */ 5070 t = btf_type_skip_modifiers(btf, array_elem->type, 5071 NULL); --- 6 unchanged lines hidden (view full) --- 5078error: 5079 bpf_log(log, "access beyond struct %s at off %u size %u\n", 5080 tname, off, size); 5081 return -EACCES; 5082 } 5083 5084 for_each_member(i, t, member) { 5085 /* offset of the field in bytes */ |
5074 moff = btf_member_bit_offset(t, member) / 8; | 5086 moff = __btf_member_bit_offset(t, member) / 8; |
5075 if (off + size <= moff) 5076 /* won't find anything, field is already too far */ 5077 break; 5078 | 5087 if (off + size <= moff) 5088 /* won't find anything, field is already too far */ 5089 break; 5090 |
5079 if (btf_member_bitfield_size(t, member)) { 5080 u32 end_bit = btf_member_bit_offset(t, member) + 5081 btf_member_bitfield_size(t, member); | 5091 if (__btf_member_bitfield_size(t, member)) { 5092 u32 end_bit = __btf_member_bit_offset(t, member) + 5093 __btf_member_bitfield_size(t, member); |
5082 5083 /* off <= moff instead of off == moff because clang 5084 * does not generate a BTF member for anonymous 5085 * bitfield like the ":16" here: 5086 * struct { 5087 * int :16; 5088 * int x:8; 5089 * }; --- 1247 unchanged lines hidden (view full) --- 6337 .gpl_only = false, 6338 .ret_type = RET_INTEGER, 6339 .arg1_type = ARG_PTR_TO_MEM, 6340 .arg2_type = ARG_CONST_SIZE, 6341 .arg3_type = ARG_ANYTHING, 6342 .arg4_type = ARG_ANYTHING, 6343}; 6344 | 5094 5095 /* off <= moff instead of off == moff because clang 5096 * does not generate a BTF member for anonymous 5097 * bitfield like the ":16" here: 5098 * struct { 5099 * int :16; 5100 * int x:8; 5101 * }; --- 1247 unchanged lines hidden (view full) --- 6349 .gpl_only = false, 6350 .ret_type = RET_INTEGER, 6351 .arg1_type = ARG_PTR_TO_MEM, 6352 .arg2_type = ARG_CONST_SIZE, 6353 .arg3_type = ARG_ANYTHING, 6354 .arg4_type = ARG_ANYTHING, 6355}; 6356 |
6345BTF_ID_LIST_GLOBAL_SINGLE(btf_task_struct_ids, struct, task_struct) | 6357BTF_ID_LIST_GLOBAL(btf_tracing_ids, MAX_BTF_TRACING_TYPE) 6358#define BTF_TRACING_TYPE(name, type) BTF_ID(struct, type) 6359BTF_TRACING_TYPE_xxx 6360#undef BTF_TRACING_TYPE |
6346 6347/* BTF ID set registration API for modules */ 6348 6349struct kfunc_btf_id_list { 6350 struct list_head list; 6351 struct mutex mutex; 6352}; 6353 --- 47 unchanged lines hidden --- | 6361 6362/* BTF ID set registration API for modules */ 6363 6364struct kfunc_btf_id_list { 6365 struct list_head list; 6366 struct mutex mutex; 6367}; 6368 --- 47 unchanged lines hidden --- |