Skip to content

Commit c2209c6

Browse files
author
Alexei Starovoitov
committed
Merge branch 'btf-check-name'
Yonghong Song says: ==================== 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 2667a26 ("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 ==================== Signed-off-by: Alexei Starovoitov <[email protected]>
2 parents d78a5eb + d084891 commit c2209c6

File tree

2 files changed

+450
-7
lines changed

2 files changed

+450
-7
lines changed

kernel/bpf/btf.c

+82
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include <uapi/linux/types.h>
66
#include <linux/seq_file.h>
77
#include <linux/compiler.h>
8+
#include <linux/ctype.h>
89
#include <linux/errno.h>
910
#include <linux/slab.h>
1011
#include <linux/anon_inodes.h>
@@ -426,6 +427,30 @@ static bool btf_name_offset_valid(const struct btf *btf, u32 offset)
426427
offset < btf->hdr.str_len;
427428
}
428429

430+
/* Only C-style identifier is permitted. This can be relaxed if
431+
* necessary.
432+
*/
433+
static bool btf_name_valid_identifier(const struct btf *btf, u32 offset)
434+
{
435+
/* offset must be valid */
436+
const char *src = &btf->strings[offset];
437+
const char *src_limit;
438+
439+
if (!isalpha(*src) && *src != '_')
440+
return false;
441+
442+
/* set a limit on identifier length */
443+
src_limit = src + KSYM_NAME_LEN;
444+
src++;
445+
while (*src && src < src_limit) {
446+
if (!isalnum(*src) && *src != '_')
447+
return false;
448+
src++;
449+
}
450+
451+
return !*src;
452+
}
453+
429454
static const char *btf_name_by_offset(const struct btf *btf, u32 offset)
430455
{
431456
if (!offset)
@@ -1143,6 +1168,22 @@ static int btf_ref_type_check_meta(struct btf_verifier_env *env,
11431168
return -EINVAL;
11441169
}
11451170

1171+
/* typedef type must have a valid name, and other ref types,
1172+
* volatile, const, restrict, should have a null name.
1173+
*/
1174+
if (BTF_INFO_KIND(t->info) == BTF_KIND_TYPEDEF) {
1175+
if (!t->name_off ||
1176+
!btf_name_valid_identifier(env->btf, t->name_off)) {
1177+
btf_verifier_log_type(env, t, "Invalid name");
1178+
return -EINVAL;
1179+
}
1180+
} else {
1181+
if (t->name_off) {
1182+
btf_verifier_log_type(env, t, "Invalid name");
1183+
return -EINVAL;
1184+
}
1185+
}
1186+
11461187
btf_verifier_log_type(env, t, NULL);
11471188

11481189
return 0;
@@ -1300,6 +1341,13 @@ static s32 btf_fwd_check_meta(struct btf_verifier_env *env,
13001341
return -EINVAL;
13011342
}
13021343

1344+
/* fwd type must have a valid name */
1345+
if (!t->name_off ||
1346+
!btf_name_valid_identifier(env->btf, t->name_off)) {
1347+
btf_verifier_log_type(env, t, "Invalid name");
1348+
return -EINVAL;
1349+
}
1350+
13031351
btf_verifier_log_type(env, t, NULL);
13041352

13051353
return 0;
@@ -1356,6 +1404,12 @@ static s32 btf_array_check_meta(struct btf_verifier_env *env,
13561404
return -EINVAL;
13571405
}
13581406

1407+
/* array type should not have a name */
1408+
if (t->name_off) {
1409+
btf_verifier_log_type(env, t, "Invalid name");
1410+
return -EINVAL;
1411+
}
1412+
13591413
if (btf_type_vlen(t)) {
13601414
btf_verifier_log_type(env, t, "vlen != 0");
13611415
return -EINVAL;
@@ -1532,6 +1586,13 @@ static s32 btf_struct_check_meta(struct btf_verifier_env *env,
15321586
return -EINVAL;
15331587
}
15341588

1589+
/* struct type either no name or a valid one */
1590+
if (t->name_off &&
1591+
!btf_name_valid_identifier(env->btf, t->name_off)) {
1592+
btf_verifier_log_type(env, t, "Invalid name");
1593+
return -EINVAL;
1594+
}
1595+
15351596
btf_verifier_log_type(env, t, NULL);
15361597

15371598
last_offset = 0;
@@ -1543,6 +1604,12 @@ static s32 btf_struct_check_meta(struct btf_verifier_env *env,
15431604
return -EINVAL;
15441605
}
15451606

1607+
/* struct member either no name or a valid one */
1608+
if (member->name_off &&
1609+
!btf_name_valid_identifier(btf, member->name_off)) {
1610+
btf_verifier_log_member(env, t, member, "Invalid name");
1611+
return -EINVAL;
1612+
}
15461613
/* A member cannot be in type void */
15471614
if (!member->type || !BTF_TYPE_ID_VALID(member->type)) {
15481615
btf_verifier_log_member(env, t, member,
@@ -1730,6 +1797,13 @@ static s32 btf_enum_check_meta(struct btf_verifier_env *env,
17301797
return -EINVAL;
17311798
}
17321799

1800+
/* enum type either no name or a valid one */
1801+
if (t->name_off &&
1802+
!btf_name_valid_identifier(env->btf, t->name_off)) {
1803+
btf_verifier_log_type(env, t, "Invalid name");
1804+
return -EINVAL;
1805+
}
1806+
17331807
btf_verifier_log_type(env, t, NULL);
17341808

17351809
for (i = 0; i < nr_enums; i++) {
@@ -1739,6 +1813,14 @@ static s32 btf_enum_check_meta(struct btf_verifier_env *env,
17391813
return -EINVAL;
17401814
}
17411815

1816+
/* enum member must have a valid name */
1817+
if (!enums[i].name_off ||
1818+
!btf_name_valid_identifier(btf, enums[i].name_off)) {
1819+
btf_verifier_log_type(env, t, "Invalid name");
1820+
return -EINVAL;
1821+
}
1822+
1823+
17421824
btf_verifier_log(env, "\t%s val=%d\n",
17431825
btf_name_by_offset(btf, enums[i].name_off),
17441826
enums[i].val);

0 commit comments

Comments
 (0)