mirror of
https://github.com/anchore/syft.git
synced 2025-11-17 16:33:21 +01:00
feat: elf_binary_package_cataloger
Signed-off-by: Brian Ebarb <brian.ebarb@cgifederal.com>
This commit is contained in:
parent
5534c38d0f
commit
a35f64c971
@ -117,6 +117,7 @@ func DefaultPackageTaskFactories() PackageTaskFactories {
|
||||
},
|
||||
pkgcataloging.DeclaredTag, pkgcataloging.DirectoryTag, pkgcataloging.InstalledTag, pkgcataloging.ImageTag, "binary",
|
||||
),
|
||||
newSimplePackageTaskFactory(binary.NewELFPackageCataloger, pkgcataloging.DeclaredTag, pkgcataloging.DirectoryTag, pkgcataloging.InstalledTag, pkgcataloging.ImageTag, "binary", "elf-package"),
|
||||
newSimplePackageTaskFactory(githubactions.NewActionUsageCataloger, pkgcataloging.DeclaredTag, pkgcataloging.DirectoryTag, "github", "github-actions"),
|
||||
newSimplePackageTaskFactory(githubactions.NewWorkflowUsageCataloger, pkgcataloging.DeclaredTag, pkgcataloging.DirectoryTag, "github", "github-actions"),
|
||||
newPackageTaskFactory(
|
||||
|
||||
@ -630,6 +630,33 @@
|
||||
"dso"
|
||||
]
|
||||
},
|
||||
"ElfBinaryPackageNotes": {
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string"
|
||||
},
|
||||
"vendor": {
|
||||
"type": "string"
|
||||
},
|
||||
"system": {
|
||||
"type": "string"
|
||||
},
|
||||
"sourceRepo": {
|
||||
"type": "string"
|
||||
},
|
||||
"commit": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"type": "object",
|
||||
"required": [
|
||||
"type",
|
||||
"vendor",
|
||||
"system",
|
||||
"sourceRepo",
|
||||
"commit"
|
||||
]
|
||||
},
|
||||
"ElixirMixLockEntry": {
|
||||
"properties": {
|
||||
"name": {
|
||||
@ -1410,6 +1437,9 @@
|
||||
{
|
||||
"$ref": "#/$defs/DpkgDbEntry"
|
||||
},
|
||||
{
|
||||
"$ref": "#/$defs/ElfBinaryPackageNotes"
|
||||
},
|
||||
{
|
||||
"$ref": "#/$defs/ElixirMixLockEntry"
|
||||
},
|
||||
|
||||
@ -630,6 +630,33 @@
|
||||
"dso"
|
||||
]
|
||||
},
|
||||
"ElfBinaryPackageNotes": {
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string"
|
||||
},
|
||||
"vendor": {
|
||||
"type": "string"
|
||||
},
|
||||
"system": {
|
||||
"type": "string"
|
||||
},
|
||||
"sourceRepo": {
|
||||
"type": "string"
|
||||
},
|
||||
"commit": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"type": "object",
|
||||
"required": [
|
||||
"type",
|
||||
"vendor",
|
||||
"system",
|
||||
"sourceRepo",
|
||||
"commit"
|
||||
]
|
||||
},
|
||||
"ElixirMixLockEntry": {
|
||||
"properties": {
|
||||
"name": {
|
||||
@ -1425,6 +1452,9 @@
|
||||
{
|
||||
"$ref": "#/$defs/DpkgDbEntry"
|
||||
},
|
||||
{
|
||||
"$ref": "#/$defs/ElfBinaryPackageNotes"
|
||||
},
|
||||
{
|
||||
"$ref": "#/$defs/ElixirMixLockEntry"
|
||||
},
|
||||
|
||||
@ -19,6 +19,7 @@ func AllTypes() []any {
|
||||
pkg.DotnetDepsEntry{},
|
||||
pkg.DotnetPortableExecutableEntry{},
|
||||
pkg.DpkgDBEntry{},
|
||||
pkg.ELFBinaryPackageNotes{},
|
||||
pkg.ElixirMixLockEntry{},
|
||||
pkg.ErlangRebarLockEntry{},
|
||||
pkg.GolangBinaryBuildinfoEntry{},
|
||||
|
||||
@ -74,6 +74,7 @@ var jsonTypes = makeJSONTypes(
|
||||
jsonNames(pkg.DotnetDepsEntry{}, "dotnet-deps-entry", "DotnetDepsMetadata"),
|
||||
jsonNames(pkg.DotnetPortableExecutableEntry{}, "dotnet-portable-executable-entry"),
|
||||
jsonNames(pkg.DpkgDBEntry{}, "dpkg-db-entry", "DpkgMetadata"),
|
||||
jsonNames(pkg.ELFBinaryPackageNotes{}, "elf-binary-package-notes"),
|
||||
jsonNames(pkg.RubyGemspec{}, "ruby-gemspec", "GemMetadata"),
|
||||
jsonNames(pkg.GolangBinaryBuildinfoEntry{}, "go-module-buildinfo-entry", "GolangBinMetadata", "GolangMetadata"),
|
||||
jsonNames(pkg.GolangModuleEntry{}, "go-module-entry", "GolangModMetadata"),
|
||||
|
||||
@ -12,3 +12,12 @@ type ClassifierMatch struct {
|
||||
Classifier string `mapstructure:"Classifier" json:"classifier"`
|
||||
Location file.Location `mapstructure:"Location" json:"location"`
|
||||
}
|
||||
|
||||
// ELFBinaryPackageNotes Represents metadata captured from the .note.package section of the binary
|
||||
type ELFBinaryPackageNotes struct {
|
||||
Type string `json:"type"`
|
||||
Vendor string `json:"vendor"`
|
||||
System string `json:"system"`
|
||||
Source string `json:"sourceRepo"`
|
||||
Commit string `json:"commit"`
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
# Adding tests for the Binary cataloger
|
||||
# Adding tests for the Binary classifier cataloger
|
||||
|
||||
> [!TIP]
|
||||
> **TL;DR** to add a test for a new classifier:
|
||||
|
||||
@ -125,7 +125,7 @@ func fileNameTemplateVersionMatcher(fileNamePattern string, contentTemplate stri
|
||||
|
||||
matchMetadata := internal.MatchNamedCaptureGroups(tmplPattern, string(contents))
|
||||
|
||||
p := newPackage(classifier, location, matchMetadata)
|
||||
p := newClassifierPackage(classifier, location, matchMetadata)
|
||||
if p == nil {
|
||||
return nil, nil
|
||||
}
|
||||
@ -144,7 +144,7 @@ func FileContentsVersionMatcher(pattern string) EvidenceMatcher {
|
||||
|
||||
matchMetadata := internal.MatchNamedCaptureGroups(pat, string(contents))
|
||||
|
||||
p := newPackage(classifier, location, matchMetadata)
|
||||
p := newClassifierPackage(classifier, location, matchMetadata)
|
||||
if p == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
@ -11,7 +11,7 @@ import (
|
||||
|
||||
var emptyPURL = packageurl.PackageURL{}
|
||||
|
||||
func newPackage(classifier Classifier, location file.Location, matchMetadata map[string]string) *pkg.Package {
|
||||
func newClassifierPackage(classifier Classifier, location file.Location, matchMetadata map[string]string) *pkg.Package {
|
||||
version, ok := matchMetadata["version"]
|
||||
if !ok {
|
||||
return nil
|
||||
35
syft/pkg/cataloger/binary/elf_package.go
Normal file
35
syft/pkg/cataloger/binary/elf_package.go
Normal file
@ -0,0 +1,35 @@
|
||||
package binary
|
||||
|
||||
import (
|
||||
"github.com/anchore/packageurl-go"
|
||||
"github.com/anchore/syft/syft/file"
|
||||
"github.com/anchore/syft/syft/pkg"
|
||||
)
|
||||
|
||||
func newELFPackage(metadata elfBinaryPackageNotes, locations file.LocationSet, licenses []pkg.License) pkg.Package {
|
||||
p := pkg.Package{
|
||||
Name: metadata.Name,
|
||||
Version: metadata.Version,
|
||||
Licenses: pkg.NewLicenseSet(licenses...),
|
||||
PURL: packageURL(metadata),
|
||||
Type: pkg.BinaryPkg,
|
||||
Locations: locations,
|
||||
Metadata: metadata.ELFBinaryPackageNotes,
|
||||
}
|
||||
|
||||
p.SetID()
|
||||
|
||||
return p
|
||||
}
|
||||
|
||||
func packageURL(metadata elfBinaryPackageNotes) string {
|
||||
// TODO: what if the System value is not set?
|
||||
return packageurl.NewPackageURL(
|
||||
packageurl.TypeGeneric,
|
||||
metadata.System,
|
||||
metadata.Name,
|
||||
metadata.Version,
|
||||
nil,
|
||||
"",
|
||||
).ToString()
|
||||
}
|
||||
147
syft/pkg/cataloger/binary/elf_package_cataloger.go
Normal file
147
syft/pkg/cataloger/binary/elf_package_cataloger.go
Normal file
@ -0,0 +1,147 @@
|
||||
package binary
|
||||
|
||||
import (
|
||||
"context"
|
||||
"debug/elf"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/anchore/syft/internal/log"
|
||||
"github.com/anchore/syft/internal/mimetype"
|
||||
"github.com/anchore/syft/syft/artifact"
|
||||
"github.com/anchore/syft/syft/file"
|
||||
"github.com/anchore/syft/syft/internal/unionreader"
|
||||
"github.com/anchore/syft/syft/pkg"
|
||||
)
|
||||
|
||||
var _ pkg.Cataloger = (*elfPackageCataloger)(nil)
|
||||
|
||||
type elfPackageCataloger struct {
|
||||
}
|
||||
|
||||
type elfBinaryPackageNotes struct {
|
||||
Name string `json:"name"`
|
||||
Version string `json:"version"`
|
||||
PURL string `json:"purl"`
|
||||
CPE string `json:"cpe"`
|
||||
License string `json:"license"`
|
||||
pkg.ELFBinaryPackageNotes `json:",inline"`
|
||||
Location file.Location `json:"-"`
|
||||
}
|
||||
|
||||
type elfPackageKey struct {
|
||||
Name string
|
||||
Version string
|
||||
PURL string
|
||||
CPE string
|
||||
}
|
||||
|
||||
func NewELFPackageCataloger() pkg.Cataloger {
|
||||
return &elfPackageCataloger{}
|
||||
}
|
||||
|
||||
func (c *elfPackageCataloger) Name() string {
|
||||
return "elf-binary-package-cataloger"
|
||||
}
|
||||
|
||||
func (c *elfPackageCataloger) Catalog(_ context.Context, resolver file.Resolver) ([]pkg.Package, []artifact.Relationship, error) {
|
||||
locations, err := resolver.FilesByMIMEType(mimetype.ExecutableMIMETypeSet.List()...)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("unable to get binary files by mime type: %w", err)
|
||||
}
|
||||
|
||||
// first find all ELF binaries that have notes
|
||||
var notesByLocation = make(map[elfPackageKey][]elfBinaryPackageNotes)
|
||||
for _, location := range locations {
|
||||
reader, err := resolver.FileContentsByLocation(location)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("unable to get binary contents %q: %w", location.Path(), err)
|
||||
}
|
||||
|
||||
notes, err := c.parseElfNotes(file.LocationReadCloser{
|
||||
Location: location,
|
||||
ReadCloser: reader,
|
||||
})
|
||||
if err != nil {
|
||||
log.Warnf("unable to parse ELF notes: %v", err)
|
||||
continue
|
||||
}
|
||||
|
||||
if notes == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
notes.Location = location
|
||||
key := elfPackageKey{
|
||||
Name: notes.Name,
|
||||
Version: notes.Version,
|
||||
PURL: notes.PURL,
|
||||
CPE: notes.CPE,
|
||||
}
|
||||
notesByLocation[key] = append(notesByLocation[key], *notes)
|
||||
}
|
||||
|
||||
// now we have all ELF binaries that have notes, let's create packages for them.
|
||||
// we do this in a second pass since it is possible that we have multiple ELF binaries with the same name and version
|
||||
// which means the set of binaries collectively represent a single logical package.
|
||||
var pkgs []pkg.Package
|
||||
for _, notes := range notesByLocation {
|
||||
noteLocations := file.NewLocationSet()
|
||||
for _, note := range notes {
|
||||
noteLocations.Add(note.Location.WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation))
|
||||
}
|
||||
|
||||
// create a package for each unique name/version pair (based on the first note found)
|
||||
pkgs = append(pkgs, newELFPackage(notes[0], noteLocations, nil))
|
||||
}
|
||||
|
||||
// why not return relationships? We have an executable cataloger that will note the dynamic libraries imported by
|
||||
// each binary. After all files and packages are processed there is a final task that creates package-to-package
|
||||
// and package-to-file relationships based on the dynamic libraries imported by each binary.
|
||||
return pkgs, nil, nil
|
||||
}
|
||||
|
||||
func (c *elfPackageCataloger) parseElfNotes(reader file.LocationReadCloser) (*elfBinaryPackageNotes, error) {
|
||||
metadata, err := getELFNotes(reader)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to process ELF binary: %w", err)
|
||||
}
|
||||
|
||||
if metadata == nil || metadata.Name == "" || metadata.Version == "" {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
return metadata, nil
|
||||
}
|
||||
|
||||
func getELFNotes(r file.LocationReadCloser) (*elfBinaryPackageNotes, error) {
|
||||
unionReader, err := unionreader.GetUnionReader(r)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to get union reader for binary: %w", err)
|
||||
}
|
||||
|
||||
f, err := elf.NewFile(unionReader)
|
||||
if f == nil || err != nil {
|
||||
log.WithFields("file", r.Location.Path(), "error", err).Trace("unable to parse binary as ELF")
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
noteSection := f.Section(".note.package")
|
||||
if noteSection == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
notes, err := noteSection.Data()
|
||||
if err != nil {
|
||||
log.WithFields("error", err).Trace("unable to read .note.package")
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var metadata elfBinaryPackageNotes
|
||||
if err := json.Unmarshal(notes, &metadata); err != nil {
|
||||
log.WithFields("error", err).Trace("unable to unmarshal ELF package notes as JSON")
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
return &metadata, err
|
||||
}
|
||||
124
syft/pkg/cataloger/binary/elf_package_cataloger_test.go
Normal file
124
syft/pkg/cataloger/binary/elf_package_cataloger_test.go
Normal file
@ -0,0 +1,124 @@
|
||||
package binary
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/anchore/syft/syft/file"
|
||||
"github.com/anchore/syft/syft/pkg"
|
||||
"github.com/anchore/syft/syft/pkg/cataloger/internal/pkgtest"
|
||||
)
|
||||
|
||||
func Test_ELF_Package_Cataloger(t *testing.T) {
|
||||
expectedPkgs := []pkg.Package{
|
||||
{
|
||||
Name: "libhello_world.so",
|
||||
Version: "0.01",
|
||||
PURL: "pkg:generic/syftsys/libhello_world.so@0.01",
|
||||
FoundBy: "",
|
||||
Locations: file.NewLocationSet(file.NewVirtualLocation("/usr/local/bin/elftests/elfbinwithnestedlib/bin/lib/libhello_world.so", "/usr/local/bin/elftests/elfbinwithnestedlib/bin/lib/libhello_world.so"),
|
||||
file.NewVirtualLocation("/usr/local/bin/elftests/elfbinwithsisterlib/lib/libhello_world.so", "/usr/local/bin/elftests/elfbinwithsisterlib/lib/libhello_world.so"),
|
||||
file.NewVirtualLocation("/usr/local/bin/elftests/elfbinwithsisterlib/lib/libhello_world2.so", "/usr/local/bin/elftests/elfbinwithsisterlib/lib/libhello_world2.so"),
|
||||
),
|
||||
Language: "",
|
||||
Type: pkg.BinaryPkg,
|
||||
Metadata: pkg.ELFBinaryPackageNotes{
|
||||
Type: "testfixture",
|
||||
Vendor: "syft",
|
||||
System: "syftsys",
|
||||
Source: "",
|
||||
Commit: "",
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "syfttestfixture",
|
||||
Version: "0.01",
|
||||
PURL: "pkg:generic/syftsys/syfttestfixture@0.01",
|
||||
FoundBy: "",
|
||||
Locations: file.NewLocationSet(file.NewLocation("/usr/local/bin/elftests/elfbinwithnestedlib/bin/elfbinwithnestedlib").WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
|
||||
file.NewLocation("/usr/local/bin/elftests/elfbinwithsisterlib/bin/elfwithparallellibbin1").WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
|
||||
file.NewLocation("/usr/local/bin/elftests/elfbinwithsisterlib/bin/elfwithparallellibbin2").WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
|
||||
),
|
||||
Language: "",
|
||||
Type: pkg.BinaryPkg,
|
||||
Metadata: pkg.ELFBinaryPackageNotes{
|
||||
Type: "testfixture",
|
||||
Vendor: "syft",
|
||||
System: "syftsys",
|
||||
Source: "",
|
||||
Commit: "",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
pkgtest.NewCatalogTester().
|
||||
WithImageResolver(t, "elf-test-fixtures").
|
||||
IgnoreLocationLayer(). // this fixture can be rebuilt, thus the layer ID will change
|
||||
Expects(expectedPkgs, nil).
|
||||
TestCataloger(t, NewELFPackageCataloger())
|
||||
|
||||
// expectedPkgs = []pkg.Package{
|
||||
// {
|
||||
// Name: "libhello_world.so",
|
||||
// Version: "0.01",
|
||||
// PURL: "pkg:generic/syftsys/libhello_world.so@0.01",
|
||||
// FoundBy: "",
|
||||
// Locations: file.NewLocationSet(file.NewVirtualLocation("/usr/local/bin/syftelftest/lib/libhello_world.so", "/usr/local/bin/syftelftest/lib/libhello_world.so")),
|
||||
// Language: "",
|
||||
// Type: pkg.BinaryPkg,
|
||||
// Metadata: pkg.ELFBinaryPackageNotes{
|
||||
// Type: "testfixture",
|
||||
// Vendor: "syft",
|
||||
// System: "syftsys",
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// Name: "syfttestfixture",
|
||||
// Version: "0.01",
|
||||
// PURL: "pkg:generic/syftsys/syfttestfixture@0.01",
|
||||
// FoundBy: "",
|
||||
// Locations: file.NewLocationSet(file.NewVirtualLocation("/usr/local/bin/syftelftest/bin/elfwithparallellibbin1", "/usr/local/bin/syftelftest/bin/elfwithparallellibbin1")),
|
||||
// Language: "",
|
||||
// Type: pkg.BinaryPkg,
|
||||
// Metadata: pkg.ELFBinaryPackageNotes{
|
||||
// Type: "testfixture",
|
||||
// Vendor: "syft",
|
||||
// System: "syftsys",
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// Name: "libhello_world2.so",
|
||||
// Version: "0.01",
|
||||
// PURL: "pkg:generic/syftsys/libhello_world2.so@0.01",
|
||||
// FoundBy: "",
|
||||
// Locations: file.NewLocationSet(file.NewVirtualLocation("/usr/local/bin/syftelftest/lib/libhello_world2.so", "/usr/local/bin/syftelftest/lib/libhello_world2.so")),
|
||||
// Language: "",
|
||||
// Type: pkg.BinaryPkg,
|
||||
// Metadata: pkg.ELFBinaryPackageNotes{
|
||||
// Type: "testfixture",
|
||||
// Vendor: "syft",
|
||||
// System: "syftsys",
|
||||
// },
|
||||
// },
|
||||
|
||||
// {
|
||||
// Name: "syfttestfixture",
|
||||
// Version: "0.01",
|
||||
// PURL: "pkg:generic/syftsys/syfttestfixture@0.01",
|
||||
// FoundBy: "",
|
||||
// Locations: file.NewLocationSet(file.NewVirtualLocation("/usr/local/bin/syftelftest/bin/elfwithparallellibbin2", "/usr/local/bin/syftelftest/bin/elfwithparallellibbin2")),
|
||||
// Language: "",
|
||||
// Type: pkg.BinaryPkg,
|
||||
// Metadata: pkg.ELFBinaryPackageNotes{
|
||||
// Type: "testfixture",
|
||||
// Vendor: "syft",
|
||||
// System: "syftsys",
|
||||
// },
|
||||
// },
|
||||
// }
|
||||
// pkgtest.NewCatalogTester().
|
||||
// WithImageResolver(t, "elf-test-fixture-sister-lib").
|
||||
// IgnoreLocationLayer(). // this fixture can be rebuilt, thus the layer ID will change
|
||||
// Expects(expectedPkgs, nil).
|
||||
// TestCataloger(t, NewELFPackageCataloger())
|
||||
|
||||
}
|
||||
96
syft/pkg/cataloger/binary/elf_package_test.go
Normal file
96
syft/pkg/cataloger/binary/elf_package_test.go
Normal file
@ -0,0 +1,96 @@
|
||||
package binary
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/google/go-cmp/cmp/cmpopts"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/anchore/syft/syft/file"
|
||||
"github.com/anchore/syft/syft/pkg"
|
||||
)
|
||||
|
||||
func Test_packageURL(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
notes elfBinaryPackageNotes
|
||||
expected string
|
||||
}{
|
||||
{
|
||||
name: "elf-binary-package-cataloger",
|
||||
notes: elfBinaryPackageNotes{
|
||||
Name: "github.com/anchore/syft",
|
||||
Version: "v0.1.0",
|
||||
ELFBinaryPackageNotes: pkg.ELFBinaryPackageNotes{
|
||||
System: "syftsys",
|
||||
},
|
||||
},
|
||||
expected: "pkg:generic/syftsys/github.com/anchore/syft@v0.1.0",
|
||||
},
|
||||
{
|
||||
name: "elf binary package short name",
|
||||
notes: elfBinaryPackageNotes{
|
||||
Name: "go.opencensus.io",
|
||||
Version: "v0.23.0",
|
||||
ELFBinaryPackageNotes: pkg.ELFBinaryPackageNotes{
|
||||
System: "syftsys",
|
||||
},
|
||||
},
|
||||
expected: "pkg:generic/syftsys/go.opencensus.io@v0.23.0",
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
assert.Equal(t, test.expected, packageURL(test.notes))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_newELFPackage(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
metadata elfBinaryPackageNotes
|
||||
expected pkg.Package
|
||||
}{
|
||||
{
|
||||
name: "elf-binary-package-cataloger",
|
||||
metadata: elfBinaryPackageNotes{
|
||||
Name: "syfttestfixture",
|
||||
Version: "0.01",
|
||||
PURL: "pkg:generic/syftsys/syfttestfixture@0.01",
|
||||
CPE: "cpe:/o:syft:syftsys_testfixture_syfttestfixture:0.01",
|
||||
ELFBinaryPackageNotes: pkg.ELFBinaryPackageNotes{
|
||||
Type: "binary",
|
||||
System: "syftsys",
|
||||
},
|
||||
},
|
||||
|
||||
expected: pkg.Package{
|
||||
Name: "syfttestfixture",
|
||||
Version: "0.01",
|
||||
Type: "binary",
|
||||
PURL: "pkg:generic/syftsys/syfttestfixture@0.01",
|
||||
Metadata: pkg.ELFBinaryPackageNotes{
|
||||
Type: "binary",
|
||||
System: "syftsys",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
// for _, test := range tests {
|
||||
// t.Run(test.name, func(t *testing.T) {
|
||||
// assert.Equal(t, test.expected, newELFPackage(test.metadata, file.NewLocationSet(), nil))
|
||||
// })
|
||||
// }
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
actual := newELFPackage(test.metadata, file.NewLocationSet(), nil)
|
||||
if diff := cmp.Diff(test.expected, actual, cmpopts.IgnoreFields(pkg.Package{}, "id"), cmpopts.IgnoreUnexported(pkg.Package{}, file.LocationSet{}, pkg.LicenseSet{})); diff != "" {
|
||||
t.Errorf("newELFPackage() mismatch (-want +got):\n%s", diff)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,14 @@
|
||||
FROM rockylinux:8
|
||||
RUN dnf update -y; \
|
||||
dnf install make automake gcc gcc-c++ kernel-devel -y; \
|
||||
dnf clean all
|
||||
RUN mkdir -p /usr/local/bin/elftests/elfbinwithnestedlib
|
||||
RUN mkdir -p /usr/local/bin/elftests/elfbinwithsisterlib
|
||||
COPY ./elfbinwithnestedlib /usr/local/bin/elftests/elfbinwithnestedlib
|
||||
COPY ./elfbinwithsisterlib /usr/local/bin/elftests/elfbinwithsisterlib
|
||||
ENV LD_LIBRARY_PATH=/usr/local/bin/elftests/elfbinwithnestedlib/bin/lib
|
||||
WORKDIR /usr/local/bin/elftests/elfbinwithnestedlib/
|
||||
RUN make
|
||||
WORKDIR /usr/local/bin/elftests/elfbinwithsisterlib
|
||||
RUN make
|
||||
|
||||
@ -0,0 +1,6 @@
|
||||
#include <iostream>
|
||||
#include "hello_world.h"
|
||||
|
||||
void print_hello_world() {
|
||||
std::cout << "Hello, World!" << std::endl;
|
||||
}
|
||||
@ -0,0 +1,8 @@
|
||||
|
||||
#ifndef HELLO_WORLD_H
|
||||
#define HELLO_WORLD_H
|
||||
|
||||
// Function declaration for printing "Hello, World!" to stdout
|
||||
void print_hello_world();
|
||||
|
||||
#endif // HELLO_WORLD_H
|
||||
@ -0,0 +1,48 @@
|
||||
LDFLAGS := -L/lib64 -lstdc++
|
||||
|
||||
SRC_DIR := ./
|
||||
BUILD_DIR := ../build
|
||||
BIN_DIR := ../bin
|
||||
LIB_DIR := $(BIN_DIR)/lib
|
||||
|
||||
LIB_NAME := hello_world
|
||||
LIB_SRC := $(SRC_DIR)/hello_world.cpp
|
||||
LIB_OBJ := $(BUILD_DIR)/$(LIB_NAME).o
|
||||
LIB_SO := $(LIB_DIR)/lib$(LIB_NAME).so
|
||||
|
||||
EXECUTABLE := elfbinwithnestedlib
|
||||
EXEC_SRC := $(SRC_DIR)/testbin.cpp
|
||||
EXEC_OBJ := $(BUILD_DIR)/$(EXECUTABLE).o
|
||||
|
||||
|
||||
|
||||
all: testfixture
|
||||
|
||||
$(LIB_SO): $(LIB_OBJ) | $(LIB_DIR)
|
||||
$(CC) -shared -o $@ $<
|
||||
echo '{"type": "testfixture","vendor": "syft","system": "syftsys","name": "libhello_world.so","version": "0.01","purl": "pkg:generic/syftsys/syfttestfixture@0.01","cpe": "cpe:/o:syft:syftsys_testfixture_syfttestfixture:0.01"}' | objcopy --add-section .note.package=/dev/stdin --set-section-flags .note.package=noload,readonly $@
|
||||
|
||||
$(LIB_OBJ): $(LIB_SRC) | $(BUILD_DIR)
|
||||
$(CC) $(CFLAGS) -fPIC -c $< -o $@
|
||||
|
||||
$(EXEC_OBJ): $(EXEC_SRC) | $(BUILD_DIR)
|
||||
$(CC) $(CFLAGS) -c $< -o $@
|
||||
|
||||
$(BIN_DIR):
|
||||
mkdir -p $(BIN_DIR)
|
||||
$(BUILD_DIR):
|
||||
mkdir -p $(BUILD_DIR)
|
||||
$(LIB_DIR):
|
||||
mkdir -p $(LIB_DIR)
|
||||
|
||||
$(BIN_DIR)/$(EXECUTABLE): $(EXEC_OBJ) $(LIB_SO) | $(BIN_DIR)
|
||||
$(CC) $(CFLAGS) -o $@ $^ -L$(LIB_DIR) -l$(LIB_NAME) $(LDFLAGS)
|
||||
echo '{"type": "testfixture","vendor": "syft","system": "syftsys","name": "syfttestfixture","version": "0.01","purl": "pkg:generic/syftsys/syfttestfixture@0.01","cpe": "cpe:/o:syft:syftsys_testfixture_syfttestfixture:0.01"}' | objcopy --add-section .note.package=/dev/stdin --set-section-flags .note.package=noload,readonly $@
|
||||
|
||||
testfixture: $(BIN_DIR)/$(EXECUTABLE)
|
||||
|
||||
clean:
|
||||
rm -rf $(BUILD_DIR) $(LIB_DIR) $(BIN_DIR) $(EXECUTABLE)
|
||||
|
||||
.PHONY: all clean
|
||||
|
||||
@ -0,0 +1,8 @@
|
||||
#include "hello_world.h"
|
||||
|
||||
int main() {
|
||||
// Call the function from the shared library
|
||||
print_hello_world();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -0,0 +1,18 @@
|
||||
CC = g++
|
||||
CFLAGS = -std=c++17 -Wall -Wextra -pedantic
|
||||
BUILD_DIR := ./build
|
||||
BIN_DIR := ./bin
|
||||
LIB_DIR := $(BIN_DIR)/lib
|
||||
|
||||
|
||||
|
||||
all: testfixtures
|
||||
|
||||
testfixtures:
|
||||
$(MAKE) -C elfsrc
|
||||
|
||||
clean:
|
||||
rm -rf $(BUILD_DIR) $(BIN_DIR)
|
||||
|
||||
.PHONY: all clean testfixtures
|
||||
|
||||
@ -0,0 +1,6 @@
|
||||
#include <iostream>
|
||||
#include "hello_world.h"
|
||||
|
||||
void print_hello_world() {
|
||||
std::cout << "Hello, World!" << std::endl;
|
||||
}
|
||||
@ -0,0 +1,8 @@
|
||||
|
||||
#ifndef HELLO_WORLD_H
|
||||
#define HELLO_WORLD_H
|
||||
|
||||
// Function declaration for printing "Hello, World!" to stdout
|
||||
void print_hello_world();
|
||||
|
||||
#endif // HELLO_WORLD_H
|
||||
@ -0,0 +1,48 @@
|
||||
LDFLAGS := -L/lib64 -lstdc++
|
||||
|
||||
SRC_DIR := ./
|
||||
BUILD_DIR := ../build
|
||||
LIB_DIR := ../lib
|
||||
BIN_DIR := ../bin
|
||||
|
||||
LIB_NAME := hello_world
|
||||
LIB_SRC := $(SRC_DIR)/hello_world.cpp
|
||||
LIB_OBJ := $(BUILD_DIR)/$(LIB_NAME).o
|
||||
LIB_SO := $(LIB_DIR)/lib$(LIB_NAME).so
|
||||
|
||||
EXECUTABLE := elfwithparallellibbin1
|
||||
EXEC_SRC := $(SRC_DIR)/testbin.cpp
|
||||
EXEC_OBJ := $(BUILD_DIR)/$(EXECUTABLE).o
|
||||
|
||||
|
||||
|
||||
all: testfixture
|
||||
|
||||
$(LIB_SO): $(LIB_OBJ) | $(LIB_DIR)
|
||||
$(CC) -shared -o $@ $<
|
||||
echo '{"type": "testfixture","vendor": "syft","system": "syftsys","name": "libhello_world.so","version": "0.01","purl": "pkg:generic/syftsys/syfttestfixture@0.01","cpe": "cpe:/o:syft:syftsys_testfixture_syfttestfixture:0.01"}' | objcopy --add-section .note.package=/dev/stdin --set-section-flags .note.package=noload,readonly $@
|
||||
|
||||
$(LIB_OBJ): $(LIB_SRC) | $(BUILD_DIR)
|
||||
$(CC) $(CFLAGS) -fPIC -c $< -o $@
|
||||
|
||||
$(EXEC_OBJ): $(EXEC_SRC) | $(BUILD_DIR)
|
||||
$(CC) $(CFLAGS) -c $< -o $@
|
||||
|
||||
$(BIN_DIR):
|
||||
mkdir -p $(BIN_DIR)
|
||||
$(BUILD_DIR):
|
||||
mkdir -p $(BUILD_DIR)
|
||||
$(LIB_DIR):
|
||||
mkdir -p $(LIB_DIR)
|
||||
|
||||
$(BIN_DIR)/$(EXECUTABLE): $(EXEC_OBJ) $(LIB_SO) | $(BIN_DIR)
|
||||
$(CC) $(CFLAGS) -o $@ $^ -L$(LIB_DIR) -l$(LIB_NAME) $(LDFLAGS)
|
||||
echo '{"type": "testfixture","vendor": "syft","system": "syftsys","name": "syfttestfixture","version": "0.01","purl": "pkg:generic/syftsys/syfttestfixture@0.01","cpe": "cpe:/o:syft:syftsys_testfixture_syfttestfixture:0.01"}' | objcopy --add-section .note.package=/dev/stdin --set-section-flags .note.package=noload,readonly $@
|
||||
|
||||
testfixture: $(BIN_DIR)/$(EXECUTABLE)
|
||||
|
||||
clean:
|
||||
rm -rf $(BUILD_DIR) $(LIB_DIR) $(BIN_DIR) $(EXECUTABLE)
|
||||
|
||||
.PHONY: all clean
|
||||
|
||||
@ -0,0 +1,8 @@
|
||||
#include "hello_world.h"
|
||||
|
||||
int main() {
|
||||
// Call the function from the shared library
|
||||
print_hello_world();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -0,0 +1,6 @@
|
||||
#include <iostream>
|
||||
#include "hello_world2.h"
|
||||
|
||||
void print_hello_world() {
|
||||
std::cout << "Hello, World again!!" << std::endl;
|
||||
}
|
||||
@ -0,0 +1,8 @@
|
||||
|
||||
#ifndef HELLO_WORLD2_H
|
||||
#define HELLO_WORLD2_H
|
||||
|
||||
// Function declaration for printing "Hello, World!" to stdout
|
||||
void print_hello_world();
|
||||
|
||||
#endif // HELLO_WORLD2_H
|
||||
@ -0,0 +1,48 @@
|
||||
LDFLAGS := -L/lib64 -lstdc++
|
||||
|
||||
SRC_DIR := ./
|
||||
BUILD_DIR := ../build
|
||||
LIB_DIR := ../lib
|
||||
BIN_DIR := ../bin
|
||||
|
||||
LIB_NAME := hello_world2
|
||||
LIB_SRC := $(SRC_DIR)/hello_world2.cpp
|
||||
LIB_OBJ := $(BUILD_DIR)/$(LIB_NAME).o
|
||||
LIB_SO := $(LIB_DIR)/lib$(LIB_NAME).so
|
||||
|
||||
EXECUTABLE := elfwithparallellibbin2
|
||||
EXEC_SRC := $(SRC_DIR)/testbin2.cpp
|
||||
EXEC_OBJ := $(BUILD_DIR)/$(EXECUTABLE).o
|
||||
|
||||
|
||||
|
||||
all: testfixture
|
||||
|
||||
$(LIB_SO): $(LIB_OBJ) | $(LIB_DIR)
|
||||
$(CC) -shared -o $@ $<
|
||||
echo '{"type": "testfixture","vendor": "syft","system": "syftsys","name": "libhello_world.so","version": "0.01","purl": "pkg:generic/syftsys/syfttestfixture@0.01","cpe": "cpe:/o:syft:syftsys_testfixture_syfttestfixture:0.01"}' | objcopy --add-section .note.package=/dev/stdin --set-section-flags .note.package=noload,readonly $@
|
||||
|
||||
$(LIB_OBJ): $(LIB_SRC) | $(BUILD_DIR)
|
||||
$(CC) $(CFLAGS) -fPIC -c $< -o $@
|
||||
|
||||
$(EXEC_OBJ): $(EXEC_SRC) | $(BUILD_DIR)
|
||||
$(CC) $(CFLAGS) -c $< -o $@
|
||||
|
||||
$(BIN_DIR):
|
||||
mkdir -p $(BIN_DIR)
|
||||
$(BUILD_DIR):
|
||||
mkdir -p $(BUILD_DIR)
|
||||
$(LIB_DIR):
|
||||
mkdir -p $(LIB_DIR)
|
||||
|
||||
$(BIN_DIR)/$(EXECUTABLE): $(EXEC_OBJ) $(LIB_SO) | $(BIN_DIR)
|
||||
$(CC) $(CFLAGS) -o $@ $^ -L$(LIB_DIR) -l$(LIB_NAME) $(LDFLAGS)
|
||||
echo '{"type": "testfixture","vendor": "syft","system": "syftsys","name": "syfttestfixture","version": "0.01","purl": "pkg:generic/syftsys/syfttestfixture@0.01","cpe": "cpe:/o:syft:syftsys_testfixture_syfttestfixture:0.01"}' | objcopy --add-section .note.package=/dev/stdin --set-section-flags .note.package=noload,readonly $@
|
||||
|
||||
testfixture: $(BIN_DIR)/$(EXECUTABLE)
|
||||
|
||||
clean:
|
||||
rm -rf $(BUILD_DIR) $(LIB_DIR) $(BIN_DIR) $(EXECUTABLE)
|
||||
|
||||
.PHONY: all clean
|
||||
|
||||
@ -0,0 +1,8 @@
|
||||
#include "hello_world2.h"
|
||||
|
||||
int main() {
|
||||
// Call the function from the shared library
|
||||
print_hello_world();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -0,0 +1,18 @@
|
||||
CC = g++
|
||||
CFLAGS = -std=c++17 -Wall -Wextra -pedantic
|
||||
BUILD_DIR := ./build
|
||||
LIB_DIR := ./lib
|
||||
BIN_DIR := ./bin
|
||||
|
||||
|
||||
all: testfixtures
|
||||
|
||||
testfixtures:
|
||||
$(MAKE) -C elfsrc1
|
||||
$(MAKE) -C elfsrc2
|
||||
|
||||
clean:
|
||||
rm -rf $(BUILD_DIR) $(LIB_DIR) $(BIN_DIR)
|
||||
|
||||
.PHONY: all clean testfixtures
|
||||
|
||||
@ -82,7 +82,7 @@ func LanguageByName(name string) Language {
|
||||
return Dart
|
||||
case string(Dotnet), ".net", packageurl.TypeNuget:
|
||||
return Dotnet
|
||||
case packageurl.TypeCocoapods, packageurl.TypeSwift, string(CocoapodsPkg):
|
||||
case packageurl.TypeCocoapods, packageurl.TypeSwift, string(CocoapodsPkg), string(SwiftPkg):
|
||||
return Swift
|
||||
case packageurl.TypeConan, string(CPP):
|
||||
return CPP
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user