Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

debug/elf: Incorrectly double-decompressing ELF section #59208

Closed
brancz opened this issue Mar 23, 2023 · 7 comments
Closed

debug/elf: Incorrectly double-decompressing ELF section #59208

brancz opened this issue Mar 23, 2023 · 7 comments
Assignees
Labels
compiler/runtime Issues related to the Go compiler and/or runtime.
Milestone

Comments

@brancz
Copy link
Contributor

brancz commented Mar 23, 2023

What version of Go are you using (go version)?

$ go version
go version go1.20.1 darwin/arm64

Does this issue reproduce with the latest release?

Yes.

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
GO111MODULE=""
GOARCH="arm64"
GOBIN="/Users/brancz/bin"
GOCACHE="/Users/brancz/Library/Caches/go-build"
GOENV="/Users/brancz/Library/Application Support/go/env"
GOEXE=""
GOEXPERIMENT=""
GOFLAGS=""
GOHOSTARCH="arm64"
GOHOSTOS="darwin"
GOINSECURE=""
GOMODCACHE="/Users/brancz/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="darwin"
GOPATH="/Users/brancz"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/opt/homebrew/Cellar/go/1.20.1/libexec"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/opt/homebrew/Cellar/go/1.20.1/libexec/pkg/tool/darwin_arm64"
GOVCS=""
GOVERSION="go1.20.1"
GCCGO="gccgo"
AR="ar"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD="/Users/brancz/src/github.com/polarsignals/polarsignals/go.mod"
GOWORK=""
CGO_CFLAGS="-O2 -g"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-O2 -g"
CGO_FFLAGS="-O2 -g"
CGO_LDFLAGS="-O2 -g"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -arch arm64 -pthread -fno-caret-diagnostics -Qunused-arguments -Wl,--no-gc-sections -fmessage-length=0 -fdebug-prefix-map=/var/folders/rl/8sh8jb5s1c1fl77ztzy4zw6m0000gn/T/go-build2747742421=/tmp/go-build -gno-record-gcc-switches -fno-common"

What did you do?

Downloaded the debuginfo for liblzma5:

curl https://debuginfod.ubuntu.com/buildid/0e13b0f27b3bc79a2828c11199ce4336a348af37/debuginfo > liblzma5.debuginfo

Tried to look at the DWARF entries:

package main

import (
	"bytes"
	"debug/elf"
	"fmt"
	"io"
	"net/http"
)

func main() {
	resp, err := http.Get("https://debuginfod.ubuntu.com/buildid/0e13b0f27b3bc79a2828c11199ce4336a348af37/debuginfo")
	if err != nil {
		panic(err)
	}

	if resp.StatusCode != 200 {
		panic("unexpected status code")
	}

	content, err := io.ReadAll(resp.Body)
	if err != nil {
		panic(err)
	}

	f, err := elf.NewFile(bytes.NewReader(content))
	if err != nil {
		panic(err)
	}

	_, err = f.DWARF()
	fmt.Println("DWARF ERROR:", err)
}

And running that returns an error:

$ go run main.go
DWARF ERROR: zlib: invalid header

What did you expect to see?

No error.

What did you see instead?

An error, and I suspect I know why: debug/elf in extremely rare cases attempts to double-decompress an ELF section.

First the call to .Data() returns the decompressed section:

b, err := s.Data()

And if by pure chance the first 4 bytes of the decompressed bytes also happen to be what trigger a decompression, then the .DWARF() function will attempt to decompress the section a second time:

go/src/debug/elf/file.go

Lines 1317 to 1319 in 0aa14fc

if dlen == 0 && len(b) >= 12 && s.Flags&SHF_COMPRESSED != 0 &&
s.Flags&SHF_ALLOC == 0 &&
f.FileHeader.ByteOrder.Uint32(b[:]) == uint32(COMPRESS_ZLIB) {

cc @mengzhuo since you recently added this case

@gopherbot gopherbot added the compiler/runtime Issues related to the Go compiler and/or runtime. label Mar 23, 2023
@brancz
Copy link
Contributor Author

brancz commented Mar 23, 2023

A suggestion of how to fix this: I think all the decompression code should live in the (*section).Open function. Then there is no risk of double-decompressing.

@mengzhuo
Copy link
Contributor

mengzhuo commented Mar 24, 2023

I'll send a CL for this issue, thanks.
This file seems corrupted at .debug_loc Section:34 with [1 0 0 0 0 0 4 0 0 0 0 0 0 0 44 0], which matched COMPRESS_ZLIB (0x1 in 4 bytes little endian)

error: unexpected end of data at offset 0x503f6 while reading [0x4e299, 0x51099)

Meanwhile, a good DWARF section should contains with a list of DIEs starts with dwarf.TagCompileUnit(0x11)

@mengzhuo mengzhuo self-assigned this Mar 24, 2023
@mknyszek mknyszek added this to the Backlog milestone Mar 29, 2023
@gopherbot
Copy link

Change https://go.dev/cl/480895 mentions this issue: debug/elf: avoid decompress of section twice

@brancz
Copy link
Contributor Author

brancz commented Apr 13, 2023

Any chance this will be backported to a 1.20 patch release?

@ianlancetaylor
Copy link
Contributor

@brancz Just to be sure, can you confirm that the problem you originally reported is fixed on HEAD? Thanks.

@brancz
Copy link
Contributor Author

brancz commented Apr 4, 2024

Sorry for the very late reply, but I can confirm that this has been fixed since the linked change landed.

@lucab
Copy link
Contributor

lucab commented Apr 5, 2024

For future reference, this was the amd64 debuginfo for Ubuntu xz-utils 5.2.4-1ubuntu1.1 (launchpad entry).
Auto-built on 2022-04-08 as part of liblzma5-dbgsym_5.2.4-1ubuntu1.1_amd64.ddeb in https://launchpad.net/~ubuntu-security-proposed/+archive/ubuntu/ppa/+build/23531947.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
compiler/runtime Issues related to the Go compiler and/or runtime.
Projects
None yet
Development

No branches or pull requests

6 participants