• Yonghong Song's avatar
    compiler_types: define __user as __attribute__((btf_type_tag("user"))) · 7472d5a6
    Yonghong Song authored
    The __user attribute is currently mainly used by sparse for type checking.
    The attribute indicates whether a memory access is in user memory address
    space or not. Such information is important during tracing kernel
    internal functions or data structures as accessing user memory often
    has different mechanisms compared to accessing kernel memory. For example,
    the perf-probe needs explicit command line specification to indicate a
    particular argument or string in user-space memory ([1], [2], [3]).
    Currently, vmlinux BTF is available in kernel with many distributions.
    If __user attribute information is available in vmlinux BTF, the explicit
    user memory access information from users will not be necessary as
    the kernel can figure it out by itself with vmlinux BTF.
    
    Besides the above possible use for perf/probe, another use case is
    for bpf verifier. Currently, for bpf BPF_PROG_TYPE_TRACING type of bpf
    programs, users can write direct code like
      p->m1->m2
    and "p" could be a function parameter. Without __user information in BTF,
    the verifier will assume p->m1 accessing kernel memory and will generate
    normal loads. Let us say "p" actually tagged with __user in the source
    code.  In such cases, p->m1 is actually accessing user memory and direct
    load is not right and may produce incorrect result. For such cases,
    bpf_probe_read_user() will be the correct way to read p->m1.
    
    To support encoding __user information in BTF, a new attribute
      __attribute__((btf_type_tag("<arbitrary_string>")))
    is implemented in clang ([4]). For example, if we have
      #define __user __attribute__((btf_type_tag("user")))
    during kernel compilation, the attribute "user" information will
    be preserved in dwarf. After pahole converting dwarf to BTF, __user
    information will be available in vmlinux BTF.
    
    The following is an example with latest upstream clang (clang14) and
    pahole 1.23:
    
      [$ ~] cat test.c
      #define __user __attribute__((btf_type_tag("user")))
      int foo(int __user *arg) {
              return *arg;
      }
      [$ ~] clang -O2 -g -c test.c
      [$ ~] pahole -JV test.o
      ...
      [1] INT int size=4 nr_bits=32 encoding=SIGNED
      [2] TYPE_TAG user type_id=1
      [3] PTR (anon) type_id=2
      [4] FUNC_PROTO (anon) return=1 args=(3 arg)
      [5] FUNC foo type_id=4
      [$ ~]
    
    You can see for the function argument "int __user *arg", its type is
    described as
      PTR -> TYPE_TAG(user) -> INT
    The kernel can use this information for bpf verification or other
    use cases.
    
    Current btf_type_tag is only supported in clang (>= clang14) and
    pahole (>= 1.23). gcc support is also proposed and under development ([5]).
    
      [1] http://lkml.kernel.org/r/155789874562.26965.10836126971405890891.stgit@devnote2
      [2] http://lkml.kernel.org/r/155789872187.26965.4468456816590888687.stgit@devnote2
      [3] http://lkml.kernel.org/r/155789871009.26965.14167558859557329331.stgit@devnote2
      [4] https://reviews.llvm.org/D111199
      [5] https://lore.kernel.org/bpf/0cbeb2fb-1a18-f690-e360-24b1c90c2a91@fb.com/Signed-off-by: default avatarYonghong Song <yhs@fb.com>
    Link: https://lore.kernel.org/r/20220127154600.652613-1-yhs@fb.comSigned-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
    7472d5a6
Kconfig.debug 87.6 KB