Skip to content

debug/dwarf: DW_TAG_reference_type causes a panic when encountered by debug/dwarf #29601

Closed
@ilch1

Description

@ilch1

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

$ go version
go version go1.11 darwin/amd64

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
GOARCH="amd64"
GOBIN=""
GOCACHE="/Users/ilya/Library/Caches/go-build"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOOS="darwin"
GOPATH="/Users/ilya/volx/go"
GOPROXY=""
GORACE=""
GOROOT="/usr/local/go"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/darwin_amd64"
GCCGO="gccgo"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/nk/ft8bd8fx68n2gv_l5ft8yhvw0000gn/T/go-build278199837=/tmp/go-build -gno-record-gcc-switches -fno-common"

What did you do?

Tried to parse the dwarf information of an elf file.

Compile the following:

//g++ -g test.cc 
int i = 3;
int &bad = i;

int main() {
        return 0;
}

Then try to parse the DWARF information from the compiled ELF file, using:

//crash.go
package main

import (
        "debug/dwarf"
        "debug/elf"
        "fmt"
        "os"
)

func main() {
        elf_file, err := elf.Open(os.Args[1])
        defer elf_file.Close()
        if err != nil {
                fmt.Fprintf(os.Stderr, "open failed %v", err)
                os.Exit(1)
        }
        data, err := elf_file.DWARF()
        r := data.Reader()
        for {
                e, err := r.Next()
                if err != nil || e == nil {
                        break
                }
                if e.Tag == dwarf.TagVariable {
                        genAttr := e.Val(dwarf.AttrType)
                        typOff, ok := genAttr.(dwarf.Offset)
                        if !ok {
                                fmt.Fprint(os.Stderr, "Bad type")
                                os.Exit(1)
                        }
                        _, err := data.Type(typOff)
                        if err != nil {
                                fmt.Fprint(os.Stderr, "err in type decode: %v\n", err)
                                os.Exit(1)
                        }
                }
        }
}

Run:
<prog> a.out

What did you expect to see?

data.Type() extracting the type of each variable

What did you see instead?

$ ./crash ../a.out
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x18 pc=0x10a182e]

goroutine 1 [running]:
debug/dwarf.(*Data).readType(0xc0000ba000, 0x10fd3ae, 0x4, 0x1118540, 0xc0000c0240, 0xc00000005c, 0xc000066c00, 0xc00006e0e0, 0x0, 0x0, ...)
        /usr/local/go/src/debug/dwarf/type.go:703 +0xe1e
debug/dwarf.(*Data).readType.func3(0xc000066db0, 0xc000066c00, 0xc000000062)
        /usr/local/go/src/debug/dwarf/type.go:365 +0x1a0
debug/dwarf.(*Data).readType(0xc0000ba000, 0x10fd3ae, 0x4, 0x1118540, 0xc0000c01b0, 0xc000000062, 0xc000066c00, 0xc00006e0e0, 0x0, 0x0, ...)
        /usr/local/go/src/debug/dwarf/type.go:576 +0x260a
debug/dwarf.(*Data).Type(0xc0000ba000, 0xc000000062, 0x10d1540, 0xc00007f020, 0x0, 0x0)
        /usr/local/go/src/debug/dwarf/type.go:278 +0x85
main.main()
        /Users/ilya/test/crash/example.go:31 +0x1c9

It appears that the switch e.Tag { in debug/dwarf/type.go:readType() does not handle some dwarf tag types. This results in no error generated and use of a uninitialized global variable (that was not initialized in the switch statements), which ultimately causes the nil dereference.

Metadata

Metadata

Assignees

No one assigned

    Labels

    FrozenDueToAgeNeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions