This is an archive of the discontinued LLVM Phabricator instance.

BPF: permit type modifiers for __builtin_btf_type_id() relocation
ClosedPublic

Authored by yonghong-song on Mar 4 2021, 3:00 PM.

Details

Summary

Lorenz Bauer from Cloudflare tried to use "const struct <name>"
as the type for __builtin_btf_type_id(*(const struct <name>)0, 1)
relocation and hit a llvm BPF fatal error.

https://lore.kernel.org/bpf/a3782f71-3f6b-1e75-17a9-1827822c2030@fb.com/

... 
fatal error: error in backend: Empty type name for BTF_TYPE_ID_REMOTE reloc

Currently, we require the debuginfo type itself must have a name.
In this case, the debuginfo type is "const" which points to "struct <name>".
The "const" type does not have a name, hence the above fatal error
will be triggered.

Let us permit "const" and "volatile" type modifiers. We skip modifiers
in some other cases as well like structure member type tracing.
This can aviod the above fatal error.

Diff Detail

Event Timeline

yonghong-song created this revision.Mar 4 2021, 3:00 PM
yonghong-song requested review of this revision.Mar 4 2021, 3:00 PM
Herald added a project: Restricted Project. · View Herald TranscriptMar 4 2021, 3:00 PM
ast accepted this revision.Mar 4 2021, 3:04 PM
This revision is now accepted and ready to land.Mar 4 2021, 3:04 PM
anakryiko added inline comments.Mar 4 2021, 3:25 PM
llvm/lib/Target/BPF/BPFPreserveDIType.cpp
91

should we strip restrict as well?

yonghong-song added inline comments.Mar 4 2021, 3:54 PM
llvm/lib/Target/BPF/BPFPreserveDIType.cpp
91

I deliberately skipped the restrict. in C, restrict is used to restrict pointers and used in pointer declarations (include variables and parameters).

https://en.wikipedia.org/wiki/Restrict

In type casting, the restrict will be ignored. For example,

-bash-4.4$ cat tt.c
struct s {
  int a;
};
int test() {
  return __builtin_btf_type_id(*(struct s * restrict)0, 1);
}
-bash-4.4$ clang -target bpf -O2 -S -g tt.c -emit-llvm -Xclang -disable-llvm-passes

restrict does not show up in the debuginfo.

I tried to construct another example,

-bash-4.4$ cat tt.c                                                               
struct s {
  int a;
};

int test() {
  struct s * restrict v;
  return __builtin_btf_type_id(*v, 1);
}

In this case, "restrict" shows up in variable declaration as restrict -> pointer -> struct s.
The meta data we attached is the pointee type "struct s", so we are fine.

typically restrict shows up before pointer like [restrict|const|volatile]+ pointer [const|volatile]+ non-pointer type.

What I did is trying to remove const/volatile in "[const|volatile]+ non-pointer-type". So we should be fine here.

anakryiko added inline comments.Mar 4 2021, 3:57 PM
llvm/lib/Target/BPF/BPFPreserveDIType.cpp
91

ok, thanks for checking, Yonghong!

This revision was landed with ongoing or failed builds.Mar 4 2021, 4:49 PM
This revision was automatically updated to reflect the committed changes.