On Sat, Sep 19, 2020 at 10:05 PM Tony Ambardar <tony.ambardar@xxxxxxxxx> wrote: > > If BTF data is missing or removed from the ELF section it is still exported > via sysfs as a zero-length file: > > root@OpenWrt:/# ls -l /sys/kernel/btf/vmlinux > -r--r--r-- 1 root root 0 Jul 18 02:59 /sys/kernel/btf/vmlinux > > Moreover, reads from this file succeed and leak kernel data: > > root@OpenWrt:/# hexdump -C /sys/kernel/btf/vmlinux|head -10 > 000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| > * > 000cc0 00 00 00 00 00 00 00 00 00 00 00 00 80 83 b0 80 |................| > 000cd0 00 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| > 000ce0 00 00 00 00 00 00 00 00 00 00 00 00 57 ac 6e 9d |............W.n.| > 000cf0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| > * > 002650 00 00 00 00 00 00 00 10 00 00 00 01 00 00 00 01 |................| > 002660 80 82 9a c4 80 85 97 80 81 a9 51 68 00 00 00 02 |..........Qh....| > 002670 80 25 44 dc 80 85 97 80 81 a9 50 24 81 ab c4 60 |.%D.......P$...`| > > This situation was first observed with kernel 5.4.x, cross-compiled for a > MIPS target system. Fix by adding a sanity-check for export of zero-length > data sections. > > Fixes: 341dfcf8d78e ("btf: expose BTF info through sysfs") > > Signed-off-by: Tony Ambardar <Tony.Ambardar@xxxxxxxxx> > --- Apparently sysfs infrastructure doesn't validate read position and size when bin_attribute's size is 0, and just expects read callback to handle such situation explicitly. Preventing sysfs entry from registering seems like a good solution. Thanks! Acked-by: Andrii Nakryiko <andriin@xxxxxx> > kernel/bpf/sysfs_btf.c | 6 +++--- > 1 file changed, 3 insertions(+), 3 deletions(-) > > diff --git a/kernel/bpf/sysfs_btf.c b/kernel/bpf/sysfs_btf.c > index 3b495773de5a..11b3380887fa 100644 > --- a/kernel/bpf/sysfs_btf.c > +++ b/kernel/bpf/sysfs_btf.c > @@ -30,15 +30,15 @@ static struct kobject *btf_kobj; > > static int __init btf_vmlinux_init(void) > { > - if (!__start_BTF) > + bin_attr_btf_vmlinux.size = __stop_BTF - __start_BTF; > + > + if (!__start_BTF || bin_attr_btf_vmlinux.size == 0) > return 0; > > btf_kobj = kobject_create_and_add("btf", kernel_kobj); > if (!btf_kobj) > return -ENOMEM; > > - bin_attr_btf_vmlinux.size = __stop_BTF - __start_BTF; > - > return sysfs_create_bin_file(btf_kobj, &bin_attr_btf_vmlinux); > } > > -- > 2.25.1 >