From 84164c48c97ed69b55f480a43e97ca612890484b Mon Sep 17 00:00:00 2001 From: Lorenz Bauer Date: Fri, 27 Nov 2020 11:20:45 +0000 Subject: [PATCH] internal: add safe ELF file wrapper Fuzzing the ELF loader isn't very succesful since it keeps crashing in debug/elf. Most of the time the culprit is a call to elf.Section.Data(). This method allocates a buffer with a size taken from the ELF, which can lead to outlandishly large allocations. It's not clear how to validate elf.Section.Size since the code that creates the section doesn't know the total length of the ELF. Instead, add a wrapper that catches panics due to ELF parsing, and turns them into errors. This isn't a fool proof solution since the runtime can still kill the process due to an OOM, but hopefully we will still crash less overall. See https://github.com/golang/go/issues/33121 --- btf.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/btf.go b/btf.go index 51f84d0..57f2b7d 100644 --- a/btf.go +++ b/btf.go @@ -53,7 +53,7 @@ type btfHeader struct { // // Returns a nil Spec and no error if no BTF was present. func LoadSpecFromReader(rd io.ReaderAt) (*Spec, error) { - file, err := elf.NewFile(rd) + file, err := internal.NewSafeELFFile(rd) if err != nil { return nil, err } @@ -109,7 +109,7 @@ func LoadSpecFromReader(rd io.ReaderAt) (*Spec, error) { return spec, nil } -func findBtfSections(file *elf.File) (*elf.Section, *elf.Section, map[string]uint32, error) { +func findBtfSections(file *internal.SafeELFFile) (*elf.Section, *elf.Section, map[string]uint32, error) { var ( btfSection *elf.Section btfExtSection *elf.Section @@ -138,7 +138,7 @@ func findBtfSections(file *elf.File) (*elf.Section, *elf.Section, map[string]uin } func loadSpecFromVmlinux(rd io.ReaderAt) (*Spec, error) { - file, err := elf.NewFile(rd) + file, err := internal.NewSafeELFFile(rd) if err != nil { return nil, err }