From 28ccfa094bd633f0015f4d0c668341e2f24b588f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Mart=C3=AD?= Date: Sun, 9 Feb 2025 13:27:49 +0000 Subject: [PATCH] internal/linker: add Go patches rebased on go1.24rc3 See https://github.com/burrowers/go-patches/pull/8. --- .../go1.24/0001-add-custom-magic-value.patch | 47 ++++++++++ ...dd-unexported-function-name-removing.patch | 85 +++++++++++++++++++ .../go1.24/0003-add-entryOff-encryption.patch | 43 ++++++++++ 3 files changed, 175 insertions(+) create mode 100644 internal/linker/patches/go1.24/0001-add-custom-magic-value.patch create mode 100644 internal/linker/patches/go1.24/0002-add-unexported-function-name-removing.patch create mode 100644 internal/linker/patches/go1.24/0003-add-entryOff-encryption.patch diff --git a/internal/linker/patches/go1.24/0001-add-custom-magic-value.patch b/internal/linker/patches/go1.24/0001-add-custom-magic-value.patch new file mode 100644 index 0000000..1ce6dad --- /dev/null +++ b/internal/linker/patches/go1.24/0001-add-custom-magic-value.patch @@ -0,0 +1,47 @@ +From 1eb3d02d33155831067ca7db2c6517108c4305ae Mon Sep 17 00:00:00 2001 +From: pagran +Date: Mon, 9 Jan 2023 13:30:00 +0100 +Subject: [PATCH 1/3] add custom magic value + +--- + cmd/link/internal/ld/pcln.go | 17 +++++++++++++++++ + 1 file changed, 17 insertions(+) + +diff --git a/cmd/link/internal/ld/pcln.go b/cmd/link/internal/ld/pcln.go +index ea08fd3d31..7bae9f18c5 100644 +--- a/cmd/link/internal/ld/pcln.go ++++ b/cmd/link/internal/ld/pcln.go +@@ -4,6 +4,10 @@ + + package ld + ++import ( ++ "os" ++) ++ + import ( + "cmd/internal/goobj" + "cmd/internal/objabi" +@@ -262,6 +266,19 @@ func (state *pclntab) generatePCHeader(ctxt *Link) { + if off != size { + panic(fmt.Sprintf("pcHeader size: %d != %d", off, size)) + } ++ ++ // Use garble prefix in variable names to minimize collision risk ++ garbleMagicStr := os.Getenv("GARBLE_LINK_MAGIC") ++ if garbleMagicStr == "" { ++ panic("[garble] magic value must be set") ++ } ++ var garbleMagicVal uint32 ++ // Use fmt package instead of strconv to avoid importing a new package ++ if _, err := fmt.Sscan(garbleMagicStr, &garbleMagicVal); err != nil { ++ panic(fmt.Errorf("[garble] invalid magic value %s: %v", garbleMagicStr, err)) ++ } ++ ++ header.SetUint32(ctxt.Arch, 0, garbleMagicVal) + } + + state.pcheader = state.addGeneratedSym(ctxt, "runtime.pcheader", size, writeHeader) +-- +2.48.1 + diff --git a/internal/linker/patches/go1.24/0002-add-unexported-function-name-removing.patch b/internal/linker/patches/go1.24/0002-add-unexported-function-name-removing.patch new file mode 100644 index 0000000..6839c27 --- /dev/null +++ b/internal/linker/patches/go1.24/0002-add-unexported-function-name-removing.patch @@ -0,0 +1,85 @@ +From 2a691e00bc659059133cd5604c7a099981cf684c Mon Sep 17 00:00:00 2001 +From: pagran +Date: Mon, 9 Jan 2023 13:30:36 +0100 +Subject: [PATCH 2/3] add unexported function name removing + +--- + cmd/link/internal/ld/pcln.go | 43 +++++++++++++++++++++++++++++++++++- + 1 file changed, 42 insertions(+), 1 deletion(-) + +diff --git a/cmd/link/internal/ld/pcln.go b/cmd/link/internal/ld/pcln.go +index 7bae9f18c5..b497573b15 100644 +--- a/cmd/link/internal/ld/pcln.go ++++ b/cmd/link/internal/ld/pcln.go +@@ -8,6 +8,10 @@ import ( + "os" + ) + ++import ( ++ "unicode" ++) ++ + import ( + "cmd/internal/goobj" + "cmd/internal/objabi" +@@ -318,19 +322,56 @@ func walkFuncs(ctxt *Link, funcs []loader.Sym, f func(loader.Sym)) { + func (state *pclntab) generateFuncnametab(ctxt *Link, funcs []loader.Sym) map[loader.Sym]uint32 { + nameOffsets := make(map[loader.Sym]uint32, state.nfunc) + ++ garbleTiny := os.Getenv("GARBLE_LINK_TINY") == "true" ++ + // Write the null terminated strings. + writeFuncNameTab := func(ctxt *Link, s loader.Sym) { + symtab := ctxt.loader.MakeSymbolUpdater(s) ++ if garbleTiny { ++ symtab.AddStringAt(0, "") ++ } ++ + for s, off := range nameOffsets { ++ if garbleTiny && off == 0 { ++ continue ++ } + symtab.AddCStringAt(int64(off), ctxt.loader.SymName(s)) + } + } + + // Loop through the CUs, and calculate the size needed. + var size int64 ++ ++ if garbleTiny { ++ size = 1 // first byte is reserved for empty string used for all non-exportable method names ++ } ++ // Kinds of SymNames found in the wild: ++ // ++ // * reflect.Value.CanAddr ++ // * reflect.(*Value).String ++ // * reflect.w6cEoKc ++ // * internal/abi.(*RegArgs).IntRegArgAddr ++ // * type:.eq.runtime.special ++ // * runtime/internal/atomic.(*Pointer[go.shape.string]).Store ++ // ++ // Checking whether the first rune after the last dot is uppercase seems enough. ++ isExported := func(name string) bool { ++ for _, r := range name[strings.LastIndexByte(name, '.')+1:] { ++ return unicode.IsUpper(r) ++ } ++ return false ++ } ++ + walkFuncs(ctxt, funcs, func(s loader.Sym) { ++ name := ctxt.loader.SymName(s) ++ ++ if garbleTiny && !isExported(name) { ++ nameOffsets[s] = 0 // redirect name to empty string ++ return ++ } ++ + nameOffsets[s] = uint32(size) +- size += int64(len(ctxt.loader.SymName(s)) + 1) // NULL terminate ++ size += int64(len(name) + 1) // NULL terminate + }) + + state.funcnametab = state.addGeneratedSym(ctxt, "runtime.funcnametab", size, writeFuncNameTab) +-- +2.48.1 + diff --git a/internal/linker/patches/go1.24/0003-add-entryOff-encryption.patch b/internal/linker/patches/go1.24/0003-add-entryOff-encryption.patch new file mode 100644 index 0000000..b60a2b3 --- /dev/null +++ b/internal/linker/patches/go1.24/0003-add-entryOff-encryption.patch @@ -0,0 +1,43 @@ +From 03342e79193875d08bf3f88154e77a453b28c076 Mon Sep 17 00:00:00 2001 +From: pagran +Date: Sat, 14 Jan 2023 21:36:16 +0100 +Subject: [PATCH 3/3] add entryOff encryption + +--- + cmd/link/internal/ld/pcln.go | 20 ++++++++++++++++++++ + 1 file changed, 20 insertions(+) + +diff --git a/cmd/link/internal/ld/pcln.go b/cmd/link/internal/ld/pcln.go +index b497573b15..f1021fcee3 100644 +--- a/cmd/link/internal/ld/pcln.go ++++ b/cmd/link/internal/ld/pcln.go +@@ -806,6 +806,26 @@ func writeFuncs(ctxt *Link, sb *loader.SymbolBuilder, funcs []loader.Sym, inlSym + sb.SetUint32(ctxt.Arch, dataoff, uint32(ldr.SymValue(fdsym)-gofuncBase)) + } + } ++ ++ // Moving next code higher is not recommended. ++ // Only at the end of the current function no edits between go versions ++ garbleEntryOffKeyStr := os.Getenv("GARBLE_LINK_ENTRYOFF_KEY") ++ if garbleEntryOffKeyStr == "" { ++ panic("[garble] entryOff key must be set") ++ } ++ var garbleEntryOffKey uint32 ++ // Use fmt package instead of strconv to avoid importing a new package ++ if _, err := fmt.Sscan(garbleEntryOffKeyStr, &garbleEntryOffKey); err != nil { ++ panic(fmt.Errorf("[garble] invalid entryOff key %s: %v", garbleEntryOffKeyStr, err)) ++ } ++ ++ garbleData := sb.Data() ++ for _, off := range startLocations { ++ entryOff := ctxt.Arch.ByteOrder.Uint32(garbleData[off:]) ++ nameOff := ctxt.Arch.ByteOrder.Uint32(garbleData[off+4:]) ++ ++ sb.SetUint32(ctxt.Arch, int64(off), entryOff^(nameOff*garbleEntryOffKey)) ++ } + } + + // pclntab initializes the pclntab symbol with +-- +2.48.1 +