Message ID | 20211110051940.367472-1-yhs@fb.com (mailing list archive) |
---|---|
Headers | show |
Series | Support BTF_KIND_TYPE_TAG for btf_type_tag attributes | expand |
On Tue, Nov 09, 2021 at 09:19:40PM -0800, Yonghong Song 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() > etc. to read the data. +#define __tag1 __attribute__((btf_type_tag("tag1"))) +#define __tag2 __attribute__((btf_type_tag("tag2"))) + +struct btf_type_tag_test { + int __tag1 * __tag1 __tag2 *p; +} g; Can we build the kernel with the latest clang and get __user in BTF ?
On 11/9/21 9:28 PM, Alexei Starovoitov wrote: > On Tue, Nov 09, 2021 at 09:19:40PM -0800, Yonghong Song 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() >> etc. to read the data. > > +#define __tag1 __attribute__((btf_type_tag("tag1"))) > +#define __tag2 __attribute__((btf_type_tag("tag2"))) > + > +struct btf_type_tag_test { > + int __tag1 * __tag1 __tag2 *p; > +} g; > > Can we build the kernel with the latest clang and get __user in BTF ? Not yet. The following are the steps: 1. land this patch set in the kernel 2. sync to libbpf repo. 3. pahole sync with libbpf repo, and pahole convert btf_type_tag in llvm to BTF 4. another kernel patch to define __user as __attribute__((btf_type_tag("user"))) and then we will get __user in vmlinux BTF.
On Tue, Nov 9, 2021 at 10:26 PM Yonghong Song <yhs@fb.com> wrote: > > > > On 11/9/21 9:28 PM, Alexei Starovoitov wrote: > > On Tue, Nov 09, 2021 at 09:19:40PM -0800, Yonghong Song 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() > >> etc. to read the data. > > > > +#define __tag1 __attribute__((btf_type_tag("tag1"))) > > +#define __tag2 __attribute__((btf_type_tag("tag2"))) > > + > > +struct btf_type_tag_test { > > + int __tag1 * __tag1 __tag2 *p; > > +} g; > > > > Can we build the kernel with the latest clang and get __user in BTF ? > > Not yet. The following are the steps: > 1. land this patch set in the kernel > 2. sync to libbpf repo. > 3. pahole sync with libbpf repo, and pahole convert btf_type_tag > in llvm to BTF > 4. another kernel patch to define __user as > __attribute__((btf_type_tag("user"))) > and then we will get __user in vmlinux BTF. Makes sense. I was wondering whether clang can handle the whole kernel source code with #define __user __attribute__((btf_type_tag("user"))) Steps 1,2,3 are necessary to make use of it, but step 4 can be tried out already?
On 11/10/21 8:40 AM, Alexei Starovoitov wrote: > On Tue, Nov 9, 2021 at 10:26 PM Yonghong Song <yhs@fb.com> wrote: >> >> >> >> On 11/9/21 9:28 PM, Alexei Starovoitov wrote: >>> On Tue, Nov 09, 2021 at 09:19:40PM -0800, Yonghong Song 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() >>>> etc. to read the data. >>> >>> +#define __tag1 __attribute__((btf_type_tag("tag1"))) >>> +#define __tag2 __attribute__((btf_type_tag("tag2"))) >>> + >>> +struct btf_type_tag_test { >>> + int __tag1 * __tag1 __tag2 *p; >>> +} g; >>> >>> Can we build the kernel with the latest clang and get __user in BTF ? >> >> Not yet. The following are the steps: >> 1. land this patch set in the kernel >> 2. sync to libbpf repo. >> 3. pahole sync with libbpf repo, and pahole convert btf_type_tag >> in llvm to BTF >> 4. another kernel patch to define __user as >> __attribute__((btf_type_tag("user"))) >> and then we will get __user in vmlinux BTF. > > Makes sense. I was wondering whether clang can handle > the whole kernel source code with > #define __user __attribute__((btf_type_tag("user"))) > Steps 1,2,3 are necessary to make use of it, > but step 4 can be tried out already? Yes, you try clang -> vmlinux dwarf part of step 4 with the following kernel hack: diff --git a/include/linux/compiler_types.h b/include/linux/compiler_types.h index 05ceb2e92b0e..30e199c30a53 100644 --- a/include/linux/compiler_types.h +++ b/include/linux/compiler_types.h @@ -32,7 +32,7 @@ static inline void __chk_io_ptr(const volatile void __iomem *ptr) { } # ifdef STRUCTLEAK_PLUGIN # define __user __attribute__((user)) # else -# define __user +# define __user __attribute__((btf_type_tag("user"))) # endif # define __iomem # define __percpu [yhs@devbig309.ftw3 ~/work/bpf-next]
On Wed, Nov 10, 2021 at 9:04 AM Yonghong Song <yhs@fb.com> wrote: > > > > On 11/10/21 8:40 AM, Alexei Starovoitov wrote: > > On Tue, Nov 9, 2021 at 10:26 PM Yonghong Song <yhs@fb.com> wrote: > >> > >> > >> > >> On 11/9/21 9:28 PM, Alexei Starovoitov wrote: > >>> On Tue, Nov 09, 2021 at 09:19:40PM -0800, Yonghong Song 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() > >>>> etc. to read the data. > >>> > >>> +#define __tag1 __attribute__((btf_type_tag("tag1"))) > >>> +#define __tag2 __attribute__((btf_type_tag("tag2"))) > >>> + > >>> +struct btf_type_tag_test { > >>> + int __tag1 * __tag1 __tag2 *p; > >>> +} g; > >>> > >>> Can we build the kernel with the latest clang and get __user in BTF ? > >> > >> Not yet. The following are the steps: > >> 1. land this patch set in the kernel > >> 2. sync to libbpf repo. > >> 3. pahole sync with libbpf repo, and pahole convert btf_type_tag > >> in llvm to BTF > >> 4. another kernel patch to define __user as > >> __attribute__((btf_type_tag("user"))) > >> and then we will get __user in vmlinux BTF. > > > > Makes sense. I was wondering whether clang can handle > > the whole kernel source code with > > #define __user __attribute__((btf_type_tag("user"))) > > Steps 1,2,3 are necessary to make use of it, > > but step 4 can be tried out already? > > Yes, you try clang -> vmlinux dwarf part of step 4 with > the following kernel hack: > > diff --git a/include/linux/compiler_types.h b/include/linux/compiler_types.h > index 05ceb2e92b0e..30e199c30a53 100644 > --- a/include/linux/compiler_types.h > +++ b/include/linux/compiler_types.h > @@ -32,7 +32,7 @@ static inline void __chk_io_ptr(const volatile void > __iomem *ptr) { } > # ifdef STRUCTLEAK_PLUGIN > # define __user __attribute__((user)) > # else > -# define __user > +# define __user __attribute__((btf_type_tag("user"))) > # endif > # define __iomem > # define __percpu I've tried the latest LLVM with the above diff and it seems to work! $ llvm-dwarfdump kernel/bpf/built-in.a |grep -3 btf_type_tag|head 0x00003ace: DW_TAG_pointer_type 0x00003acf: DW_TAG_LLVM_annotation DW_AT_name ("btf_type_tag") DW_AT_const_value ("user") Nice! Didn't notice any warnings. Great.