Add support for scanning RPM files (#917)

This commit is contained in:
Keith Zantow 2022-09-09 14:56:37 -04:00 committed by GitHub
parent 7f09eebdde
commit ba73ab362a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 53 additions and 46 deletions

4
go.mod
View file

@ -11,7 +11,7 @@ require (
github.com/anchore/go-version v1.2.2-0.20210903204242-51efa5b487c4
github.com/anchore/packageurl-go v0.1.1-0.20220428202044-a072fa3cb6d7
github.com/anchore/stereoscope v0.0.0-20220829182958-659c89aa659f
github.com/anchore/syft v0.55.0
github.com/anchore/syft v0.55.1-0.20220907184338-999994f197d5
github.com/bmatcuk/doublestar/v2 v2.0.4
github.com/docker/docker v20.10.17+incompatible
github.com/dustin/go-humanize v1.0.0
@ -72,6 +72,7 @@ require (
github.com/Azure/go-autorest/autorest/date v0.3.0 // indirect
github.com/Azure/go-autorest/logger v0.2.1 // indirect
github.com/Azure/go-autorest/tracing v0.6.0 // indirect
github.com/DataDog/zstd v1.4.5 // indirect
github.com/Masterminds/goutils v1.1.1 // indirect
github.com/Masterminds/semver/v3 v3.1.1 // indirect
github.com/Microsoft/go-winio v0.5.2 // indirect
@ -206,6 +207,7 @@ require (
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 // indirect
github.com/rivo/uniseg v0.2.0 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/sassoftware/go-rpmutils v0.2.0 // indirect
github.com/sassoftware/relic v0.0.0-20210427151427-dfb082b79b74 // indirect
github.com/shibumi/go-pathspec v1.3.0 // indirect
github.com/shopspring/decimal v1.2.0 // indirect

9
go.sum
View file

@ -144,6 +144,8 @@ github.com/BurntSushi/toml v0.4.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbi
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/CycloneDX/cyclonedx-go v0.6.0 h1:SizWGbZzFTC/O/1yh072XQBMxfvsoWqd//oKCIyzFyE=
github.com/CycloneDX/cyclonedx-go v0.6.0/go.mod h1:nQCiF4Tvrg5Ieu8qPhYMvzPGMu5I7fANZkrSsJjl5mg=
github.com/DataDog/zstd v1.4.5 h1:EndNeuB0l9syBZhut0wns3gV1hL8zX8LIu6ZiVHWLIQ=
github.com/DataDog/zstd v1.4.5/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo=
github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24/go.mod h1:4UJr5HIiMZrwgkSPdsjy2uOQExX/WEILpIrO9UPGuXs=
github.com/GoogleCloudPlatform/cloudsql-proxy v0.0.0-20191009163259-e802c2cb94ae/go.mod h1:mjwGPas4yKduTyubHvD1Atl9r1rUq8DfVy+gkVvZ+oo=
github.com/GoogleCloudPlatform/docker-credential-gcr v2.0.5+incompatible/go.mod h1:BB1eHdMLYEFuFdBlRMb0N7YGVdM5s6Pt0njxgvfbGGs=
@ -224,8 +226,8 @@ github.com/anchore/sqlite v1.4.6-0.20220607210448-bcc6ee5c4963 h1:vrf2PYH77vqVJo
github.com/anchore/sqlite v1.4.6-0.20220607210448-bcc6ee5c4963/go.mod h1:AVRyXOUP0hTz9Cb8OlD1XnwA8t4lBPfTuwPHmEUuiLc=
github.com/anchore/stereoscope v0.0.0-20220829182958-659c89aa659f h1:ekyERd7HC9ylQL6CutrFkP6u6aHfy1wz6LugRzDP6Qs=
github.com/anchore/stereoscope v0.0.0-20220829182958-659c89aa659f/go.mod h1:QjCxOPxjv7RqJm0pMIvB7P3rKHn7/uMBU7mnmM7ijTU=
github.com/anchore/syft v0.55.0 h1:8Z8ANPvGHLA89EM8qQetsSd0DSInv1zdKj9u11+h4T4=
github.com/anchore/syft v0.55.0/go.mod h1:abW0lg68hOQnXNFa/hBhGyAMdVe5k2ntrXY59yInPfA=
github.com/anchore/syft v0.55.1-0.20220907184338-999994f197d5 h1:l5fCdAn2akvBTzJpy5CRpoQPwYCDjz2luSFuydMMEVY=
github.com/anchore/syft v0.55.1-0.20220907184338-999994f197d5/go.mod h1:pAHjZvHC+ZuEUPYJ9HgTs81niKkrBqKvLEz2LdVE+AU=
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8=
github.com/andybalholm/brotli v1.0.1/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y=
github.com/andybalholm/brotli v1.0.2/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y=
@ -1177,6 +1179,7 @@ github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0
github.com/klauspost/compress v1.11.2/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
github.com/klauspost/compress v1.11.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
github.com/klauspost/compress v1.11.4/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
github.com/klauspost/compress v1.11.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
github.com/klauspost/compress v1.11.13/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
github.com/klauspost/compress v1.13.4/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg=
github.com/klauspost/compress v1.13.5/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
@ -1607,6 +1610,8 @@ github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0
github.com/sanposhiho/wastedassign/v2 v2.0.6/go.mod h1:KyZ0MWTwxxBmfwn33zh3k1dmsbF2ud9pAAGfoLfjhtI=
github.com/sassoftware/go-rpmutils v0.0.0-20190420191620-a8f1baeba37b/go.mod h1:am+Fp8Bt506lA3Rk3QCmSqmYmLMnPDhdDUcosQCAx+I=
github.com/sassoftware/go-rpmutils v0.1.1/go.mod h1:euhXULoBpvAxqrBHEyJS4Tsu3hHxUmQWNymxoJbzgUY=
github.com/sassoftware/go-rpmutils v0.2.0 h1:pKW0HDYMFWQ5b4JQPiI3WI12hGsVoW0V8+GMoZiI/JE=
github.com/sassoftware/go-rpmutils v0.2.0/go.mod h1:TJJQYtLe/BeEmEjelI3b7xNZjzAukEkeWKmoakvaOoI=
github.com/sassoftware/relic v0.0.0-20210427151427-dfb082b79b74 h1:sUNzanSKA9z/h8xXl+ZJoxIYZL0Qx306MmxqRrvUgr0=
github.com/sassoftware/relic v0.0.0-20210427151427-dfb082b79b74/go.mod h1:YlB8wFIZmFLZ1JllNBfSURzz52fBxbliNgYALk1UDmk=
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=

View file

@ -6,7 +6,7 @@ const (
ApkMatcher MatcherType = "apk-matcher"
RubyGemMatcher MatcherType = "ruby-gem-matcher"
DpkgMatcher MatcherType = "dpkg-matcher"
RpmDBMatcher MatcherType = "rpmdb-matcher"
RpmMatcher MatcherType = "rpm-matcher"
JavaMatcher MatcherType = "java-matcher"
PythonMatcher MatcherType = "python-matcher"
DotnetMatcher MatcherType = "dotnet-matcher"
@ -20,7 +20,7 @@ var AllMatcherTypes = []MatcherType{
ApkMatcher,
RubyGemMatcher,
DpkgMatcher,
RpmDBMatcher,
RpmMatcher,
JavaMatcher,
PythonMatcher,
DotnetMatcher,

View file

@ -16,7 +16,7 @@ import (
"github.com/anchore/grype/grype/matcher/msrc"
"github.com/anchore/grype/grype/matcher/portage"
"github.com/anchore/grype/grype/matcher/python"
"github.com/anchore/grype/grype/matcher/rpmdb"
"github.com/anchore/grype/grype/matcher/rpm"
"github.com/anchore/grype/grype/matcher/ruby"
"github.com/anchore/grype/grype/matcher/stock"
"github.com/anchore/grype/grype/pkg"
@ -49,7 +49,7 @@ func NewDefaultMatchers(mc Config) []Matcher {
ruby.NewRubyMatcher(mc.Ruby),
python.NewPythonMatcher(mc.Python),
dotnet.NewDotnetMatcher(mc.Dotnet),
&rpmdb.Matcher{},
&rpm.Matcher{},
java.NewJavaMatcher(mc.Java),
javascript.NewJavascriptMatcher(mc.Javascript),
&apk.Matcher{},

View file

@ -1,4 +1,4 @@
package rpmdb
package rpm
import (
"fmt"
@ -20,7 +20,7 @@ func (m *Matcher) PackageTypes() []syftPkg.Type {
}
func (m *Matcher) Type() match.MatcherType {
return match.RpmDBMatcher
return match.RpmMatcher
}
//nolint:funlen

View file

@ -1,4 +1,4 @@
package rpmdb
package rpm
import (
"strings"

View file

@ -1,4 +1,4 @@
package rpmdb
package rpm
import (
"testing"
@ -18,7 +18,7 @@ func intRef(x int) *int {
return &x
}
func TestMatcherRpmdb(t *testing.T) {
func TestMatcherRpm(t *testing.T) {
tests := []struct {
name string
p pkg.Package
@ -27,7 +27,7 @@ func TestMatcherRpmdb(t *testing.T) {
wantErr bool
}{
{
name: "Rpmdb Match matches by direct and by source indirection",
name: "Rpm Match matches by direct and by source indirection",
p: pkg.Package{
ID: pkg.ID(uuid.NewString()),
Name: "neutron-libs",
@ -58,7 +58,7 @@ func TestMatcherRpmdb(t *testing.T) {
},
},
{
name: "Rpmdb Match matches by direct and ignores the source rpm when the package names are the same",
name: "Rpm Match matches by direct and ignores the source rpm when the package names are the same",
p: pkg.Package{
ID: pkg.ID(uuid.NewString()),
Name: "neutron",
@ -88,7 +88,7 @@ func TestMatcherRpmdb(t *testing.T) {
},
{
// Regression against https://github.com/anchore/grype/issues/376
name: "Rpmdb Match matches by direct and by source indirection when the SourceRpm version is desynced from package version",
name: "Rpm Match matches by direct and by source indirection when the SourceRpm version is desynced from package version",
p: pkg.Package{
ID: pkg.ID(uuid.NewString()),
Name: "neutron-libs",
@ -119,13 +119,13 @@ func TestMatcherRpmdb(t *testing.T) {
{
// Epoch in pkg but not in src package version, epoch found in the vuln record
// Regression: https://github.com/anchore/grype/issues/437
name: "Rpmdb Match should not occur due to source match even though source has no epoch",
name: "Rpm Match should not occur due to source match even though source has no epoch",
p: pkg.Package{
ID: pkg.ID(uuid.NewString()),
Name: "perl-Errno",
Version: "0:1.28-419.el8_4.1",
Type: syftPkg.RpmPkg,
Metadata: pkg.RpmdbMetadata{
Metadata: pkg.RpmMetadata{
Epoch: intRef(0),
},
Upstreams: []pkg.UpstreamPackage{
@ -159,7 +159,7 @@ func TestMatcherRpmdb(t *testing.T) {
Name: "perl-Errno",
Version: "1.28-419.el8_4.1",
Type: syftPkg.RpmPkg,
Metadata: pkg.RpmdbMetadata{},
Metadata: pkg.RpmMetadata{},
},
setup: func() (vulnerability.Provider, *distro.Distro, Matcher) {
matcher := Matcher{}
@ -183,7 +183,7 @@ func TestMatcherRpmdb(t *testing.T) {
Name: "perl-Errno",
Version: "1.28-419.el8_4.1",
Type: syftPkg.RpmPkg,
Metadata: pkg.RpmdbMetadata{},
Metadata: pkg.RpmMetadata{},
},
setup: func() (vulnerability.Provider, *distro.Distro, Matcher) {
matcher := Matcher{}
@ -207,7 +207,7 @@ func TestMatcherRpmdb(t *testing.T) {
Name: "perl-Errno",
Version: "2:1.28-419.el8_4.1",
Type: syftPkg.RpmPkg,
Metadata: pkg.RpmdbMetadata{},
Metadata: pkg.RpmMetadata{},
},
setup: func() (vulnerability.Provider, *distro.Distro, Matcher) {
matcher := Matcher{}
@ -231,7 +231,7 @@ func TestMatcherRpmdb(t *testing.T) {
Name: "perl-Errno",
Version: "2:1.28-419.el8_4.1",
Type: syftPkg.RpmPkg,
Metadata: pkg.RpmdbMetadata{},
Metadata: pkg.RpmMetadata{},
},
setup: func() (vulnerability.Provider, *distro.Distro, Matcher) {
matcher := Matcher{}

View file

@ -8,6 +8,6 @@ const (
UnknownMetadataType MetadataType = "UnknownMetadata"
JavaMetadataType MetadataType = "JavaMetadata"
RpmdbMetadataType MetadataType = "RpmdbMetadata"
RpmMetadataType MetadataType = "RpmMetadata"
GolangBinMetadataType MetadataType = "GolangBinMetadata"
)

View file

@ -97,12 +97,12 @@ func dataFromPkg(p pkg.Package) (MetadataType, interface{}, []UpstreamPackage) {
}
case pkg.DpkgMetadataType:
upstreams = dpkgDataFromPkg(p)
case pkg.RpmdbMetadataType:
m, u := rpmdbDataFromPkg(p)
case pkg.RpmMetadataType:
m, u := rpmDataFromPkg(p)
upstreams = u
if m != nil {
metadata = *m
metadataType = RpmdbMetadataType
metadataType = RpmMetadataType
}
case pkg.JavaMetadataType:
if m := javaDataFromPkg(p); m != nil {
@ -143,8 +143,8 @@ func dpkgDataFromPkg(p pkg.Package) (upstreams []UpstreamPackage) {
return upstreams
}
func rpmdbDataFromPkg(p pkg.Package) (metadata *RpmdbMetadata, upstreams []UpstreamPackage) {
if value, ok := p.Metadata.(pkg.RpmdbMetadata); ok {
func rpmDataFromPkg(p pkg.Package) (metadata *RpmMetadata, upstreams []UpstreamPackage) {
if value, ok := p.Metadata.(pkg.RpmMetadata); ok {
if value.SourceRpm != "" {
name, version := getNameAndELVersion(value.SourceRpm)
if name == "" && version == "" {
@ -158,7 +158,7 @@ func rpmdbDataFromPkg(p pkg.Package) (metadata *RpmdbMetadata, upstreams []Upstr
}
}
if value.Epoch != nil {
metadata = &RpmdbMetadata{Epoch: value.Epoch}
metadata = &RpmMetadata{Epoch: value.Epoch}
}
} else {
log.Warnf("unable to extract RPM metadata for %s", p)

View file

@ -67,10 +67,10 @@ func TestNew(t *testing.T) {
},
},
{
name: "rpmdb with source info",
name: "rpm with source info",
syftPkg: syftPkg.Package{
MetadataType: syftPkg.RpmdbMetadataType,
Metadata: syftPkg.RpmdbMetadata{
MetadataType: syftPkg.RpmMetadataType,
Metadata: syftPkg.RpmMetadata{
Name: "name-info",
Version: "version-info",
Epoch: intRef(30),
@ -96,7 +96,7 @@ func TestNew(t *testing.T) {
},
},
},
metadata: RpmdbMetadata{
metadata: RpmMetadata{
Epoch: intRef(30),
},
upstreams: []UpstreamPackage{
@ -107,11 +107,11 @@ func TestNew(t *testing.T) {
},
},
{
name: "rpmdb with source info that matches the package info",
name: "rpm with source info that matches the package info",
syftPkg: syftPkg.Package{
Name: "sqlite",
MetadataType: syftPkg.RpmdbMetadataType,
Metadata: syftPkg.RpmdbMetadata{
MetadataType: syftPkg.RpmMetadataType,
Metadata: syftPkg.RpmMetadata{
SourceRpm: "sqlite-3.26.0-6.el8.src.rpm",
},
},

View file

@ -1,5 +1,5 @@
package pkg
type RpmdbMetadata struct {
type RpmMetadata struct {
Epoch *int `json:"epoch"`
}

View file

@ -61,8 +61,8 @@ func TestJsonImgsPresenter(t *testing.T) {
Version: "3.2",
},
},
MetadataType: pkg.RpmdbMetadataType,
Metadata: pkg.RpmdbMetadata{Epoch: &epoch},
MetadataType: pkg.RpmMetadataType,
Metadata: pkg.RpmMetadata{Epoch: &epoch},
}
var pkg2 = pkg.Package{

View file

@ -63,7 +63,7 @@
"version": "3.2"
}
],
"metadataType": "RpmdbMetadata",
"metadataType": "RpmMetadata",
"metadata": {
"epoch": 2
}
@ -132,7 +132,7 @@
"version": "3.2"
}
],
"metadataType": "RpmdbMetadata",
"metadataType": "RpmMetadata",
"metadata": {
"epoch": 2
}
@ -189,7 +189,7 @@
"version": "3.2"
}
],
"metadataType": "RpmdbMetadata",
"metadataType": "RpmMetadata",
"metadata": {
"epoch": 2
}

View file

@ -51,7 +51,7 @@ func ParseFormat(userStr string) Format {
return ApkFormat
case strings.ToLower(DebFormat.String()), "dpkg":
return DebFormat
case strings.ToLower(RpmFormat.String()), "rpmdb":
case strings.ToLower(RpmFormat.String()), "rpm":
return RpmFormat
case strings.ToLower(PythonFormat.String()), "python":
return PythonFormat

View file

@ -120,7 +120,7 @@
"name": "dive",
"version": "0.9.2-1",
"type": "rpm",
"foundBy": "rpmdb-cataloger",
"foundBy": "rpm-db-cataloger",
"locations": [
{
"path": "test/integration/test-fixtures/image-sles-match-coverage/var/lib/rpm/Packages"
@ -132,7 +132,7 @@
"cpe:2.3:a:dive:dive:0.9.2-1:*:*:*:*:*:*:*"
],
"purl": "",
"metadataType": "RpmdbMetadata",
"metadataType": "RpmMetadata",
"metadata": {
"name": "dive",
"version": "0.9.2",

View file

@ -367,7 +367,7 @@ func addRhelMatches(t *testing.T, theSource source.Source, catalog *syftPkg.Cata
Found: map[string]interface{}{
"constraint": "<= 1.0.42 (rpm)",
},
Matcher: match.RpmDBMatcher,
Matcher: match.RpmMatcher,
},
},
})
@ -401,7 +401,7 @@ func addSlesMatches(t *testing.T, theSource source.Source, catalog *syftPkg.Cata
Found: map[string]interface{}{
"constraint": "<= 1.0.42 (rpm)",
},
Matcher: match.RpmDBMatcher,
Matcher: match.RpmMatcher,
},
},
})