Skip to content

Commit

Permalink
Add relationships for rust audit binary packages (#3500)
Browse files Browse the repository at this point in the history
* add rust audit binary pkg relationships

Signed-off-by: Alex Goodman <[email protected]>

* fix linting

Signed-off-by: Alex Goodman <[email protected]>

---------

Signed-off-by: Alex Goodman <[email protected]>
  • Loading branch information
wagoodman authored Dec 6, 2024
1 parent 4adb56d commit 340b5e1
Show file tree
Hide file tree
Showing 12 changed files with 460 additions and 50 deletions.
2 changes: 1 addition & 1 deletion cmd/syft/internal/options/source.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ import (
"sort"
"strings"

stereoscopeFile "github.com/anchore/stereoscope/pkg/file"
"github.com/dustin/go-humanize"
"github.com/scylladb/go-set/strset"

"github.com/anchore/clio"
stereoscopeFile "github.com/anchore/stereoscope/pkg/file"
"github.com/anchore/syft/syft/source/sourceproviders"
)

Expand Down
3 changes: 2 additions & 1 deletion syft/internal/fileresolver/file_indexer.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@ import (
"os"
"path/filepath"

"github.com/wagoodman/go-progress"

"github.com/anchore/stereoscope/pkg/file"
"github.com/anchore/stereoscope/pkg/filetree"
"github.com/anchore/syft/internal/log"
"github.com/anchore/syft/syft/internal/windows"
"github.com/wagoodman/go-progress"
)

type fileIndexer struct {
Expand Down
8 changes: 5 additions & 3 deletions syft/internal/fileresolver/file_indexer_test.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
package fileresolver

import (
"github.com/anchore/stereoscope/pkg/file"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"io/fs"
"os"
"path"
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

"github.com/anchore/stereoscope/pkg/file"
)

// - Verify that both the parent and the path are indexed
Expand Down
5 changes: 3 additions & 2 deletions syft/internal/fileresolver/filetree_resolver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,14 @@ import (
"testing"
"time"

stereoscopeFile "github.com/anchore/stereoscope/pkg/file"
"github.com/anchore/syft/syft/file"
"github.com/google/go-cmp/cmp"
"github.com/scylladb/go-set/strset"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"go.uber.org/goleak"

stereoscopeFile "github.com/anchore/stereoscope/pkg/file"
"github.com/anchore/syft/syft/file"
)

// Tests for filetree resolver when directory is used for index
Expand Down
4 changes: 3 additions & 1 deletion syft/pkg/cataloger/rust/cataloger.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import (
"github.com/anchore/syft/syft/pkg/cataloger/generic"
)

const cargoAuditBinaryCatalogerName = "cargo-auditable-binary-cataloger"

// NewCargoLockCataloger returns a new Rust Cargo lock file cataloger object.
func NewCargoLockCataloger() pkg.Cataloger {
return generic.NewCataloger("rust-cargo-lock-cataloger").
Expand All @@ -18,6 +20,6 @@ func NewCargoLockCataloger() pkg.Cataloger {
// NewAuditBinaryCataloger returns a new Rust auditable binary cataloger object that can detect dependencies
// in binaries produced with https://github.com/Shnatsel/rust-audit
func NewAuditBinaryCataloger() pkg.Cataloger {
return generic.NewCataloger("cargo-auditable-binary-cataloger").
return generic.NewCataloger(cargoAuditBinaryCatalogerName).
WithParserByMimeTypes(parseAuditBinary, mimetype.ExecutableMIMETypeSet.List()...)
}
272 changes: 247 additions & 25 deletions syft/pkg/cataloger/rust/cataloger_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,48 +3,270 @@ package rust
import (
"testing"

"github.com/anchore/syft/syft/artifact"
"github.com/anchore/syft/syft/file"
"github.com/anchore/syft/syft/pkg"
"github.com/anchore/syft/syft/pkg/cataloger/internal/pkgtest"
)

func TestNewAuditBinaryCataloger(t *testing.T) {
locations := file.NewLocationSet(file.NewVirtualLocation("/usr/local/bin/hello_world", "/usr/local/bin/hello_world"))

argh := pkg.Package{
Name: "argh",
Version: "0.1.12",
PURL: "pkg:cargo/[email protected]",
FoundBy: "cargo-auditable-binary-cataloger",
Locations: locations,
Language: pkg.Rust,
Type: pkg.RustPkg,
Metadata: pkg.RustBinaryAuditEntry{
Name: "argh",
Version: "0.1.12",
Source: "crates.io",
},
}

arghDerive := pkg.Package{
Name: "argh_derive",
Version: "0.1.12",
PURL: "pkg:cargo/[email protected]",
FoundBy: "cargo-auditable-binary-cataloger",
Locations: locations,
Language: pkg.Rust,
Type: pkg.RustPkg,
Metadata: pkg.RustBinaryAuditEntry{
Name: "argh_derive",
Version: "0.1.12",
Source: "crates.io",
},
}

arghShared := pkg.Package{
Name: "argh_shared",
Version: "0.1.12",
PURL: "pkg:cargo/[email protected]",
FoundBy: "cargo-auditable-binary-cataloger",
Locations: locations,
Language: pkg.Rust,
Type: pkg.RustPkg,
Metadata: pkg.RustBinaryAuditEntry{
Name: "argh_shared",
Version: "0.1.12",
Source: "crates.io",
},
}

helloWorld := pkg.Package{
Name: "hello_world",
Version: "0.1.0",
PURL: "pkg:cargo/[email protected]",
FoundBy: "cargo-auditable-binary-cataloger",
Locations: locations,
Language: pkg.Rust,
Type: pkg.RustPkg,
Metadata: pkg.RustBinaryAuditEntry{
Name: "hello_world",
Version: "0.1.0",
Source: "local",
},
}

procMacro2 := pkg.Package{
Name: "proc-macro2",
Version: "1.0.92",
PURL: "pkg:cargo/[email protected]",
FoundBy: "cargo-auditable-binary-cataloger",
Locations: locations,
Language: pkg.Rust,
Type: pkg.RustPkg,
Metadata: pkg.RustBinaryAuditEntry{
Name: "proc-macro2",
Version: "1.0.92",
Source: "crates.io",
},
}

quote := pkg.Package{
Name: "quote",
Version: "1.0.37",
PURL: "pkg:cargo/[email protected]",
FoundBy: "cargo-auditable-binary-cataloger",
Locations: locations,
Language: pkg.Rust,
Type: pkg.RustPkg,
Metadata: pkg.RustBinaryAuditEntry{
Name: "quote",
Version: "1.0.37",
Source: "crates.io",
},
}

serde := pkg.Package{
Name: "serde",
Version: "1.0.215",
PURL: "pkg:cargo/[email protected]",
FoundBy: "cargo-auditable-binary-cataloger",
Locations: locations,
Language: pkg.Rust,
Type: pkg.RustPkg,
Metadata: pkg.RustBinaryAuditEntry{
Name: "serde",
Version: "1.0.215",
Source: "crates.io",
},
}

serdeDerive := pkg.Package{
Name: "serde_derive",
Version: "1.0.215",
PURL: "pkg:cargo/[email protected]",
FoundBy: "cargo-auditable-binary-cataloger",
Locations: locations,
Language: pkg.Rust,
Type: pkg.RustPkg,
Metadata: pkg.RustBinaryAuditEntry{
Name: "serde_derive",
Version: "1.0.215",
Source: "crates.io",
},
}

syn := pkg.Package{
Name: "syn",
Version: "2.0.90",
PURL: "pkg:cargo/[email protected]",
FoundBy: "cargo-auditable-binary-cataloger",
Locations: locations,
Language: pkg.Rust,
Type: pkg.RustPkg,
Metadata: pkg.RustBinaryAuditEntry{
Name: "syn",
Version: "2.0.90",
Source: "crates.io",
},
}

unicodeIdent := pkg.Package{
Name: "unicode-ident",
Version: "1.0.14",
PURL: "pkg:cargo/[email protected]",
FoundBy: "cargo-auditable-binary-cataloger",
Locations: locations,
Language: pkg.Rust,
Type: pkg.RustPkg,
Metadata: pkg.RustBinaryAuditEntry{
Name: "unicode-ident",
Version: "1.0.14",
Source: "crates.io",
},
}

expectedPkgs := []pkg.Package{
argh,
arghDerive,
arghShared,
helloWorld,
procMacro2,
quote,
serde,
serdeDerive,
syn,
unicodeIdent,
}

expectedRelationships := []artifact.Relationship{
{
Name: "auditable",
Version: "0.1.0",
PURL: "pkg:cargo/[email protected]",
FoundBy: "cargo-auditable-binary-cataloger",
Locations: file.NewLocationSet(file.NewVirtualLocation("/hello-auditable", "/hello-auditable")),
Language: pkg.Rust,
Type: pkg.RustPkg,
Metadata: pkg.RustBinaryAuditEntry{
Name: "auditable",
Version: "0.1.0",
Source: "local",
},
From: argh,
To: helloWorld,
Type: artifact.DependencyOfRelationship,
},
{
Name: "hello-auditable",
Version: "0.1.0",
PURL: "pkg:cargo/[email protected]",
FoundBy: "cargo-auditable-binary-cataloger",
Locations: file.NewLocationSet(file.NewVirtualLocation("/hello-auditable", "/hello-auditable")),
Language: pkg.Rust,
Type: pkg.RustPkg,
Metadata: pkg.RustBinaryAuditEntry{
Name: "hello-auditable",
Version: "0.1.0",
Source: "local",
},
From: arghDerive,
To: argh,
Type: artifact.DependencyOfRelationship,
},
{
From: arghShared,
To: argh,
Type: artifact.DependencyOfRelationship,
},
{
From: arghShared,
To: arghDerive,
Type: artifact.DependencyOfRelationship,
},
{
From: procMacro2,
To: arghDerive,
Type: artifact.DependencyOfRelationship,
},
{
From: procMacro2,
To: quote,
Type: artifact.DependencyOfRelationship,
},
{
From: procMacro2,
To: serdeDerive,
Type: artifact.DependencyOfRelationship,
},
{
From: procMacro2,
To: syn,
Type: artifact.DependencyOfRelationship,
},
{
From: quote,
To: arghDerive,
Type: artifact.DependencyOfRelationship,
},
{
From: quote,
To: serdeDerive,
Type: artifact.DependencyOfRelationship,
},
{
From: quote,
To: syn,
Type: artifact.DependencyOfRelationship,
},
{
From: serde,
To: arghShared,
Type: artifact.DependencyOfRelationship,
},
{
From: serdeDerive,
To: serde,
Type: artifact.DependencyOfRelationship,
},
{
From: syn,
To: arghDerive,
Type: artifact.DependencyOfRelationship,
},
{
From: syn,
To: serdeDerive,
Type: artifact.DependencyOfRelationship,
},
{
From: unicodeIdent,
To: procMacro2,
Type: artifact.DependencyOfRelationship,
},
{
From: unicodeIdent,
To: syn,
Type: artifact.DependencyOfRelationship,
},
}

pkgtest.NewCatalogTester().
WithImageResolver(t, "image-audit").
IgnoreLocationLayer(). // this fixture can be rebuilt, thus the layer ID will change
Expects(expectedPkgs, nil).
Expects(expectedPkgs, expectedRelationships).
TestCataloger(t, NewAuditBinaryCataloger())
}

Expand Down
Loading

0 comments on commit 340b5e1

Please sign in to comment.