Message ID | 20211110051946.368626-1-yhs@fb.com (mailing list archive) |
---|---|
State | Superseded |
Delegated to: | BPF |
Headers | show |
Series | Support BTF_KIND_TYPE_TAG for btf_type_tag attributes | expand |
On Tue, Nov 9, 2021 at 9:19 PM Yonghong Song <yhs@fb.com> wrote: > > LLVM patches ([1] for clang, [2] and [3] for BPF backend) > added support for btf_type_tag attributes. This patch > added support for the kernel. > > The main motivation for btf_type_tag is to bring kernel > annotations __user, __rcu etc. to btf. With such information > available in btf, bpf verifier can detect mis-usages > and reject the program. For example, for __user tagged pointer, > developers can then use proper helper like bpf_probe_read_kernel() probably meant to write bpf_probe_read_user()? LGTM, otherwise. Acked-by: Andrii Nakryiko <andrii@kernel.org> > etc. to read the data. > > BTF_KIND_TYPE_TAG may also useful for other tracing > facility where instead of to require user to specify > kernel/user address type, the kernel can detect it > by itself with btf. > > [1] https://reviews.llvm.org/D111199 > [2] https://reviews.llvm.org/D113222 > [3] https://reviews.llvm.org/D113496 > > Signed-off-by: Yonghong Song <yhs@fb.com> > --- > include/uapi/linux/btf.h | 3 ++- > kernel/bpf/btf.c | 14 +++++++++++++- > tools/include/uapi/linux/btf.h | 3 ++- > 3 files changed, 17 insertions(+), 3 deletions(-) > [...]
On 11/11/21 10:27 AM, Andrii Nakryiko wrote: > On Tue, Nov 9, 2021 at 9:19 PM Yonghong Song <yhs@fb.com> wrote: >> >> LLVM patches ([1] for clang, [2] and [3] for BPF backend) >> added support for btf_type_tag attributes. This patch >> added support for the kernel. >> >> The main motivation for btf_type_tag is to bring kernel >> annotations __user, __rcu etc. to btf. With such information >> available in btf, bpf verifier can detect mis-usages >> and reject the program. For example, for __user tagged pointer, >> developers can then use proper helper like bpf_probe_read_kernel() > > probably meant to write bpf_probe_read_user()? Oh, yes, a typo. should be bpf_probe_read_user(). > > LGTM, otherwise. > > Acked-by: Andrii Nakryiko <andrii@kernel.org> > >> etc. to read the data. >> >> BTF_KIND_TYPE_TAG may also useful for other tracing >> facility where instead of to require user to specify >> kernel/user address type, the kernel can detect it >> by itself with btf. >> >> [1] https://reviews.llvm.org/D111199 >> [2] https://reviews.llvm.org/D113222 >> [3] https://reviews.llvm.org/D113496 >> >> Signed-off-by: Yonghong Song <yhs@fb.com> >> --- >> include/uapi/linux/btf.h | 3 ++- >> kernel/bpf/btf.c | 14 +++++++++++++- >> tools/include/uapi/linux/btf.h | 3 ++- >> 3 files changed, 17 insertions(+), 3 deletions(-) >> > > [...] >
diff --git a/include/uapi/linux/btf.h b/include/uapi/linux/btf.h index deb12f755f0f..b0d8fea1951d 100644 --- a/include/uapi/linux/btf.h +++ b/include/uapi/linux/btf.h @@ -43,7 +43,7 @@ struct btf_type { * "size" tells the size of the type it is describing. * * "type" is used by PTR, TYPEDEF, VOLATILE, CONST, RESTRICT, - * FUNC, FUNC_PROTO, VAR and DECL_TAG. + * FUNC, FUNC_PROTO, VAR, DECL_TAG and TYPE_TAG. * "type" is a type_id referring to another type. */ union { @@ -75,6 +75,7 @@ enum { BTF_KIND_DATASEC = 15, /* Section */ BTF_KIND_FLOAT = 16, /* Floating point */ BTF_KIND_DECL_TAG = 17, /* Decl Tag */ + BTF_KIND_TYPE_TAG = 18, /* Type Tag */ NR_BTF_KINDS, BTF_KIND_MAX = NR_BTF_KINDS - 1, diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c index cdb0fba65600..1dd9ba82da1e 100644 --- a/kernel/bpf/btf.c +++ b/kernel/bpf/btf.c @@ -282,6 +282,7 @@ static const char * const btf_kind_str[NR_BTF_KINDS] = { [BTF_KIND_DATASEC] = "DATASEC", [BTF_KIND_FLOAT] = "FLOAT", [BTF_KIND_DECL_TAG] = "DECL_TAG", + [BTF_KIND_TYPE_TAG] = "TYPE_TAG", }; const char *btf_type_str(const struct btf_type *t) @@ -418,6 +419,7 @@ static bool btf_type_is_modifier(const struct btf_type *t) case BTF_KIND_VOLATILE: case BTF_KIND_CONST: case BTF_KIND_RESTRICT: + case BTF_KIND_TYPE_TAG: return true; } @@ -1737,6 +1739,7 @@ __btf_resolve_size(const struct btf *btf, const struct btf_type *type, case BTF_KIND_VOLATILE: case BTF_KIND_CONST: case BTF_KIND_RESTRICT: + case BTF_KIND_TYPE_TAG: id = type->type; type = btf_type_by_id(btf, type->type); break; @@ -2345,6 +2348,8 @@ static int btf_ref_type_check_meta(struct btf_verifier_env *env, const struct btf_type *t, u32 meta_left) { + const char *value; + if (btf_type_vlen(t)) { btf_verifier_log_type(env, t, "vlen != 0"); return -EINVAL; @@ -2360,7 +2365,7 @@ 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, + /* typedef/type_tag 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) { @@ -2369,6 +2374,12 @@ static int btf_ref_type_check_meta(struct btf_verifier_env *env, btf_verifier_log_type(env, t, "Invalid name"); return -EINVAL; } + } else if (BTF_INFO_KIND(t->info) == BTF_KIND_TYPE_TAG) { + value = btf_name_by_offset(env->btf, t->name_off); + if (!value || !value[0]) { + btf_verifier_log_type(env, t, "Invalid name"); + return -EINVAL; + } } else { if (t->name_off) { btf_verifier_log_type(env, t, "Invalid name"); @@ -4059,6 +4070,7 @@ static const struct btf_kind_operations * const kind_ops[NR_BTF_KINDS] = { [BTF_KIND_DATASEC] = &datasec_ops, [BTF_KIND_FLOAT] = &float_ops, [BTF_KIND_DECL_TAG] = &decl_tag_ops, + [BTF_KIND_TYPE_TAG] = &modifier_ops, }; static s32 btf_check_meta(struct btf_verifier_env *env, diff --git a/tools/include/uapi/linux/btf.h b/tools/include/uapi/linux/btf.h index deb12f755f0f..b0d8fea1951d 100644 --- a/tools/include/uapi/linux/btf.h +++ b/tools/include/uapi/linux/btf.h @@ -43,7 +43,7 @@ struct btf_type { * "size" tells the size of the type it is describing. * * "type" is used by PTR, TYPEDEF, VOLATILE, CONST, RESTRICT, - * FUNC, FUNC_PROTO, VAR and DECL_TAG. + * FUNC, FUNC_PROTO, VAR, DECL_TAG and TYPE_TAG. * "type" is a type_id referring to another type. */ union { @@ -75,6 +75,7 @@ enum { BTF_KIND_DATASEC = 15, /* Section */ BTF_KIND_FLOAT = 16, /* Floating point */ BTF_KIND_DECL_TAG = 17, /* Decl Tag */ + BTF_KIND_TYPE_TAG = 18, /* Type Tag */ NR_BTF_KINDS, BTF_KIND_MAX = NR_BTF_KINDS - 1,
LLVM patches ([1] for clang, [2] and [3] for BPF backend) added support for btf_type_tag attributes. This patch added support for the kernel. The main motivation for btf_type_tag is to bring kernel annotations __user, __rcu etc. to btf. With such information available in btf, bpf verifier can detect mis-usages and reject the program. For example, for __user tagged pointer, developers can then use proper helper like bpf_probe_read_kernel() etc. to read the data. BTF_KIND_TYPE_TAG may also useful for other tracing facility where instead of to require user to specify kernel/user address type, the kernel can detect it by itself with btf. [1] https://reviews.llvm.org/D111199 [2] https://reviews.llvm.org/D113222 [3] https://reviews.llvm.org/D113496 Signed-off-by: Yonghong Song <yhs@fb.com> --- include/uapi/linux/btf.h | 3 ++- kernel/bpf/btf.c | 14 +++++++++++++- tools/include/uapi/linux/btf.h | 3 ++- 3 files changed, 17 insertions(+), 3 deletions(-)