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 ---