From 7024f1ab66ff8d34485e64099b2d21c7fb4b99e1 Mon Sep 17 00:00:00 2001 From: Lorenz Bauer Date: Tue, 31 Oct 2023 17:27:23 +0000 Subject: [PATCH] btf: fix CO-RE relocations for local type id At some point the kernel gained the ability to dynamically allocated typed memory via a bpf_obj_new helper (see [1]). This helper receives the ID of the type to allocate as an argument. Trying to use this helper with the library will currently fail, since we took a short-cut when implementing on the fly BTF generation. At that point in time there was no use of the local_type_id relocation in the kernel, so we just stuck with the value present in ext_infos. This is of course not correct when building a BTF blob from scratch: type IDs are reallocated, and only used types are passed to the kernel in the first place. Fix this by allocating an ID for any type that is the target of a local_type_id relocation. 1: https://lwn.net/Articles/915404/ Signed-off-by: Lorenz Bauer --- btf/core.go | 17 ++++++++-------- btf/core_reloc_test.go | 2 ++ btf/core_test.go | 4 ++-- btf/ext_info.go | 18 ++++++++--------- btf/marshal.go | 5 +++++ btf/testdata/relocs-eb.elf | Bin 15536 -> 15560 bytes btf/testdata/relocs-el.elf | Bin 15536 -> 15560 bytes btf/testdata/relocs.c | 39 +++++++++++++++++-------------------- linker.go | 4 ++-- prog.go | 24 +++++++++++++++-------- 10 files changed, 62 insertions(+), 51 deletions(-) diff --git a/btf/core.go b/btf/core.go index ded7d43d4..f19d56bb2 100644 --- a/btf/core.go +++ b/btf/core.go @@ -164,7 +164,7 @@ func (k coreKind) String() string { // // Fixups are returned in the order of relos, e.g. fixup[i] is the solution // for relos[i]. -func CORERelocate(relos []*CORERelocation, target *Spec, bo binary.ByteOrder) ([]COREFixup, error) { +func CORERelocate(relos []*CORERelocation, target *Spec, bo binary.ByteOrder, typeID func(Type) (TypeID, error)) ([]COREFixup, error) { if target == nil { var err error target, _, err = kernelSpec() @@ -194,14 +194,15 @@ func CORERelocate(relos []*CORERelocation, target *Spec, bo binary.ByteOrder) ([ return nil, fmt.Errorf("%s: unexpected accessor %v", relo.kind, relo.accessor) } + id, err := typeID(relo.typ) + if err != nil { + return nil, fmt.Errorf("%s: get type id: %w", relo.kind, err) + } + result[i] = COREFixup{ - kind: relo.kind, - local: uint64(relo.id), - // NB: Using relo.id as the target here is incorrect, since - // it doesn't match the BTF we generate on the fly. This isn't - // too bad for now since there are no uses of the local type ID - // in the kernel, yet. - target: uint64(relo.id), + kind: relo.kind, + local: uint64(relo.id), + target: uint64(id), } continue } diff --git a/btf/core_reloc_test.go b/btf/core_reloc_test.go index 037d8419c..24d5540f7 100644 --- a/btf/core_reloc_test.go +++ b/btf/core_reloc_test.go @@ -30,6 +30,8 @@ func TestCORERelocationLoad(t *testing.T) { return } + testutils.SkipOnOldKernel(t, "4.18", "BTF") + for _, progSpec := range spec.Programs { t.Run(progSpec.Name, func(t *testing.T) { if _, err := fh.Seek(0, io.SeekStart); err != nil { diff --git a/btf/core_test.go b/btf/core_test.go index 75420ddca..fab618395 100644 --- a/btf/core_test.go +++ b/btf/core_test.go @@ -590,7 +590,7 @@ func TestCORERelocation(t *testing.T) { relos = append(relos, reloInfo.relo) } - fixups, err := CORERelocate(relos, spec, spec.byteOrder) + fixups, err := CORERelocate(relos, spec, spec.byteOrder, spec.TypeID) if want := errs[name]; want != nil { if !errors.Is(err, want) { t.Fatal("Expected", want, "got", err) @@ -737,7 +737,7 @@ func BenchmarkCORESkBuff(b *testing.B) { b.ReportAllocs() for i := 0; i < b.N; i++ { - _, err = CORERelocate([]*CORERelocation{relo}, spec, spec.byteOrder) + _, err = CORERelocate([]*CORERelocation{relo}, spec, spec.byteOrder, spec.TypeID) if err != nil { b.Fatal(err) } diff --git a/btf/ext_info.go b/btf/ext_info.go index 3eae08b28..910c07e4d 100644 --- a/btf/ext_info.go +++ b/btf/ext_info.go @@ -144,11 +144,11 @@ func AssignMetadataToInstructions( // wire format. // // Returns ErrNotSupported if the kernel doesn't support BTF-associated programs. -func MarshalExtInfos(insns asm.Instructions) (_ *Handle, funcInfos, lineInfos []byte, _ error) { +func MarshalExtInfos(insns asm.Instructions, b *Builder) (funcInfos, lineInfos []byte, _ error) { // Bail out early if the kernel doesn't support Func(Proto). If this is the // case, func_info will also be unsupported. if err := haveProgBTF(); err != nil { - return nil, nil, nil, err + return nil, nil, err } iter := insns.Iterate() @@ -160,10 +160,9 @@ func MarshalExtInfos(insns asm.Instructions) (_ *Handle, funcInfos, lineInfos [] } } - return nil, nil, nil, nil + return nil, nil, nil marshal: - var b Builder var fiBuf, liBuf bytes.Buffer for { if fn := FuncMetadata(iter.Ins); fn != nil { @@ -171,8 +170,8 @@ marshal: fn: fn, offset: iter.Offset, } - if err := fi.marshal(&fiBuf, &b); err != nil { - return nil, nil, nil, fmt.Errorf("write func info: %w", err) + if err := fi.marshal(&fiBuf, b); err != nil { + return nil, nil, fmt.Errorf("write func info: %w", err) } } @@ -181,8 +180,8 @@ marshal: line: line, offset: iter.Offset, } - if err := li.marshal(&liBuf, &b); err != nil { - return nil, nil, nil, fmt.Errorf("write line info: %w", err) + if err := li.marshal(&liBuf, b); err != nil { + return nil, nil, fmt.Errorf("write line info: %w", err) } } @@ -191,8 +190,7 @@ marshal: } } - handle, err := NewHandle(&b) - return handle, fiBuf.Bytes(), liBuf.Bytes(), err + return fiBuf.Bytes(), liBuf.Bytes(), nil } // btfExtHeader is found at the start of the .BTF.ext section. diff --git a/btf/marshal.go b/btf/marshal.go index 0d093c665..cdaf08a6c 100644 --- a/btf/marshal.go +++ b/btf/marshal.go @@ -93,6 +93,11 @@ func NewBuilder(types []Type) (*Builder, error) { return b, nil } +// Empty returns true if [Add] has not been invoked on the builder. +func (b *Builder) Empty() bool { + return len(b.types) == 0 +} + // Add a Type and allocate a stable ID for it. // // Adding the identical Type multiple times is valid and will return the same ID. diff --git a/btf/testdata/relocs-eb.elf b/btf/testdata/relocs-eb.elf index 7af281b3049b62b0c921923762eed9263823f566..4fce1add7910a12ec5c00aa1f31290dec0fa255b 100644 GIT binary patch delta 3948 zcmZXXe{5S<701tg*FRodr*a0BleNX}XjcaYacN7O{ve6iXao~=%T@)ch)nE<$J#B7 z!rW2j{82{4U(Qb1JXTQt7*d2PEm|fu(u$TphU!g4ibf|q7$Qhv3)-ZaQbefugYS9o zyy{}E^zM6~bMCqKoO{lF&z?WsJY63!V>8998JHQ%nc_?(XLij@=gjA3=5l7wOfzTp z&aCCk=h-(oGsp$>B_2aR#1-`WcpCkFoo&>} z+C}Mz4skUU_6e!*%RCnfKjsL(!mUu)?FhfhzRjDh+;2ZSbQn_`M@K&uK+{Ar|ItKYIkjK=z%FD1m4XNyC zBz+RR!QmgMwGX)uxv$n|I3LfNA95+4>v^hUr=Q_UJhzEA{clv~z&So1&+)7Aw0V}B z@tk>{*U_jgrF%H&`~$+^Zw zX#b&FNr{}0C?(f<0@{B%T1jlA{TJ7vT~}=ewn=C+y3POQrPP4A!R^#xvv*-+!%N0I z#qD&qZ)Y00z`$FHk}<3%&!~f>&-w0b_o`~Q5~VVHXZKMrbqhDTcXxkL728p*C%M%< z(ETfw?1W@>;o}?M_hR=y_UI|Tk=YqOi#CE;=9-w?enjB&yEkBFMWjgSrA3(LZb%14Q=3b&LW!K3iH@=vHn??PaDRq!g& zif~E!k3_4&Et!JwqVgSN?hsy6J__G?cXIeu>N_;WgzZ8L5e&@(@65mCP04-cTR+$e;#l*e4ZiCL=`< zV!MDZCiK@Ci+ex6KF1GCC+kqK&GQTZb>ZLfw2o1q}# zlW~gx(x90&+$05O$crJI-~a{R)=-`pCGSodsgWffCvOanMyX0Ld3Ot!aABUrugNP5 zkK?L{;63v05kWN^klcv65^gB(ChvaXMdf4URfJp0Rq{>iSN&_`o#NMW zQf%H?L=YVLPeCaS4)_SJSDx_@@Gi1a%{0=%nhO6LWb>k*QhmgAZ@}dYFig-l%ZL)hrKiR=k$~VYL3ZnDvhm2xth6B3tWF;rj z0gu@8RX<8ra^$H4T@jC{{z0;mGH;@TtI9tndtCIoBV8BBPDrtNb2{J(S;?ulq}(Pe zIrUm0r;23H3AdGx;gtZk>R{?gvgd{Ks(*p(tZ+&B64@7p%gXPNy-*WDB@}G%$j%E- zDSwje>%tA?yT~?$=anBKdqudZ{508R;T7dylD#UtuG}Om$2FEwzDD-G6%iCdL3#_> zRpF74(FYALq9EruZuUBg_5Z#{PhbkzrI#=c`kCf~$8xO#EH-j{Epv^*~1dj-%6 zxP-qRPJi$O91%cnv%aWNJ;P$K=|&Eu}Pu+ab-AM3k+BVMIG>pvUnU# z2x~i`ypFqYRaq890Jg3y3kuIE%Ywp7%Ceqtiw=hi$buqh>ww@78BQ#ABXB?_M2qFo zi9<3WS}bx{CPYgg;Y@$lEODW~xNy9Gcg7rBs1GGQGs=zqgXRP;?;kd8&KwvvWiF#1 J=lX&Ce*sqF<`@6~ delta 3960 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 L%02Sp=DPm@sEgw- delta 4002 zcmZ9Oe{7Xk8OP6g-`?Ka(%ZDK+8@we>RNU?wzNuTTWM+8z@Z7VLx`OLDVZcyV0MaH zaBxwx1kFfVpNz3=(-J{2S)^G_RwE|-VHNF&jTu|#SXPn|%f{BmY_3z5`2C*yyysr} z!a48zd7kr}^E}Tv&$+#LVD!LH+BOe2F1Mc>-k7qj!@EmZuINr3H0~LY4rEY1o{nf4gE%m1u6RlX+Zx)*%;iB+_5xe z_`HPnCHbC{RC~#0Iqf9NyyQW->?BDqc}Qa69d?H_hO65ttX*ooZVSGia+F=6AKx!Q z%@Gy$^G?H+zbVJU%Jy$L>AhaM$MG7^d-0XCZuath@+Pbwb)#2%>9-v>dLF=6&U%%X zKPLASRJMP|jjr?3?>f%q=KEk;m*Bn4u5fR9{sTD#>p>^2^wI;4D?A?r)4IUPm%2Bt ze<+t={kW4Rz4VadC7ut1X`OKLgnQFEBek(gdqnPyrQ$yVBh&J1EF}kH#dXKQ6}ApN zY|)-ZtFXCvPRQw4%043#=%15o=%1HZVaonO8VXb8zr^Tmw#e-htw&^AVV6BAPoe*t zTt+`B74cU4vTTkw*-LUL{($|vOvJnFl*AGb*vqmx(PdwiV~JM#noJ~`s;4naE{0AY z!#^ciR9XFoYP0!i^^sqZPH5j$Ene{IGkm$2W@R6=*Gb3@{v*QN{=Xy7L;LP6+6GY8 z_J&-7_WfJ5x$MlzC(wSN+N@XA-m4Ggp5n^t|EM;*E6aRDAIT1A7jDrez4pIy4BG#x zwhZrWHg5Q4o^Q$@i<|5x@?PJHgM(SIO$~ zI(ewPKE7|){zv-LyX9(G&Dco!UyEe#@|N{`!fbkBVR$**mi2&WmZSY6yS(Gu(YIxn zaLkmSk*mwonOBUd0#Lwu32-FZlzCc%E5`IHPmpJ_<2Zhf{I)SC@Fq7Sq~L}z^Om4vf%C*>npv{_D<#pr@ z^0nHU%p=^L?bdLYcs}@Wi4530XWii<|CS~ra6$EdCZDo?6J95uwPus*|4n|unm*-H z)Il(coG90me`ho1s0vys7)O$nd&uXl8CBj(zF^Ho<)4uMgrq4SCtpO2%IC;0BZHd6 zN%FMyn|PgkC4-1`KoEmq1`#ROk>9qaNBMs8tTp}0JIOb4yF5sq$0n%$X)=xilIAk{ zd-6hV*Iy-PZXzNbFh>FY!AWO;K-_~h9lNb63tRzZe?hbIGz!Y}1in5V1_xUMzf}jx zI4W%z)_``3yghLBlA+)d1$}|vn-9s~2>e#mphAOzz!yv>c|RQ033rkQ1E2cCQy;qPk6e|&Jn7JM<2#>wls8a+cW90* z;vwao)HjDd4&{tLQ-?XACCmk)yr2_2L+%LO4MGPZ?$*H0Q{Nq$fkk{o`6~5W;lM47 zQj3m2ya)q&Ltpt3C$wWEc5tXjUr!nEXO$+LV7q9t};8@&#}v z7!M7cauZzVfb-Zx<>DpasnDEIzMK3?XfTHx{~&o98C2d!z7m=lw^M>KF%h+p%?KT}_)T}y#Ev*_pREy_0(xQnzD z_AAhE3=9%z_;+EU8GHZJFIu}tPS*dWjz5k(^&G((|0)<6an~xXC*`LNO_@nZ5r;ds zlyVf=;9PNj&P!%NwcuTa#u?k#;aQ2s&kp6Za}f7iym|eJY41=vR&= z7|hdif)TWGw8#No>Jd{vg;tTLpHb%g)F%*F%`9N<+G8DQtlraT6^ zOP%`2zITy*e;(6*DBm9IyWjHs2}be^pf;m<2KY2n=<-tNE_rg~z>Mmn0Opmcr+pRD z5M_+(yT1h@0S9ctfczBpDn}CxfTN7i{wO%#fe~;tANAvT_T(ur|He%gvtaNstAaI{ zg=~-~4tQ9(O8KC2v+}dbo0KsjO--NjTgroZdImV8yrvlOQ*c%VT#$T0nG2F}D>#R^ zAQ?p+MF2uJP|r!zH!aiKx1>6T{m{JJs#M! c{AO*d?UAc%yX>^ob#&P_*@eDaPIlb+e=+IRVgLXD diff --git a/btf/testdata/relocs.c b/btf/testdata/relocs.c index 766dc8158..92f83400f 100644 --- a/btf/testdata/relocs.c +++ b/btf/testdata/relocs.c @@ -29,13 +29,6 @@ union u { typedef union u u_t; -#define local_id_zero(expr) \ - ({ \ - if (bpf_core_type_id_local(expr) != 0) { \ - return __LINE__; \ - } \ - }) - #define local_id_not_zero(expr) \ ({ \ if (bpf_core_type_id_local(expr) == 0) { \ @@ -43,9 +36,9 @@ typedef union u u_t; } \ }) -#define target_and_local_id_match(expr) \ +#define target_and_local_id_dont_match(expr) \ ({ \ - if (bpf_core_type_id_kernel(expr) != bpf_core_type_id_local(expr)) { \ + if (bpf_core_type_id_kernel(expr) == bpf_core_type_id_local(expr)) { \ return __LINE__; \ } \ }) @@ -69,19 +62,23 @@ __section("socket_filter/type_ids") int type_ids() { local_id_not_zero(const u_t); local_id_not_zero(volatile u_t); + // In this context, target is the BTF generated by clang. local is + // generated on the fly by the library. There is a low chance that + // the order on both is the same, so we assert this to make sure that + // CO-RE uses the IDs from the dynamic BTF. // Qualifiers on types crash clang. - target_and_local_id_match(struct s); - target_and_local_id_match(s_t); - // target_and_local_id_match(const s_t); - // target_and_local_id_match(volatile s_t); - target_and_local_id_match(enum e); - target_and_local_id_match(e_t); - // target_and_local_id_match(const e_t); - // target_and_local_id_match(volatile e_t); - target_and_local_id_match(union u); - target_and_local_id_match(u_t); - // target_and_local_id_match(const u_t); - // target_and_local_id_match(volatile u_t); + target_and_local_id_dont_match(struct s); + target_and_local_id_dont_match(s_t); + // target_and_local_id_dont_match(const s_t); + // target_and_local_id_dont_match(volatile s_t); + target_and_local_id_dont_match(enum e); + target_and_local_id_dont_match(e_t); + // target_and_local_id_dont_match(const e_t); + // target_and_local_id_dont_match(volatile e_t); + target_and_local_id_dont_match(union u); + target_and_local_id_dont_match(u_t); + // target_and_local_id_dont_match(const u_t); + // target_and_local_id_dont_match(volatile u_t); return 0; } diff --git a/linker.go b/linker.go index b653b805e..38cc12536 100644 --- a/linker.go +++ b/linker.go @@ -106,7 +106,7 @@ func hasFunctionReferences(insns asm.Instructions) bool { // // Passing a nil target will relocate against the running kernel. insns are // modified in place. -func applyRelocations(insns asm.Instructions, target *btf.Spec, bo binary.ByteOrder) error { +func applyRelocations(insns asm.Instructions, target *btf.Spec, bo binary.ByteOrder, b *btf.Builder) error { var relos []*btf.CORERelocation var reloInsns []*asm.Instruction iter := insns.Iterate() @@ -125,7 +125,7 @@ func applyRelocations(insns asm.Instructions, target *btf.Spec, bo binary.ByteOr bo = internal.NativeEndian } - fixups, err := btf.CORERelocate(relos, target, bo) + fixups, err := btf.CORERelocate(relos, target, bo, b.Add) if err != nil { return err } diff --git a/prog.go b/prog.go index 6d46a0422..0a58b9332 100644 --- a/prog.go +++ b/prog.go @@ -242,15 +242,12 @@ func newProgramWithOptions(spec *ProgramSpec, opts ProgramOptions) (*Program, er insns := make(asm.Instructions, len(spec.Instructions)) copy(insns, spec.Instructions) - handle, fib, lib, err := btf.MarshalExtInfos(insns) + var b btf.Builder + fib, lib, err := btf.MarshalExtInfos(insns, &b) if err != nil && !errors.Is(err, btf.ErrNotSupported) { - return nil, fmt.Errorf("load ext_infos: %w", err) + return nil, fmt.Errorf("marshal ext_infos: %w", err) } - if handle != nil { - defer handle.Close() - - attr.ProgBtfFd = uint32(handle.FD()) - + if len(fib) > 0 || len(lib) > 0 { attr.FuncInfoRecSize = btf.FuncInfoSize attr.FuncInfoCnt = uint32(len(fib)) / btf.FuncInfoSize attr.FuncInfo = sys.NewSlicePointer(fib) @@ -260,10 +257,21 @@ func newProgramWithOptions(spec *ProgramSpec, opts ProgramOptions) (*Program, er attr.LineInfo = sys.NewSlicePointer(lib) } - if err := applyRelocations(insns, opts.KernelTypes, spec.ByteOrder); err != nil { + if err := applyRelocations(insns, opts.KernelTypes, spec.ByteOrder, &b); err != nil { return nil, fmt.Errorf("apply CO-RE relocations: %w", err) } + var handle *btf.Handle + if !b.Empty() { + handle, err = btf.NewHandle(&b) + if err != nil { + return nil, fmt.Errorf("load BTF: %w", err) + } + defer handle.Close() + + attr.ProgBtfFd = uint32(handle.FD()) + } + kconfig, err := resolveKconfigReferences(insns) if err != nil { return nil, fmt.Errorf("resolve .kconfig: %w", err)