Hi all,
I maintain two components written in Go, so time to time the components get CVE reports where vulnerable code comes from another component via static linking during build.
I was trying to figure out how to make this better, and together with Jason (in CC) got an idea about automatic versioned buildrequires for Go packages and versions would be taken from the package versions present in buildroot.
I've checked Go Fedora guidelines and saw there is %go_generate_buildrequires macro, which looked promising, but unfortunately it does not generate BuildRequires on golang and none of the BuildRequires are versioned :( .
Do you think it is possible to have such feature?
e.g. BuildRequires: golang-src >= 1.24.1-1, or BuildRequires: golang(github.com/golang/go) >= 1.24.1-1
would tell us the package is built with this golang version, and if a golang new version comes later into repos, the package will still work with new golang due '>='.
Once CVE fix comes into golang and new golang version is released, presence of the older version in buildrequires of other package will indicate the package includes vulnerable code, and it has to be rebuilt once the original package includes a fix.
I have tried to come up at least with PoC for getting golang version from buildroot and add the versioned buildrequires, but no luck so far.
Thank you in advance!
Zdenek
On Thu, Mar 20, 2025, at 10:19 AM, Zdenek Dohnal via golang wrote:
Hi all,
I maintain two components written in Go, so time to time the components get CVE reports where vulnerable code comes from another component via static linking during build.
I was trying to figure out how to make this better, and together with Jason (in CC) got an idea about automatic versioned buildrequires for Go packages and versions would be taken from the package versions present in buildroot.
I've checked Go Fedora guidelines and saw there is %go_generate_buildrequires macro, which looked promising, but unfortunately it does not generate BuildRequires on golang and none of the BuildRequires are versioned :( .
I had this issue last time too, where upstream already specifies a minimum version of a dependency to avoid a CVE and the information gets stripped out by that macro
Do you think it is possible to have such feature?
Not sure how complex this is but I would love this feature too. We have it for Python and Rust macros after all
Best regards,
* Zdenek Dohnal via golang:
Once CVE fix comes into golang and new golang version is released, presence of the older version in buildrequires of other package will indicate the package includes vulnerable code, and it has to be rebuilt once the original package includes a fix.
A different way to do this would involve a dependency generator that looks at “go version -m” output like this:
dep golang.org/x/crypto v0.32.0 dep golang.org/x/exp v0.0.0-20250103183323-7d7fa50e5329 dep golang.org/x/mod v0.22.0 dep golang.org/x/net v0.34.0 dep golang.org/x/oauth2 v0.25.0 dep golang.org/x/sync v0.10.0 dep golang.org/x/sys v0.29.0 dep golang.org/x/term v0.28.0 dep golang.org/x/text v0.21.0 dep golang.org/x/time v0.9.0
And generates the usual Provides: from that:
Provides: bundled(golang.org/x/crypto) = v0.32.0 Provides: bundled(golang.org/x/exp) = v0.0.0-20250103183323-7d7fa50e5329 Provides: bundled(golang.org/x/mod) = v0.22.0 Provides: bundled(golang.org/x/net) = v0.34.0 Provides: bundled(golang.org/x/oauth2) = v0.25.0 Provides: bundled(golang.org/x/sync) = v0.10.0 Provides: bundled(golang.org/x/sys) = v0.29.0 Provides: bundled(golang.org/x/term) = v0.28.0 Provides: bundled(golang.org/x/text) = v0.21.0 Provides: bundled(golang.org/x/time) = v0.9.0
This data might be easier to query.
Thanks, Florian
On Thu, Mar 20, 2025 at 4:22 PM Zdenek Dohnal via golang < golang@lists.fedoraproject.org> wrote:
Hi all,
I maintain two components written in Go, so time to time the components get CVE reports where vulnerable code comes from another component via static linking during build.
I was trying to figure out how to make this better, and together with Jason (in CC) got an idea about automatic versioned buildrequires for Go packages and versions would be taken from the package versions present in buildroot.
I've checked Go Fedora guidelines and saw there is %go_generate_buildrequires macro, which looked promising, but unfortunately it does not generate BuildRequires on golang and none of the BuildRequires are versioned :( .
Do you think it is possible to have such feature?
e.g. BuildRequires: golang-src >= 1.24.1-1, or BuildRequires: golang(github.com/golang/go) >= 1.24.1-1
would tell us the package is built with this golang version, and if a golang new version comes later into repos, the package will still work with new golang due '>='.
Once CVE fix comes into golang and new golang version is released, presence of the older version in buildrequires of other package will indicate the package includes vulnerable code, and it has to be rebuilt once the original package includes a fix.
I have tried to come up at least with PoC for getting golang version from buildroot and add the versioned buildrequires, but no luck so far.
I'm not really sure if I understand the problem, but hope these two things help:
First, this is not exactly what you want to do, but we have a script in the rpms/golang package to generate the provides, maybe you can draw inspiration from it: https://src.fedoraproject.org/rpms/golang/blob/rawhide/f/bundled-deps.sh
Second, regarding the %go_generate_buildrequires macro, have you tried using go2rpm (again, I checked your golang packages, and it seems you generated them years ago with an old version of go2rpm), in the most recent versions it uses go_generate_buildrequires by default. Just in case there are some issues in the way you are invoking the macro.
Thank you in advance!
Zdenek
-- Zdenek Dohnal Senior Software Engineer Red Hat, BRQ-TPBC
-- _______________________________________________ golang mailing list -- golang@lists.fedoraproject.org To unsubscribe send an email to golang-leave@lists.fedoraproject.org Fedora Code of Conduct: https://docs.fedoraproject.org/en-US/project/code-of-conduct/ List Guidelines: https://fedoraproject.org/wiki/Mailing_list_guidelines List Archives: https://lists.fedoraproject.org/archives/list/golang@lists.fedoraproject.org Do not reply to spam, report it: https://pagure.io/fedora-infrastructure/new_issue
Am 21.03.25 um 13:55 schrieb Alejandro Saez Morollon via golang:
On Thu, Mar 20, 2025 at 4:22 PM Zdenek Dohnal via golang <golang@lists.fedoraproject.org mailto:golang@lists.fedoraproject.org> wrote:
Hi all, I maintain two components written in Go, so time to time the components get CVE reports where vulnerable code comes from another component via static linking during build. I was trying to figure out how to make this better, and together with Jason (in CC) got an idea about automatic versioned buildrequires for Go packages and versions would be taken from the package versions present in buildroot. I've checked Go Fedora guidelines and saw there is %go_generate_buildrequires macro, which looked promising, but unfortunately it does not generate BuildRequires on golang and none of the BuildRequires are versioned :( . Do you think it is possible to have such feature? e.g. BuildRequires: golang-src >= 1.24.1-1, or BuildRequires: golang(github.com/golang/go <http://github.com/golang/go>) >= 1.24.1-1 would tell us the package is built with this golang version, and if a golang new version comes later into repos, the package will still work with new golang due '>='. Once CVE fix comes into golang and new golang version is released, presence of the older version in buildrequires of other package will indicate the package includes vulnerable code, and it has to be rebuilt once the original package includes a fix. I have tried to come up at least with PoC for getting golang version from buildroot and add the versioned buildrequires, but no luck so far.I'm not really sure if I understand the problem, but hope these two things help:
First, this is not exactly what you want to do, but we have a script in the rpms/golang package to generate the provides, maybe you can draw inspiration from it: https://src.fedoraproject.org/rpms/golang/blob/rawhide/f/bundled-deps.sh https://src.fedoraproject.org/rpms/golang/blob/rawhide/f/bundled-deps.sh
This applies only for builds that use the vendored approach. Already used while packaging. The trick for them is to add "%license vendor/modules.txt" to the "%files" section (activates the corresponding generator).
IIUC, this does not cover everything, right?
In the build dir, this "go list -json | jq .Imports " shows all imports.
Second, regarding the %go_generate_buildrequires macro, have you tried using go2rpm (again, I checked your golang packages, and it seems you generated them years ago with an old version of go2rpm), in the most recent versions it uses go_generate_buildrequires by default. Just in case there are some issues in the way you are invoking the macro.
Hi Florian!
Thank you for the idea!
I knew about 'go version', which would give me go version as whole, but not about the possibility to use this to see versions of used modules - great to know!
On 3/21/25 10:53, Florian Weimer wrote:
A different way to do this would involve a dependency generator that looks at “go version -m” output like this:
dep golang.org/x/crypto v0.32.0 dep golang.org/x/exp v0.0.0-20250103183323-7d7fa50e5329 dep golang.org/x/mod v0.22.0 dep golang.org/x/net v0.34.0 dep golang.org/x/oauth2 v0.25.0 dep golang.org/x/sync v0.10.0 dep golang.org/x/sys v0.29.0 dep golang.org/x/term v0.28.0 dep golang.org/x/text v0.21.0 dep golang.org/x/time v0.9.0
How did you get such output from 'go version -m'? Or is it a theoretical output? Because if I call this on my ipp-usb binary, I get this output:
$ go version -m /usr/sbin/ipp-usb /usr/sbin/ipp-usb: go1.23.7 path github.com/OpenPrinting/ipp-usb build -buildmode=pie build -compiler=gc build -ldflags=" -X github.com/OpenPrinting/ipp-usb/version.tag=0.9.30 -X github.com/OpenPrinting/ipp-usb/version=0.9.30 -B 0x457d8742863cca388e12a3c37376a7e5c1b4eebe -compressdwarf=false -linkmode=external -extldflags '-Wl,-z,relro -Wl,--as-needed -Wl,-z,pack-relative-relocs -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -Wl,--build-id=sha1 -specs=/usr/lib/rpm/redhat/redhat-package-notes '" build -tags=rpm_crashtraceback build DefaultGODEBUG=asynctimerchan=1,gotypesalias=0,httplaxcontentlength=1,httpmuxgo121=1,httpservecontentkeepheaders=1,netedns0=0,panicnil=1,tls10server=1,tls3des=1,tlskyber=0,tlsrsakex=1,tlsunsafeekm=1,winreadlinkvolume=0,winsymlink=0,x509keypairleaf=0,x509negativeserial=1 build CGO_ENABLED=1 build CGO_CFLAGS= build CGO_CPPFLAGS= build CGO_CXXFLAGS= build CGO_LDFLAGS= build GOARCH=amd64 build GOOS=linux build GOAMD64=v1
I can see go version it was built with, but not goipp go module, which is dependency of ipp-usb and is statically linked to the ipp-usb.
And generates the usual Provides: from that:
Provides: bundled(golang.org/x/crypto) = v0.32.0 Provides: bundled(golang.org/x/exp) = v0.0.0-20250103183323-7d7fa50e5329 Provides: bundled(golang.org/x/mod) = v0.22.0 Provides: bundled(golang.org/x/net) = v0.34.0 Provides: bundled(golang.org/x/oauth2) = v0.25.0 Provides: bundled(golang.org/x/sync) = v0.10.0 Provides: bundled(golang.org/x/sys) = v0.29.0 Provides: bundled(golang.org/x/term) = v0.28.0 Provides: bundled(golang.org/x/text) = v0.21.0 Provides: bundled(golang.org/x/time) = v0.9.0
This data might be easier to query.
This would be great if we always rebase the package to the version with CVE fix, however it won't cover cases if the CVE fix is backported :(
I have tried to define BuildRequires and set the version for it by getting data by rpm, but this would have to happen later in RPM build process to get the correct version present in buildroot.
Zdenek
Thanks, Florian
On Wed, Mar 26, 2025 at 2:26 PM Zdenek Dohnal via golang golang@lists.fedoraproject.org wrote:
Hi Florian!
Thank you for the idea!
I knew about 'go version', which would give me go version as whole, but not about the possibility to use this to see versions of used modules - great to know!
On 3/21/25 10:53, Florian Weimer wrote:
A different way to do this would involve a dependency generator that looks at “go version -m” output like this:
dep golang.org/x/crypto v0.32.0 dep golang.org/x/exp v0.0.0-20250103183323-7d7fa50e5329 dep golang.org/x/mod v0.22.0 dep golang.org/x/net v0.34.0 dep golang.org/x/oauth2 v0.25.0 dep golang.org/x/sync v0.10.0 dep golang.org/x/sys v0.29.0 dep golang.org/x/term v0.28.0 dep golang.org/x/text v0.21.0 dep golang.org/x/time v0.9.0How did you get such output from 'go version -m'? Or is it a theoretical output? Because if I call this on my ipp-usb binary, I get this output:
I think this information is only embedded when building in "module mode", which package builds in Fedora explicitly turn off (GO111MODULE=off).
Fabio
Hi Alejandro!
On 3/21/25 13:55, Alejandro Saez Morollon wrote:
I'm not really sure if I understand the problem, but hope these two things help:
First, this is not exactly what you want to do, but we have a script in the rpms/golang package to generate the provides, maybe you can draw inspiration from it: https://src.fedoraproject.org/rpms/golang/blob/rawhide/f/bundled-deps.sh
This would work nicely if it worked over rpms or over found buildrequires, not text list shipped with the project :( , but it is a good reference!
Second, regarding the %go_generate_buildrequires macro, have you tried using go2rpm (again, I checked your golang packages, and it seems you generated them years ago with an old version of go2rpm), in the most recent versions it uses go_generate_buildrequires by default. Just in case there are some issues in the way you are invoking the macro.
Unfortunately the macro generates buildrequires based on go.mod content, install them and not-golang-package-modules are present in srpm, but the current golang version which was bundled in is not present...
But this got me to the latest attempt (pseudocode):
for i in 'golang(github.com/OpenPrinting/goipp)' golang do ver=`rpm -q --whatprovides $i | xargs rpm -q --queryformat "%{version}-%{release}" | python3 -c 'import sys; print("{}".format(sys.stdin.read().rsplit(".", 1)[0]));'` echo "Provides: bundled($i) = $ver" done
The list for the loop might be output of commands from %go_generate_buildrequires or such + golang, so it could be generated automatically for every Go package.
Zdenek
Thank you in advance! Zdenek -- Zdenek Dohnal Senior Software Engineer Red Hat, BRQ-TPBC -- _______________________________________________ golang mailing list -- golang@lists.fedoraproject.org To unsubscribe send an email to golang-leave@lists.fedoraproject.org Fedora Code of Conduct: https://docs.fedoraproject.org/en-US/project/code-of-conduct/ List Guidelines: https://fedoraproject.org/wiki/Mailing_list_guidelines List Archives: https://lists.fedoraproject.org/archives/list/golang@lists.fedoraproject.org Do not reply to spam, report it: https://pagure.io/fedora-infrastructure/new_issue
* Zdenek Dohnal:
On 3/21/25 10:53, Florian Weimer wrote:
A different way to do this would involve a dependency generator that looks at “go version -m” output like this:
dep golang.org/x/crypto v0.32.0 dep golang.org/x/exp v0.0.0-20250103183323-7d7fa50e5329 dep golang.org/x/mod v0.22.0 dep golang.org/x/net v0.34.0 dep golang.org/x/oauth2 v0.25.0 dep golang.org/x/sync v0.10.0 dep golang.org/x/sys v0.29.0 dep golang.org/x/term v0.28.0 dep golang.org/x/text v0.21.0 dep golang.org/x/time v0.9.0
How did you get such output from 'go version -m'? Or is it a theoretical output? Because if I call this on my ipp-usb binary, I get this output:
$ go version -m /usr/sbin/ipp-usb /usr/sbin/ipp-usb: go1.23.7 path github.com/OpenPrinting/ipp-usb build -buildmode=pie build -compiler=gc build -ldflags=" -X
I was quoting from /usr/bin/podman output, I think, so it's not made up:
$ go version -m /usr/bin/podman |& head -n 5 /usr/bin/podman: go1.24.1 path github.com/containers/podman/v5/cmd/podman mod github.com/containers/podman/v5 (devel) dep dario.cat/mergo v1.0.1 dep github.com/BurntSushi/toml v1.4.0
I don't know what's different about your build, sorry.
Thanks, Florian
On 3/26/25 16:10, Florian Weimer wrote:
How did you get such output from 'go version -m'? Or is it a theoretical output? Because if I call this on my ipp-usb binary, I get this output:
$ go version -m /usr/sbin/ipp-usb /usr/sbin/ipp-usb: go1.23.7 path github.com/OpenPrinting/ipp-usb build -buildmode=pie build -compiler=gc build -ldflags=" -X
I was quoting from /usr/bin/podman output, I think, so it's not made up:
$ go version -m /usr/bin/podman |& head -n 5 /usr/bin/podman: go1.24.1 path github.com/containers/podman/v5/cmd/podman mod github.com/containers/podman/v5 (devel) dep dario.cat/mergo v1.0.1 dep github.com/BurntSushi/toml v1.4.0
I don't know what's different about your build, sorry.
Thanks, Florian
FTR it is because podman uses vendor/modules.txt which is used by script Alejandro sent in the other email.
ipp-usb does not use the file, dependencies are generated from go.mod file, and 'go version -m' does not show such deps.
Zdenek
On 3/27/25 2:46 AM, Zdenek Dohnal via golang wrote:
FTR it is because podman uses vendor/modules.txt which is used by script Alejandro sent in the other email.
It's actually because podman enables modules mode (https://src.fedoraproject.org/rpms/podman/blob/rawhide/f/podman.spec#_10). This metadata is only added to the binary in modules mode. We disable modules mode by default, because it's not compatible with the approach we use to build dependencies as separate -devel packages.
ipp-usb does not use the file, dependencies are generated from go.mod file, and 'go version -m' does not show such deps.
%go_generate_buildrequires doesn't read the go.mod file either. That's why the version constraints aren't honored. The dependencies are generated by analyzing the sources with [0] and extracting the used import paths and then generating goipath(IMPORT_PATH) dependencies which are automatically Provided by golang-*-devel packages based on the files that they contain (thanks to [1] and [2]). -devel packages are split by import paths instead of based on module boundaries and some modules may be split up into multiple packages to avoid bootstrap loops or combined into a single package when a single source repo contains multiple modules. I was not around Fedora when the the tooling was originally developed, but I believe it predates Go modules.
[0] https://pagure.io/golist [1] https://pagure.io/go-rpm-macros/blob/master/f/rpm/fileattrs/go.attr [2] https://pagure.io/go-rpm-macros/blob/master/f/bin/go-rpm-integration
golang@lists.fedoraproject.org