bpf: btf: check name validity for various types
Subsystems (5)
v2 cover bpf: btf: check name validity for various types
This patch set added name checking for PTR, ARRAY, VOLATILE, TYPEDEF, CONST, RESTRICT, STRUCT, UNION, ENUM and FWD types. Such a strict name checking makes BTF more sound in the kernel and future BTF-to-header-file converesion ([1]) less fragile.
Patch #1 implemented btf_name_valid_identifier() for name checking which will be used in Patch #2.
Patch #2 checked name validity for the above mentioned types. Patch #3 fixed two existing test_btf unit tests exposed by the strict name checking.
Patch #4 added additional test cases.
This patch set is against bpf tree.
Patch #1 has been implemented in bpf-next commit
Commit 2667a2626f4d ("bpf: btf: Add BTF_KIND_FUNC
and BTF_KIND_FUNC_PROTO"), so there is no need to apply this patch to bpf-next. In case this patch is applied to bpf-next, there will be a minor conflict like
diff --cc kernel/bpf/btf.c
index a09b2f94ab25,93c233ab2db6..000000000000
--- a/kernel/bpf/btf.c
+++ b/kernel/bpf/btf.c
@@@ -474,7 -451,7 +474,11 @@@ static bool btf_name_valid_identifier(c
return !*src;
} ++<<<<<<< HEAD
+const char *btf_name_by_offset(const struct btf *btf, u32 offset)
++=======
+ static const char *btf_name_by_offset(const struct btf *btf, u32 offset) ++>>>>>>> fa9566b0847d... bpf: btf: implement btf_name_valid_identifier()
{
if (!offset)
return "(anon)";Just resolve the conflict by taking the "const char ..." line.
Patches #2, #3 and #4 can be applied to bpf-next without conflict.
[1]: http://vger.kernel.org/lpc-bpf2018.html#session-2
Yonghong Song (4):
bpf: btf: implement btf_name_valid_identifier()
bpf: btf: check name validity for various types
tools/bpf: fix two test_btf unit test cases
tools/bpf: add addition type tests to test_btf
kernel/bpf/btf.c | 82 ++++++ tools/testing/selftests/bpf/test_btf.c | 375 ++++++++++++++++++++++++- 2 files changed, 450 insertions(+), 7 deletions(-)
Signature · 1 line
2.17.1
PATCH v2 1/4 bpf: btf: implement btf_name_valid_identifier()
Function btf_name_valid_identifier() have been implemented in bpf-next commit 2667a2626f4d ("bpf: btf: Add BTF_KIND_FUNC and BTF_KIND_FUNC_PROTO"). Backport this function so later patch can use it.
--- kernel/bpf/btf.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+)
kernel/bpf/btf.c +25 -0
@@ -5,6 +5,7 @@#include <uapi/linux/types.h> #include <linux/seq_file.h> #include <linux/compiler.h> +#include <linux/ctype.h> #include <linux/errno.h> #include <linux/slab.h> #include <linux/anon_inodes.h>
@@ -426,6 +427,30 @@ static bool btf_name_offset_valid(const struct btf *btf, u32 offset) offset < btf->hdr.str_len; } +/* Only C-style identifier is permitted. This can be relaxed if +* necessary. +*/ +static bool btf_name_valid_identifier (const struct btf *btf,u32 offset) +{ +/* offset must be valid */ +const char *src = &btf->strings[offset]; +const char *src_limit; + +if (!isalpha (*src) && *src !='_' ) +return false; + +/* set a limit on identifier length */ + src_limit = src +KSYM_NAME_LEN ; + src++; +while (*src && src < src_limit) { +if (!isalnum (*src) && *src !='_' ) +return false; + src++; + } + +return !*src; +} +static const char *btf_name_by_offset (const struct btf *btf,u32 offset) {if (!offset)
Signature · 1 line
2.17.1
PATCH v2 2/4 bpf: btf: check name validity for various types
In reply to Yonghong SongThis patch added name checking for the following types:
. BTF_KIND_PTR, BTF_KIND_ARRAY, BTF_KIND_VOLATILE,
BTF_KIND_CONST, BTF_KIND_RESTRICT:
the name must be null
. BTF_KIND_STRUCT, BTF_KIND_UNION: the struct/member name
is either null or a valid identifier
. BTF_KIND_ENUM: the enum type name is either null or a valid
identifier; the enumerator name must be a valid identifier.
. BTF_KIND_FWD: the name must be a valid identifier
. BTF_KIND_TYPEDEF: the name must be a valid identifier
For those places a valid name is required, the name must be a valid C identifier. This can be relaxed later if we found use cases for a different (non-C) frontend.
--- kernel/bpf/btf.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+)
kernel/bpf/btf.c +57 -0
@@ -1168,6 +1168,22 @@ static int btf_ref_type_check_meta(struct btf_verifier_env *env,return -EINVAL ; } +/* typedef type must have a valid name, and other ref types, +* volatile, const, restrict, should have a null name. +*/ +if (BTF_INFO_KIND (t->info) ==BTF_KIND_TYPEDEF ) { +if (!t->name_off || + !btf_name_valid_identifier (env->btf, t->name_off)) { +btf_verifier_log_type (env, t,"Invalid name" ); +return -EINVAL ; + } + }else { +if (t->name_off) { +btf_verifier_log_type (env, t,"Invalid name" ); +return -EINVAL ; + } + } +btf_verifier_log_type (env, t,NULL );return 0 ;
@@ -1325,6 +1341,13 @@ static s32 btf_fwd_check_meta(struct btf_verifier_env *env,return -EINVAL ; } +/* fwd type must have a valid name */ +if (!t->name_off || + !btf_name_valid_identifier (env->btf, t->name_off)) { +btf_verifier_log_type (env, t,"Invalid name" ); +return -EINVAL ; + } +btf_verifier_log_type (env, t,NULL );return 0 ;
@@ -1381,6 +1404,12 @@ static s32 btf_array_check_meta(struct btf_verifier_env *env,return -EINVAL ; } +/* array type should not have a name */ +if (t->name_off) { +btf_verifier_log_type (env, t,"Invalid name" ); +return -EINVAL ; + } +if (btf_type_vlen (t)) {btf_verifier_log_type (env, t,"vlen != 0" );return -EINVAL ;
@@ -1557,6 +1586,13 @@ static s32 btf_struct_check_meta(struct btf_verifier_env *env,return -EINVAL ; } +/* struct type either no name or a valid one */ +if (t->name_off && + !btf_name_valid_identifier (env->btf, t->name_off)) { +btf_verifier_log_type (env, t,"Invalid name" ); +return -EINVAL ; + } +btf_verifier_log_type (env, t,NULL ); last_offset =0 ;
@@ -1568,6 +1604,12 @@ static s32 btf_struct_check_meta(struct btf_verifier_env *env,return -EINVAL ; } +/* struct member either no name or a valid one */ +if (member->name_off && + !btf_name_valid_identifier (btf, member->name_off)) { +btf_verifier_log_member (env, t, member,"Invalid name" ); +return -EINVAL ; + }/* A member cannot be in type void */ if (!member->type || !BTF_TYPE_ID_VALID (member->type)) { btf_verifier_log_member(env, t, member,
@@ -1755,6 +1797,13 @@ static s32 btf_enum_check_meta(struct btf_verifier_env *env,return -EINVAL ; } +/* enum type either no name or a valid one */ +if (t->name_off && + !btf_name_valid_identifier (env->btf, t->name_off)) { +btf_verifier_log_type (env, t,"Invalid name" ); +return -EINVAL ; + } +btf_verifier_log_type (env, t,NULL );for (i =0 ; i < nr_enums; i++) {
@@ -1764,6 +1813,14 @@ static s32 btf_enum_check_meta(struct btf_verifier_env *env,return -EINVAL ; } +/* enum member must have a valid name */ +if (!enums[i].name_off || + !btf_name_valid_identifier (btf, enums[i].name_off)) { +btf_verifier_log_type (env, t,"Invalid name" ); +return -EINVAL ; + } + +btf_verifier_log (env,"\t%s val=%d\n" ,btf_name_by_offset (btf, enums[i].name_off), enums[i].val);
Signature · 1 line
2.17.1
PATCH v2 3/4 tools/bpf: fix two test_btf unit test cases
In reply to Yonghong SongFrom: Martin KaFai Lau <[email protected]>
There are two unit test cases, which should encode TYPEDEF type, but instead encode PTR type. The error is flagged out after enforcing name checking in the previous patch.
--- tools/testing/selftests/bpf/test_btf.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-)
tools/testing/selftests/bpf/test_btf.c +7 -7
@@ -432,11 +432,11 @@ static struct btf_raw_test raw_tests[] = {/* const void* */ /* [3] */ BTF_TYPE_ENC (0 ,BTF_INFO_ENC (BTF_KIND_PTR ,0 ,0 ),2 ),/* typedef const void * const_void_ptr */ -BTF_TYPE_ENC (NAME_TBD ,BTF_INFO_ENC (BTF_KIND_PTR ,0 ,0 ),3 ), -/* struct A { */ /* [4] */ +BTF_TYPEDEF_ENC (NAME_TBD ,3 ),/* [4] */ +/* struct A { */ /* [5] */ BTF_TYPE_ENC (NAME_TBD ,BTF_INFO_ENC (BTF_KIND_STRUCT ,0 ,1 ),sizeof (void *)),/* const_void_ptr m; */ -BTF_MEMBER_ENC (NAME_TBD ,3 ,0 ), +BTF_MEMBER_ENC (NAME_TBD ,4 ,0 ),/* } */ BTF_END_RAW, },
@@ -494,10 +494,10 @@ static struct btf_raw_test raw_tests[] = {BTF_TYPE_ENC (0 ,BTF_INFO_ENC (BTF_KIND_CONST ,0 ,0 ),0 ),/* const void* */ /* [3] */ BTF_TYPE_ENC (0 ,BTF_INFO_ENC (BTF_KIND_PTR ,0 ,0 ),2 ), -/* typedef const void * const_void_ptr */ /* [4] */ -BTF_TYPE_ENC (NAME_TBD ,BTF_INFO_ENC (BTF_KIND_PTR ,0 ,0 ),3 ), -/* const_void_ptr[4] */ /* [5] */ -BTF_TYPE_ARRAY_ENC (3 ,1 ,4 ), +/* typedef const void * const_void_ptr */ +BTF_TYPEDEF_ENC (NAME_TBD ,3 ),/* [4] */ +/* const_void_ptr[4] */ +BTF_TYPE_ARRAY_ENC (4 ,1 ,4 ),/* [5] */ BTF_END_RAW, }, .str_sec = "\0const_void_ptr",
Signature · 1 line
2.17.1
PATCH v2 4/4 tools/bpf: add addition type tests to test_btf
In reply to Yonghong SongThe following additional unit testcases are added to test_btf:
...
BTF raw test[42] (typedef (invalid name, name_off = 0)): OK BTF raw test[43] (typedef (invalid name, invalid identifier)): OK BTF raw test[44] (ptr type (invalid name, name_off <> 0)): OK BTF raw test[45] (volatile type (invalid name, name_off <> 0)): OK BTF raw test[46] (const type (invalid name, name_off <> 0)): OK BTF raw test[47] (restrict type (invalid name, name_off <> 0)): OK BTF raw test[48] (fwd type (invalid name, name_off = 0)): OK BTF raw test[49] (fwd type (invalid name, invalid identifier)): OK BTF raw test[50] (array type (invalid name, name_off <> 0)): OK BTF raw test[51] (struct type (name_off = 0)): OK
BTF raw test[52] (struct type (invalid name, invalid identifier)): OK BTF raw test[53] (struct member (name_off = 0)): OK
BTF raw test[54] (struct member (invalid name, invalid identifier)): OK BTF raw test[55] (enum type (name_off = 0)): OK
BTF raw test[56] (enum type (invalid name, invalid identifier)): OK BTF raw test[57] (enum member (invalid name, name_off = 0)): OK BTF raw test[58] (enum member (invalid name, invalid identifier)): OK
...
--- tools/testing/selftests/bpf/test_btf.c | 361 +++++++++++++++++++++++++ 1 file changed, 361 insertions(+)
tools/testing/selftests/bpf/test_btf.c +361 -0
@@ -1292,6 +1292,367 @@ static struct btf_raw_test raw_tests[] = { .err_str = "type != 0", }, +{ + .descr = "typedef (invalid name, name_off = 0)", + .raw_types = { +BTF_TYPE_INT_ENC (0 ,BTF_INT_SIGNED ,0 ,32 ,4 ),/* [1] */ +BTF_TYPEDEF_ENC (0 ,1 ),/* [2] */ + BTF_END_RAW, + }, + .str_sec ="\0__int" , + .str_sec_size = sizeof("\0__int"), + .map_type = BPF_MAP_TYPE_ARRAY, + .map_name = "typedef_check_btf", + .key_size = sizeof(int), + .value_size = sizeof(int), + .key_type_id = 1, + .value_type_id = 1, + .max_entries = 4, + .btf_load_err = true, + .err_str = "Invalid name", +}, + +{ + .descr ="typedef (invalid name, invalid identifier)" , + .raw_types = { +BTF_TYPE_INT_ENC (0 ,BTF_INT_SIGNED ,0 ,32 ,4 ),/* [1] */ +BTF_TYPEDEF_ENC (NAME_TBD ,1 ),/* [2] */ + BTF_END_RAW, + }, + .str_sec ="\0__!int" , + .str_sec_size = sizeof("\0__!int"), + .map_type = BPF_MAP_TYPE_ARRAY, + .map_name = "typedef_check_btf", + .key_size = sizeof(int), + .value_size = sizeof(int), + .key_type_id = 1, + .value_type_id = 1, + .max_entries = 4, + .btf_load_err = true, + .err_str = "Invalid name", +}, + +{ + .descr ="ptr type (invalid name, name_off <> 0)" , + .raw_types = { +BTF_TYPE_INT_ENC (0 ,BTF_INT_SIGNED ,0 ,32 ,4 ),/* [1] */ +BTF_TYPE_ENC (NAME_TBD , +BTF_INFO_ENC (BTF_KIND_PTR ,0 ,0 ),1 ),/* [2] */ + BTF_END_RAW, + }, + .str_sec ="\0__int" , + .str_sec_size = sizeof("\0__int"), + .map_type = BPF_MAP_TYPE_ARRAY, + .map_name = "ptr_type_check_btf", + .key_size = sizeof(int), + .value_size = sizeof(int), + .key_type_id = 1, + .value_type_id = 1, + .max_entries = 4, + .btf_load_err = true, + .err_str = "Invalid name", +}, + +{ + .descr ="volatile type (invalid name, name_off <> 0)" , + .raw_types = { +BTF_TYPE_INT_ENC (0 ,BTF_INT_SIGNED ,0 ,32 ,4 ),/* [1] */ +BTF_TYPE_ENC (NAME_TBD , +BTF_INFO_ENC (BTF_KIND_VOLATILE ,0 ,0 ),1 ),/* [2] */ + BTF_END_RAW, + }, + .str_sec ="\0__int" , + .str_sec_size = sizeof("\0__int"), + .map_type = BPF_MAP_TYPE_ARRAY, + .map_name = "volatile_type_check_btf", + .key_size = sizeof(int), + .value_size = sizeof(int), + .key_type_id = 1, + .value_type_id = 1, + .max_entries = 4, + .btf_load_err = true, + .err_str = "Invalid name", +}, + +{ + .descr ="const type (invalid name, name_off <> 0)" , + .raw_types = { +BTF_TYPE_INT_ENC (0 ,BTF_INT_SIGNED ,0 ,32 ,4 ),/* [1] */ +BTF_TYPE_ENC (NAME_TBD , +BTF_INFO_ENC (BTF_KIND_CONST ,0 ,0 ),1 ),/* [2] */ + BTF_END_RAW, + }, + .str_sec ="\0__int" , + .str_sec_size = sizeof("\0__int"), + .map_type = BPF_MAP_TYPE_ARRAY, + .map_name = "const_type_check_btf", + .key_size = sizeof(int), + .value_size = sizeof(int), + .key_type_id = 1, + .value_type_id = 1, + .max_entries = 4, + .btf_load_err = true, + .err_str = "Invalid name", +}, + +{ + .descr ="restrict type (invalid name, name_off <> 0)" , + .raw_types = { +BTF_TYPE_INT_ENC (0 ,BTF_INT_SIGNED ,0 ,32 ,4 ),/* [1] */ +BTF_TYPE_ENC (0 ,BTF_INFO_ENC (BTF_KIND_PTR ,0 ,0 ),1 ),/* [2] */ +BTF_TYPE_ENC (NAME_TBD , +BTF_INFO_ENC (BTF_KIND_RESTRICT ,0 ,0 ),2 ),/* [3] */ + BTF_END_RAW, + }, + .str_sec ="\0__int" , + .str_sec_size = sizeof("\0__int"), + .map_type = BPF_MAP_TYPE_ARRAY, + .map_name = "restrict_type_check_btf", + .key_size = sizeof(int), + .value_size = sizeof(int), + .key_type_id = 1, + .value_type_id = 1, + .max_entries = 4, + .btf_load_err = true, + .err_str = "Invalid name", +}, + +{ + .descr ="fwd type (invalid name, name_off = 0)" , + .raw_types = { +BTF_TYPE_INT_ENC (0 ,BTF_INT_SIGNED ,0 ,32 ,4 ),/* [1] */ +BTF_TYPE_ENC (0 ,BTF_INFO_ENC (BTF_KIND_FWD ,0 ,0 ),0 ),/* [2] */ + BTF_END_RAW, + }, + .str_sec ="\0__skb" , + .str_sec_size = sizeof("\0__skb"), + .map_type = BPF_MAP_TYPE_ARRAY, + .map_name = "fwd_type_check_btf", + .key_size = sizeof(int), + .value_size = sizeof(int), + .key_type_id = 1, + .value_type_id = 1, + .max_entries = 4, + .btf_load_err = true, + .err_str = "Invalid name", +}, + +{ + .descr ="fwd type (invalid name, invalid identifier)" , + .raw_types = { +BTF_TYPE_INT_ENC (0 ,BTF_INT_SIGNED ,0 ,32 ,4 ),/* [1] */ +BTF_TYPE_ENC (NAME_TBD , +BTF_INFO_ENC (BTF_KIND_FWD ,0 ,0 ),0 ),/* [2] */ + BTF_END_RAW, + }, + .str_sec ="\0__!skb" , + .str_sec_size = sizeof("\0__!skb"), + .map_type = BPF_MAP_TYPE_ARRAY, + .map_name = "fwd_type_check_btf", + .key_size = sizeof(int), + .value_size = sizeof(int), + .key_type_id = 1, + .value_type_id = 1, + .max_entries = 4, + .btf_load_err = true, + .err_str = "Invalid name", +}, + +{ + .descr ="array type (invalid name, name_off <> 0)" , + .raw_types = { +BTF_TYPE_INT_ENC (0 ,BTF_INT_SIGNED ,0 ,32 ,4 ),/* [1] */ +BTF_TYPE_ENC (NAME_TBD , +BTF_INFO_ENC (BTF_KIND_ARRAY ,0 ,0 ),0 ),/* [2] */ +BTF_ARRAY_ENC (1 ,1 ,4 ), + BTF_END_RAW, + }, + .str_sec ="\0__skb" , + .str_sec_size = sizeof("\0__skb"), + .map_type = BPF_MAP_TYPE_ARRAY, + .map_name = "array_type_check_btf", + .key_size = sizeof(int), + .value_size = sizeof(int), + .key_type_id = 1, + .value_type_id = 1, + .max_entries = 4, + .btf_load_err = true, + .err_str = "Invalid name", +}, + +{ + .descr ="struct type (name_off = 0)" , + .raw_types = { +BTF_TYPE_INT_ENC (0 ,BTF_INT_SIGNED ,0 ,32 ,4 ),/* [1] */ +BTF_TYPE_ENC (0 , +BTF_INFO_ENC (BTF_KIND_STRUCT ,0 ,1 ),4 ),/* [2] */ +BTF_MEMBER_ENC (NAME_TBD ,1 ,0 ), + BTF_END_RAW, + }, + .str_sec ="\0A" , + .str_sec_size = sizeof("\0A"), + .map_type = BPF_MAP_TYPE_ARRAY, + .map_name = "struct_type_check_btf", + .key_size = sizeof(int), + .value_size = sizeof(int), + .key_type_id = 1, + .value_type_id = 1, + .max_entries = 4, +}, + +{ + .descr ="struct type (invalid name, invalid identifier)" , + .raw_types = { +BTF_TYPE_INT_ENC (0 ,BTF_INT_SIGNED ,0 ,32 ,4 ),/* [1] */ +BTF_TYPE_ENC (NAME_TBD , +BTF_INFO_ENC (BTF_KIND_STRUCT ,0 ,1 ),4 ),/* [2] */ +BTF_MEMBER_ENC (NAME_TBD ,1 ,0 ), + BTF_END_RAW, + }, + .str_sec ="\0A!\0B" , + .str_sec_size = sizeof("\0A!\0B"), + .map_type = BPF_MAP_TYPE_ARRAY, + .map_name = "struct_type_check_btf", + .key_size = sizeof(int), + .value_size = sizeof(int), + .key_type_id = 1, + .value_type_id = 1, + .max_entries = 4, + .btf_load_err = true, + .err_str = "Invalid name", +}, + +{ + .descr ="struct member (name_off = 0)" , + .raw_types = { +BTF_TYPE_INT_ENC (0 ,BTF_INT_SIGNED ,0 ,32 ,4 ),/* [1] */ +BTF_TYPE_ENC (0 , +BTF_INFO_ENC (BTF_KIND_STRUCT ,0 ,1 ),4 ),/* [2] */ +BTF_MEMBER_ENC (NAME_TBD ,1 ,0 ), + BTF_END_RAW, + }, + .str_sec ="\0A" , + .str_sec_size = sizeof("\0A"), + .map_type = BPF_MAP_TYPE_ARRAY, + .map_name = "struct_type_check_btf", + .key_size = sizeof(int), + .value_size = sizeof(int), + .key_type_id = 1, + .value_type_id = 1, + .max_entries = 4, +}, + +{ + .descr ="struct member (invalid name, invalid identifier)" , + .raw_types = { +BTF_TYPE_INT_ENC (0 ,BTF_INT_SIGNED ,0 ,32 ,4 ),/* [1] */ +BTF_TYPE_ENC (NAME_TBD , +BTF_INFO_ENC (BTF_KIND_STRUCT ,0 ,1 ),4 ),/* [2] */ +BTF_MEMBER_ENC (NAME_TBD ,1 ,0 ), + BTF_END_RAW, + }, + .str_sec ="\0A\0B*" , + .str_sec_size = sizeof("\0A\0B*"), + .map_type = BPF_MAP_TYPE_ARRAY, + .map_name = "struct_type_check_btf", + .key_size = sizeof(int), + .value_size = sizeof(int), + .key_type_id = 1, + .value_type_id = 1, + .max_entries = 4, + .btf_load_err = true, + .err_str = "Invalid name", +}, + +{ + .descr ="enum type (name_off = 0)" , + .raw_types = { +BTF_TYPE_INT_ENC (0 ,BTF_INT_SIGNED ,0 ,32 ,4 ),/* [1] */ +BTF_TYPE_ENC (0 , +BTF_INFO_ENC (BTF_KIND_ENUM ,0 ,1 ), +sizeof (int )),/* [2] */ +BTF_ENUM_ENC (NAME_TBD ,0 ), + BTF_END_RAW, + }, + .str_sec ="\0A\0B" , + .str_sec_size = sizeof("\0A\0B"), + .map_type = BPF_MAP_TYPE_ARRAY, + .map_name = "enum_type_check_btf", + .key_size = sizeof(int), + .value_size = sizeof(int), + .key_type_id = 1, + .value_type_id = 1, + .max_entries = 4, +}, + +{ + .descr ="enum type (invalid name, invalid identifier)" , + .raw_types = { +BTF_TYPE_INT_ENC (0 ,BTF_INT_SIGNED ,0 ,32 ,4 ),/* [1] */ +BTF_TYPE_ENC (NAME_TBD , +BTF_INFO_ENC (BTF_KIND_ENUM ,0 ,1 ), +sizeof (int )),/* [2] */ +BTF_ENUM_ENC (NAME_TBD ,0 ), + BTF_END_RAW, + }, + .str_sec ="\0A!\0B" , + .str_sec_size = sizeof("\0A!\0B"), + .map_type = BPF_MAP_TYPE_ARRAY, + .map_name = "enum_type_check_btf", + .key_size = sizeof(int), + .value_size = sizeof(int), + .key_type_id = 1, + .value_type_id = 1, + .max_entries = 4, + .btf_load_err = true, + .err_str = "Invalid name", +}, + +{ + .descr ="enum member (invalid name, name_off = 0)" , + .raw_types = { +BTF_TYPE_INT_ENC (0 ,BTF_INT_SIGNED ,0 ,32 ,4 ),/* [1] */ +BTF_TYPE_ENC (0 , +BTF_INFO_ENC (BTF_KIND_ENUM ,0 ,1 ), +sizeof (int )),/* [2] */ +BTF_ENUM_ENC (0 ,0 ), + BTF_END_RAW, + }, + .str_sec ="" , + .str_sec_size = sizeof(""), + .map_type = BPF_MAP_TYPE_ARRAY, + .map_name = "enum_type_check_btf", + .key_size = sizeof(int), + .value_size = sizeof(int), + .key_type_id = 1, + .value_type_id = 1, + .max_entries = 4, + .btf_load_err = true, + .err_str = "Invalid name", +}, + +{ + .descr ="enum member (invalid name, invalid identifier)" , + .raw_types = { +BTF_TYPE_INT_ENC (0 ,BTF_INT_SIGNED ,0 ,32 ,4 ),/* [1] */ +BTF_TYPE_ENC (0 , +BTF_INFO_ENC (BTF_KIND_ENUM ,0 ,1 ), +sizeof (int )),/* [2] */ +BTF_ENUM_ENC (NAME_TBD ,0 ), + BTF_END_RAW, + }, + .str_sec ="\0A!" , + .str_sec_size = sizeof("\0A!"), + .map_type = BPF_MAP_TYPE_ARRAY, + .map_name = "enum_type_check_btf", + .key_size = sizeof(int), + .value_size = sizeof(int), + .key_type_id = 1, + .value_type_id = 1, + .max_entries = 4, + .btf_load_err = true, + .err_str = "Invalid name", +}, { .descr ="arraymap invalid btf key (a bit field)" , .raw_types = {
Signature · 1 line
2.17.1
Alexei Starovoitov
AppliedQuoted 32 lines · Yonghong Song
This patch set added name checking for PTR, ARRAY, VOLATILE, TYPEDEF, CONST, RESTRICT, STRUCT, UNION, ENUM and FWD types. Such a strict name checking makes BTF more sound in the kernel and future BTF-to-header-file converesion ([1]) less fragile.
Patch #1 implemented
btf_name_valid_identifier()for name checking which will be used in Patch #2.
Patch #2 checked name validity for the above mentioned types. Patch #3 fixed two existingtest_btfunit tests exposed by the strict name checking.
Patch #4 added additional test cases.This patch set is against bpf tree.
Patch #1 has been implemented in bpf-next commit
Commit2667a2626f4d("bpf: btf: AddBTF_KIND_FUNC
andBTF_KIND_FUNC_PROTO"), so there is no need to apply this patch to bpf-next. In case this patch is applied to bpf-next, there will be a minor conflict like
diff --cckernel/bpf/btf.c
index a09b2f94ab25,93c233ab2db6..000000000000
---a/kernel/bpf/btf.c
+++b/kernel/bpf/btf.c
@@@ -474,7 -451,7 +474,11 @@@ static bool btf_name_valid_identifier(creturn !*src; }++<<<<<<< HEAD
+const char *btf_name_by_offset(const struct btf *btf, u32 offset)
++=======
+ static const char *btf_name_by_offset(const struct btf *btf, u32 offset) ++>>>>>>>fa9566b0847d... bpf: btf: implementbtf_name_valid_identifier()
Quoted 8 lines
{ if (!offset) return "(anon)";Just resolve the conflict by taking the "const char ..." line.
Patches #2, #3 and #4 can be applied to bpf-next without conflict.
Applied to bpf tree. Thanks!