syft icon indicating copy to clipboard operation
syft copied to clipboard

Go binary cataloging fails between v0.103.1 and v0.105.0

Open cinerea0 opened this issue 1 year ago • 3 comments

What happened: When running syft version 0.105.0 against a dynamically linked go binary on my system, I do not get any output. Output from syft /usr/bin/dnscrypt-proxy on version 0.105.0:

 ✔ Indexed file system                                                           /usr/bin
 ✔ Cataloged contents              e73f7e76bbf3a6969e03e29254b6b4893f7fffa31ae0113793b832  
   ├── ✔ Packages                        [0 packages]  
   └── ✔ Executables                     [0 executables]  
No packages discovered

What you expected to happen: I expected the same output that I get from version 0.103.1:

 ✔ Indexed file system                                                           /usr/bin
 ✔ Cataloged contents              e73f7e76bbf3a6969e03e29254b6b4893f7fffa31ae0113793b832  
   └── ✔ Packages                        [27 packages]  
NAME                                     VERSION                             TYPE      
github.com/BurntSushi/toml               v1.3.2                              go-module  
github.com/VividCortex/ewma              v1.2.0                              go-module  
github.com/coreos/go-systemd             v0.0.0-20191104093116-d3cd4ed1dbcf  go-module  
github.com/dchest/safefile               v0.0.0-20151022103144-855e8d98f185  go-module  
github.com/dnscrypt/dnscrypt-proxy       (devel)                             go-module  
github.com/hashicorp/go-immutable-radix  v1.3.1                              go-module  
github.com/hashicorp/go-syslog           v1.0.0                              go-module  
github.com/hashicorp/golang-lru          v1.0.2                              go-module  
github.com/jedisct1/dlog                 v0.0.0-20230811132706-443b333ff1b3  go-module  
github.com/jedisct1/go-clocksmith        v0.0.0-20230211133011-392c1afea73e  go-module  
github.com/jedisct1/go-dnsstamps         v0.0.0-20230211133001-124a632de565  go-module  
github.com/jedisct1/go-hpke-compact      v0.0.0-20230811132953-4ee502b61f80  go-module  
github.com/jedisct1/go-minisign          v0.0.0-20230811132847-661be99b8267  go-module  
github.com/jedisct1/xsecretbox           v0.0.0-20230811132812-b950633f9f1f  go-module  
github.com/k-sone/critbitgo              v1.4.0                              go-module  
github.com/kardianos/service             v1.2.2                              go-module  
github.com/miekg/dns                     v1.1.55                             go-module  
github.com/quic-go/qpack                 v0.4.0                              go-module  
github.com/quic-go/qtls-go1-20           v0.3.1                              go-module  
github.com/quic-go/quic-go               v0.37.4                             go-module  
golang.org/x/crypto                      v0.12.0                             go-module  
golang.org/x/exp                         v0.0.0-20221205204356-47842c84f3db  go-module  
golang.org/x/net                         v0.14.0                             go-module  
golang.org/x/sys                         v0.11.0                             go-module  
golang.org/x/text                        v0.12.0                             go-module  
gopkg.in/natefinch/lumberjack.v2         v2.2.1                              go-module  
stdlib                                   go1.20.7                            go-module

Steps to reproduce the issue: Run syft version 0.105.0 against a dynamically linked go executable.

Anything else we need to know?: Output of file /usr/bin/dnscrypt-proxy:

/usr/bin/dnscrypt-proxy: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, Go BuildID=DZrNTr2Q6PjaoJYVBDfF/pHsT1M_2hCSt5UGcB7Yh/aUqUnylIpyNsY6lrYJpk/fgvqN_Iti3RjinPDl6eJ, stripped

Environment:

  • Output of syft version:
Application: syft
Version:    [not provided]
BuildDate:  [not provided]
GitCommit:  [not provided]
GitDescription: [not provided]
Platform:   linux/amd64
GoVersion:  go1.21.5
Compiler:   gc

(This was the same for both releases; Void's packaging system does not seem to set these values. Maybe someone could tell me what needs to be present in the build environment for this to work?)

  • OS (e.g: cat /etc/os-release or similar):
NAME="Void"
ID="void"
PRETTY_NAME="Void Linux"
HOME_URL="https://voidlinux.org/"
DOCUMENTATION_URL="https://docs.voidlinux.org/"
LOGO="void-logo"
ANSI_COLOR="0;38;2;71;128;97"

DISTRIB_ID="void"

cinerea0 avatar Feb 15 '24 19:02 cinerea0

Hi @cinerea0. Syft reads the include go module information in go binaries, but this needs to be put in the binary by the go build tools or it won't work. Downloading a binary from dnscrypt-proxy, syft is able to scan this just fine:

$ syft --version                            
syft 0.105.0

$ syft dnscrypt-proxy
NAME                                     VERSION                             TYPE      
github.com/BurntSushi/toml               v1.3.2                              go-module  
github.com/VividCortex/ewma              v1.2.0                              go-module  
...
stdlib                                   go1.21.0                            go-module

... but this is a statically linked binary.

$file dnscrypt-proxy 
dnscrypt-proxy: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), statically linked, Go BuildID=t9pDxZpyAYSx8RGlwgNk/UD0zl91SqHtSJLMh9U0X/FFdBldolE1XyPacVWdmC/r6EBqFnbsQIdCCjgiJHZ, stripped

Are there steps you could provide to reproduce what you're seeing? I suspect that you have a binary (the dynamically linked one) which does not contain this mod information and there are simply other binaries that do have said mod information (your scan indicates /usr/bin the directory, not the dnscrypt-proxy file). You can see what's there by running go version -m <file>.

As for the version information, these ldflags are used:

      -X main.version={{.Version}}
      -X main.gitCommit={{.Commit}}
      -X main.buildDate={{.Date}}
      -X main.gitDescription={{.Summary}}

... our release process uses goreleaser, which sets them here.

kzantow avatar Feb 15 '24 19:02 kzantow

Are there steps you could provide to reproduce what you're seeing?

The binary I'm scanning was installed by my package manager. Given you are unlikely to be using the same Linux distribution I am (Void), the next best thing would probably be me providing it directly (as long as you're okay with downloading arbitrary binaries from strangers over the internet).

You're right that the scan indicates the entire /usr/bin directory and not just the dnscrypt-proxy file. However, using go to probe for modules shows the same components as does a scan with syft v0.103.1 (excluding stdlib):

$ go version -m /usr/bin/dnscrypt-proxy
/usr/bin/dnscrypt-proxy: go1.20.7
	path	github.com/dnscrypt/dnscrypt-proxy/dnscrypt-proxy
	mod	github.com/dnscrypt/dnscrypt-proxy	(devel)	
	dep	github.com/BurntSushi/toml	v1.3.2	
	dep	github.com/VividCortex/ewma	v1.2.0	
	dep	github.com/coreos/go-systemd	v0.0.0-20191104093116-d3cd4ed1dbcf	
	dep	github.com/dchest/safefile	v0.0.0-20151022103144-855e8d98f185	
	dep	github.com/hashicorp/go-immutable-radix	v1.3.1	
	dep	github.com/hashicorp/go-syslog	v1.0.0	
	dep	github.com/hashicorp/golang-lru	v1.0.2	
	dep	github.com/jedisct1/dlog	v0.0.0-20230811132706-443b333ff1b3	
	dep	github.com/jedisct1/go-clocksmith	v0.0.0-20230211133011-392c1afea73e	
	dep	github.com/jedisct1/go-dnsstamps	v0.0.0-20230211133001-124a632de565	
	dep	github.com/jedisct1/go-hpke-compact	v0.0.0-20230811132953-4ee502b61f80	
	dep	github.com/jedisct1/go-minisign	v0.0.0-20230811132847-661be99b8267	
	dep	github.com/jedisct1/xsecretbox	v0.0.0-20230811132812-b950633f9f1f	
	dep	github.com/k-sone/critbitgo	v1.4.0	
	dep	github.com/kardianos/service	v1.2.2	
	dep	github.com/miekg/dns	v1.1.55	
	dep	github.com/quic-go/qpack	v0.4.0	
	dep	github.com/quic-go/qtls-go1-20	v0.3.1	
	dep	github.com/quic-go/quic-go	v0.37.4	
	dep	golang.org/x/crypto	v0.12.0	
	dep	golang.org/x/exp	v0.0.0-20221205204356-47842c84f3db	
	dep	golang.org/x/net	v0.14.0	
	dep	golang.org/x/sys	v0.11.0	
	dep	golang.org/x/text	v0.12.0	
	dep	gopkg.in/natefinch/lumberjack.v2	v2.2.1	
	build	-buildmode=exe
	build	-compiler=gc
	build	CGO_ENABLED=1
	build	CGO_CFLAGS="-mtune=generic -O2 -pipe   "
	build	CGO_CPPFLAGS="   "
	build	CGO_CXXFLAGS="-mtune=generic -O2 -pipe   "
	build	CGO_LDFLAGS="   "
	build	GOARCH=amd64
	build	GOOS=linux
	build	GOAMD64=v1

As for the version information, these ldflags are used:

Thank you, I'll make sure future Void builds at least embed the version information since the release tarballs we build from don't have git information.

cinerea0 avatar Feb 20 '24 15:02 cinerea0

Ok, I made this simple Dockerfile:

FROM ghcr.io/void-linux/void-musl-full:20231230r1
RUN xbps-install -Suy xbps
RUN xbps-install -Suy dnscrypt-proxy

... in the container, tried to download and scan with syft:

# xbps-install -Suy curl
# curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | sh -s -- -b .

# ./syft --version
syft 0.105.0

# ./syft /usr/bin/dnscrypt-proxy
NAME                                     VERSION                             TYPE      
github.com/BurntSushi/toml               v1.3.2                              go-module  
...
stdlib                                   go1.21.0                            go-module

# ./syft /usr/bin
NAME                                     VERSION                             TYPE      
github.com/BurntSushi/toml               v1.3.2                              go-module  
...
stdlib                                   go1.21.0                            go-module

I also downloaded the dnscrypt-proxy binary out of the container and scanned on macOS, which worked as expected. I can't seem to figure out a way to reproduce this issue, do you have any other suggestions?

kzantow avatar Feb 20 '24 16:02 kzantow

This has been fixed (I'm not sure by which commit) in version 1.0.1. Closing.

cinerea0 avatar Mar 07 '24 14:03 cinerea0