Skip to content

Commit

Permalink
rhel: move IgnoreUnpatched config key from updater to matcher
Browse files Browse the repository at this point in the history
Previously the IgnoreUnpatched config key was a part of the RHEL
updater and would dictate whether or not the updater would ingest
unpatched vulnerabilities. This change moves that key to the RHEL
matcher and dictates whether the matcher should check for a
fixed_in_version when querying potential vulnerabilities. This makes the
config option more usable at the expense of DB size.

Signed-off-by: crozzy <joseph.crosland@gmail.com>
  • Loading branch information
crozzy committed May 10, 2024
1 parent e3d134c commit ab36dfd
Show file tree
Hide file tree
Showing 8 changed files with 72 additions and 22 deletions.
2 changes: 2 additions & 0 deletions datastore/postgres/querybuilder.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ func buildGetQuery(record *claircore.IndexRecord, opts *datastore.GetOpts) (stri
ex = goqu.Ex{"dist_arch": record.Distribution.Arch}
case driver.RepositoryName:
ex = goqu.Ex{"repo_name": record.Repository.Name}
case driver.HasFixedInVersion:
ex = goqu.Ex{"fixed_in_version": goqu.Op{"neq": ""}}
default:
return "", fmt.Errorf("was provided unknown matcher: %v", m)
}
Expand Down
14 changes: 14 additions & 0 deletions datastore/postgres/querybuilder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,20 @@ func TestGetQueryBuilderDeterministicArgs(t *testing.T) {
}
},
},
{
name: "FixedInVersion",
expectedQuery: preamble + both +
`("fixed_in_version" != '')` + epilogue,
matchExps: []driver.MatchConstraint{driver.HasFixedInVersion},
indexRecord: func() *claircore.IndexRecord {
pkgs := test.GenUniquePackages(1)
dists := test.GenUniqueDistributions(1)
return &claircore.IndexRecord{
Package: pkgs[0],
Distribution: dists[0],
}
},
},
}

// This is safe to do because SQL doesn't care about what whitespace is
Expand Down
2 changes: 2 additions & 0 deletions libvuln/driver/matcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ const (
DistributionPrettyName
// should match claircore.Package.Repository.Name => claircore.Vulnerability.Package.Repository.Name
RepositoryName
// should match claircore.Vulnerability.FixedInVersion != ""
HasFixedInVersion
)

// Matcher is an interface which a Controller uses to query the vulnstore for vulnerabilities.
Expand Down
2 changes: 1 addition & 1 deletion matchers/defaults/defaults.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,13 @@ var defaultMatchers = []driver.Matcher{
&photon.Matcher{},
&python.Matcher{},
rhcc.Matcher,
&rhel.Matcher{},
&ruby.Matcher{},
&suse.Matcher{},
&ubuntu.Matcher{},
}

func inner(ctx context.Context) error {
registry.Register("rhel", &rhel.MatcherFactory{})
for _, m := range defaultMatchers {
mf := driver.MatcherStatic(m)
registry.Register(m.Name(), mf)
Expand Down
12 changes: 8 additions & 4 deletions rhel/matcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ import (
)

// Matcher implements driver.Matcher.
type Matcher struct{}
type Matcher struct {
ignoreUnpatched bool
}

var _ driver.Matcher = (*Matcher)(nil)

Expand All @@ -26,10 +28,12 @@ func (*Matcher) Filter(record *claircore.IndexRecord) bool {
}

// Query implements driver.Matcher.
func (*Matcher) Query() []driver.MatchConstraint {
return []driver.MatchConstraint{
driver.PackageModule,
func (m *Matcher) Query() []driver.MatchConstraint {
mcs := []driver.MatchConstraint{driver.PackageModule}
if m.ignoreUnpatched {
mcs = append(mcs, driver.HasFixedInVersion)

Check warning on line 34 in rhel/matcher.go

View check run for this annotation

Codecov / codecov/patch

rhel/matcher.go#L31-L34

Added lines #L31 - L34 were not covered by tests
}
return mcs

Check warning on line 36 in rhel/matcher.go

View check run for this annotation

Codecov / codecov/patch

rhel/matcher.go#L36

Added line #L36 was not covered by tests
}

// Vulnerable implements driver.Matcher.
Expand Down
35 changes: 35 additions & 0 deletions rhel/matcherfactory.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package rhel

import (
"context"
"net/http"

"github.com/quay/claircore/libvuln/driver"
)

type MatcherFactory struct {
ignoreUnpatched bool
}

// MatcherFactory implements [driver.MatcherFactory]
func (f *MatcherFactory) Matcher(ctx context.Context) ([]driver.Matcher, error) {
m := &Matcher{
ignoreUnpatched: f.ignoreUnpatched,

Check warning on line 17 in rhel/matcherfactory.go

View check run for this annotation

Codecov / codecov/patch

rhel/matcherfactory.go#L15-L17

Added lines #L15 - L17 were not covered by tests
}
return []driver.Matcher{m}, nil

Check warning on line 19 in rhel/matcherfactory.go

View check run for this annotation

Codecov / codecov/patch

rhel/matcherfactory.go#L19

Added line #L19 was not covered by tests
}

type MatcherFactoryConfig struct {
IgnoreUnpatched bool `json:"ignore_unpatched" yaml:"ignore_unpatched"`
}

// MatcherFactory implements driver.MatcherConfigurable.
func (f *MatcherFactory) Configure(ctx context.Context, cfg driver.MatcherConfigUnmarshaler, c *http.Client) error {
var fc MatcherFactoryConfig

Check warning on line 28 in rhel/matcherfactory.go

View check run for this annotation

Codecov / codecov/patch

rhel/matcherfactory.go#L27-L28

Added lines #L27 - L28 were not covered by tests
// TODO: add log
if err := cfg(&fc); err != nil {
return err

Check warning on line 31 in rhel/matcherfactory.go

View check run for this annotation

Codecov / codecov/patch

rhel/matcherfactory.go#L30-L31

Added lines #L30 - L31 were not covered by tests
}
f.ignoreUnpatched = fc.IgnoreUnpatched
return nil

Check warning on line 34 in rhel/matcherfactory.go

View check run for this annotation

Codecov / codecov/patch

rhel/matcherfactory.go#L33-L34

Added lines #L33 - L34 were not covered by tests
}
10 changes: 4 additions & 6 deletions rhel/vex/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,13 +86,11 @@ func (u *VEXUpdater) DeltaParse(ctx context.Context, contents io.ReadCloser) ([]
return nil, nil, err

Check warning on line 86 in rhel/vex/parser.go

View check run for this annotation

Codecov / codecov/patch

rhel/vex/parser.go#L86

Added line #L86 was not covered by tests
}
out[name] = fixedVulns
if !u.ignoreUnpatched {
knownAffectedVulns, err := creator.knownAffectedVulnerabilities(ctx, v, protoVuln)
if err != nil {
return nil, nil, err
}
out[name] = append(out[name], knownAffectedVulns...)
knownAffectedVulns, err := creator.knownAffectedVulnerabilities(ctx, v, protoVuln)
if err != nil {
return nil, nil, err

Check warning on line 91 in rhel/vex/parser.go

View check run for this annotation

Codecov / codecov/patch

rhel/vex/parser.go#L91

Added line #L91 was not covered by tests
}
out[name] = append(out[name], knownAffectedVulns...)
}
}
vulns := []*claircore.Vulnerability{}
Expand Down
17 changes: 6 additions & 11 deletions rhel/vex/updater.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,18 +30,16 @@ const (
)

type Factory struct {
c *http.Client
base *url.URL
ignoreUnpatched bool
c *http.Client
base *url.URL
}

// UpdaterSet constructs one VEXUpdater
func (f *Factory) UpdaterSet(_ context.Context) (driver.UpdaterSet, error) {
us := driver.NewUpdaterSet()
u := &VEXUpdater{
url: f.base,
client: f.c,
ignoreUnpatched: f.ignoreUnpatched,
url: f.base,
client: f.c,
}
err := us.Add(u)
if err != nil {
Expand All @@ -53,8 +51,6 @@ func (f *Factory) UpdaterSet(_ context.Context) (driver.UpdaterSet, error) {
type FactoryConfig struct {
// URL indicates the base URL for the SecDB layout. It should have a trailing slash.
URL string `json:"url" yaml:"url"`
// IgnoreUnpatched dictates whether to ingest known affected advisories from the VEX security data.
IgnoreUnpatched bool `json:"ignore_unpatched" yaml:"ignore_unpatched"`
}

func (f *Factory) Configure(ctx context.Context, cf driver.ConfigUnmarshaler, c *http.Client) error {
Expand All @@ -79,9 +75,8 @@ func (f *Factory) Configure(ctx context.Context, cf driver.ConfigUnmarshaler, c
}

type VEXUpdater struct {
url *url.URL
client *http.Client
ignoreUnpatched bool
url *url.URL
client *http.Client
}

type fingerprint struct {
Expand Down

0 comments on commit ab36dfd

Please sign in to comment.