Go binary cataloging fails between v0.103.1 and v0.105.0
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-releaseor 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"
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.
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.
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?
This has been fixed (I'm not sure by which commit) in version 1.0.1. Closing.