Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deprecate RHELv2PackageInfo #928

Merged
merged 21 commits into from
Oct 18, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 8 additions & 14 deletions api/v1/models_rhelv2.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,30 +121,24 @@ func getRHELv2Vulns(vulns map[int][]*database.RHELv2Vulnerability, pkg *database
// 1. The package's version is less than the vuln's fixed-in version, if present.
// 2. The ArchOperation passes.
for _, vuln := range vulns[pkg.ID] {
if len(vuln.PackageInfos) != 1 {
log.Warnf("Unexpected number of package infos for vuln %q (%d != %d); Skipping...", vuln.Name, len(vuln.PackageInfos), 1)
if len(vuln.Packages) != 1 {
log.Warnf("Unexpected number of packages for vuln %q (%d != %d); Skipping...", vuln.Name, len(vuln.Packages), 1)
continue
}
vulnPkgInfo := vuln.PackageInfos[0]

if len(vulnPkgInfo.Packages) != 1 {
log.Warnf("Unexpected number of packages for vuln %q (%d != %d); Skipping...", vuln.Name, len(vulnPkgInfo.Packages), 1)
continue
}
vulnPkg := vulnPkgInfo.Packages[0]
vulnPkg := vuln.Packages[0]

// Assume the vulnerability is not fixed.
// In that case, all versions are affected.
affectedVersion := true
var vulnVersion *rpmVersion.Version
if vulnPkgInfo.FixedInVersion != "" {
if vulnPkg.FixedInVersion != "" {
// The vulnerability is fixed. Determine if this package is affected.
vulnVersion = rpmVersionPtr(rpmVersion.NewVersion(vulnPkgInfo.FixedInVersion))
vulnVersion = rpmVersionPtr(rpmVersion.NewVersion(vulnPkg.FixedInVersion))
affectedVersion = pkgVersion.LessThan(*vulnVersion)
}

// Compare the package's architecture to the affected architecture.
affectedArch := vulnPkgInfo.ArchOperation.Cmp(pkgArch, vulnPkg.Arch)
affectedArch := vulnPkg.ArchOperation.Cmp(pkgArch, vulnPkg.Arch)

if affectedVersion && affectedArch {
vulnerabilities = append(vulnerabilities, RHELv2ToVulnerability(vuln, namespaceName))
Expand Down Expand Up @@ -348,7 +342,7 @@ func RHELv2ToVulnerability(vuln *database.RHELv2Vulnerability, namespace string)
Link: vuln.Link,
Severity: vuln.Severity,
Metadata: metadata,
// It is guaranteed there is 1 and only one element in `vuln.PackageInfos`.
FixedBy: vuln.PackageInfos[0].FixedInVersion, // Empty string if not fixed.
// It is guaranteed there is 1 and only one element in `vuln.Packages`.
FixedBy: vuln.Packages[0].FixedInVersion, // Empty string if not fixed.
}
}
39 changes: 15 additions & 24 deletions api/v1/models_rhelv2_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,49 +107,40 @@ func TestLayerFromDatabaseModelRHELv2(t *testing.T) {
db.vulns[0] = []*database.RHELv2Vulnerability{
{
Name: "v1",
PackageInfos: []*database.RHELv2PackageInfo{
Packages: []*database.RHELv2Package{
{
Name: "pkg",
Arch: "x86_64",

FixedInVersion: "4",
Packages: []*database.RHELv2Package{
{
Name: "pkg",
Arch: "x86_64",
},
},
ArchOperation: archop.OpEquals,
ArchOperation: archop.OpEquals,
},
},
Issued: now,
},
{
Name: "v2",
PackageInfos: []*database.RHELv2PackageInfo{
Packages: []*database.RHELv2Package{
{
Name: "pkg",
Arch: "i686|ppc64|s390x|x86_64",

FixedInVersion: "5",
Packages: []*database.RHELv2Package{
{
Name: "pkg",
Arch: "i686|ppc64|s390x|x86_64",
},
},
ArchOperation: archop.OpPatternMatch,
ArchOperation: archop.OpPatternMatch,
},
},
Issued: now,
Updated: now,
},
{
Name: "v3",
PackageInfos: []*database.RHELv2PackageInfo{
Packages: []*database.RHELv2Package{
{
Name: "pkg",
Arch: "x86_64",

FixedInVersion: "6",
Packages: []*database.RHELv2Package{
{
Name: "pkg",
Arch: "x86_64",
},
},
ArchOperation: archop.OpNotEquals,
ArchOperation: archop.OpNotEquals,
},
},
},
Expand Down
11 changes: 4 additions & 7 deletions api/v1/orchestratorscan/openshift_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,16 +126,13 @@ func TestOpenShiftVulnVersion(t *testing.T) {
CPEs: []string{
cpe,
},
PackageInfos: []*database.RHELv2PackageInfo{
Packages: []*database.RHELv2Package{
{
Name: "package",
Arch: "x86_64",

FixedInVersion: fixedIn,
ArchOperation: archop.OpEquals,
Packages: []*database.RHELv2Package{
{
Name: "package",
Arch: "x86_64",
},
},
},
},
})
Expand Down
20 changes: 7 additions & 13 deletions api/v1/orchestratorscan/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,28 +144,22 @@ func (s *serviceImpl) GetOpenShiftVulnerabilities(_ context.Context, req *v1.Get
ScannerVersion: s.version,
}
for _, vuln := range vulns {
if len(vuln.PackageInfos) != 1 {
log.Warnf("unexpected number of package infos for vuln %q (%d != %d); Skipping...", vuln.Name, len(vuln.PackageInfos), 1)
if len(vuln.Packages) != 1 {
log.Warnf("unexpected number of packages for vuln %q (%d != %d); Skipping...", vuln.Name, len(vuln.Packages), 1)
continue
}
vulnPkgInfo := vuln.PackageInfos[0]
vulnPkg := vuln.Packages[0]

if len(vulnPkgInfo.Packages) != 1 {
log.Warnf("Unexpected number of packages for vuln %q (%d != %d); Skipping...", vuln.Name, len(vulnPkgInfo.Packages), 1)
continue
}

vulnPkg := vulnPkgInfo.Packages[0]
affectedArch := vulnPkgInfo.ArchOperation.Cmp("x86_64", vulnPkg.Arch)
affectedArch := vulnPkg.ArchOperation.Cmp("x86_64", vulnPkg.Arch)
if !affectedArch {
log.Warnf("vuln %s is for arch %v %s, Skipping ...", vuln.Name, vulnPkgInfo.ArchOperation, vulnPkg.Arch)
log.Warnf("vuln %s is for arch %v %s, Skipping ...", vuln.Name, vulnPkg.ArchOperation, vulnPkg.Arch)
continue
}

// Skip fixed vulns.
fixedBy, err := version.GetFixedVersion(vulnPkgInfo.FixedInVersion, vuln.Title)
fixedBy, err := version.GetFixedVersion(vulnPkg.FixedInVersion, vuln.Title)
if err != nil {
// Skip it. The vuln has a fixedBy version but we cannot extract it.
// Skip it. The vuln has a fixedBy version, but we cannot extract it.
log.Errorf("cannot get fix version for vuln %s: %v, Skipping ...", vuln.Name, err)
continue
}
Expand Down
17 changes: 17 additions & 0 deletions cmd/updater/diffdumps/rhelv2_diff.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,22 @@ import (
"github.com/stackrox/scanner/pkg/vulndump"
)

//nolint:staticcheck
func processRHELv2Vulnerability(v *database.RHELv2Vulnerability) {
// PackageInfos is deprecated, so it is no longer populated.
// However, we need to ensure we diff correctly with older genesis dumps
// which populate this field. We simply convert each RHELv2PackageInfo
// into its respective RHELv2Package.
for _, pkgInfo := range v.PackageInfos {
for _, pkg := range pkgInfo.Packages {
pkg.FixedInVersion = pkgInfo.FixedInVersion
pkg.ArchOperation = pkgInfo.ArchOperation
v.Packages = append(v.Packages, pkg)
}
}
v.PackageInfos = nil
}

func generateRHELv2Diff(cfg config, outputDir string, baseLastModifiedTime time.Time, baseF, headF *zip.File, rhelExists bool) error {
reader, err := headF.Open()
if err != nil {
Expand Down Expand Up @@ -62,6 +78,7 @@ func generateRHELv2Diff(cfg config, outputDir string, baseLastModifiedTime time.

baseVulnsMap := make(map[string]*database.RHELv2Vulnerability, len(baseRHEL.Vulns))
for _, vuln := range baseRHEL.Vulns {
processRHELv2Vulnerability(vuln)
if _, ok := baseVulnsMap[vuln.Name]; ok {
// Should really never happen, but being defensive.
return errors.Errorf("UNEXPECTED: got multiple vulns for key: %s", vuln.Name)
Expand Down
27 changes: 17 additions & 10 deletions database/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,21 +138,25 @@ func (mm *MetadataMap) Value() (driver.Value, error) {
type RHELv2Vulnerability struct {
Model

Name string `json:"name"`
Title string `json:"title"`
Description string `json:"description"`
Issued time.Time `json:"issued"`
Updated time.Time `json:"updated"`
Link string `json:"link"`
Severity string `json:"severity"`
CVSSv3 string `json:"cvssv3,omitempty"`
CVSSv2 string `json:"cvssv2,omitempty"`
CPEs []string `json:"cpes" hash:"ignore"` // These are checked explcitly due to the removal of unused CPEs
Name string `json:"name"`
Title string `json:"title"`
Description string `json:"description"`
Issued time.Time `json:"issued"`
Updated time.Time `json:"updated"`
Link string `json:"link"`
Severity string `json:"severity"`
CVSSv3 string `json:"cvssv3,omitempty"`
CVSSv2 string `json:"cvssv2,omitempty"`
CPEs []string `json:"cpes" hash:"ignore"` // These are checked explicitly due to the removal of unused CPEs
// Deprecated: Packages should be used instead.
PackageInfos []*RHELv2PackageInfo `json:"package_info" hash:"set"`
Packages []*RHELv2Package `json:"packages" hash:"set"`
SubCVEs []string `json:"sub_cves,omitempty" hash:"set"`
}

// RHELv2PackageInfo defines all the data necessary for fully define a RHELv2 package.
//
// Deprecated: RHELv2Package should be used instead.
type RHELv2PackageInfo struct {
Packages []*RHELv2Package `json:"package" hash:"set"`
FixedInVersion string `json:"fixed_in_version"`
Expand All @@ -169,6 +173,9 @@ type RHELv2Package struct {
Arch string `json:"arch,omitempty"`
ResolutionState string `json:"resolution_state"`

FixedInVersion string `json:"fixed_in_version"`
ArchOperation archop.ArchOp `json:"arch_op,omitempty"`

// ExecutableToDependencies maps a feature provided executable to its dependencies.
// Eg, If executable E is provided by this feature, and it imports a library B, we will have a map for E -> [B]
ExecutableToDependencies StringToStringsMap `json:"executable_to_dependencies,omitempty"`
Expand Down
60 changes: 26 additions & 34 deletions database/pgsql/rhelv2_vulnerability.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,23 +29,21 @@ const (

func (pgSQL *pgSQL) insertRHELv2Vulnerability(vulnStatement, vulnDescriptionStatement, vulnDeleteStatement *sql.Stmt, vuln *database.RHELv2Vulnerability) error {
vulnDescriptionHash := md5VulnDescription(vuln.Description)
for i, pkgInfo := range vuln.PackageInfos {
for j, pkg := range pkgInfo.Packages {
for k, cpe := range vuln.CPEs {
vulnHash := md5Vuln(vuln, i, j, k)
_, err := vulnStatement.Exec(
vulnHash,
vuln.Name, vuln.Title, vulnDescriptionHash,
vuln.Issued, vuln.Updated,
vuln.Link, vuln.Severity, vuln.CVSSv3, vuln.CVSSv2,
pkg.Name, pkg.Module, pkg.Arch,
cpe,
pkg.ResolutionState,
pkgInfo.FixedInVersion, pkgInfo.ArchOperation,
)
if err != nil {
return errors.Wrapf(err, "inserting RHELv2 vulnerability %q for package %q with cpe %q into the DB", vuln.Name, pkg.Name, cpe)
}
for i, pkg := range vuln.Packages {
for j, cpe := range vuln.CPEs {
vulnHash := md5Vuln(vuln, i, j)
_, err := vulnStatement.Exec(
vulnHash,
vuln.Name, vuln.Title, vulnDescriptionHash,
vuln.Issued, vuln.Updated,
vuln.Link, vuln.Severity, vuln.CVSSv3, vuln.CVSSv2,
pkg.Name, pkg.Module, pkg.Arch,
cpe,
pkg.ResolutionState,
pkg.FixedInVersion, pkg.ArchOperation,
)
if err != nil {
return errors.Wrapf(err, "inserting RHELv2 vulnerability %q for package %q with cpe %q into the DB", vuln.Name, pkg.Name, cpe)
}
}
}
Expand All @@ -56,12 +54,10 @@ func (pgSQL *pgSQL) insertRHELv2Vulnerability(vulnStatement, vulnDescriptionStat
}

if rhelv2.IsRedHatAdvisory(vuln.Name) {
if len(vuln.SubCVEs) != 0 && len(vuln.PackageInfos) != 0 && len(vuln.CPEs) != 0 {
if len(vuln.SubCVEs) != 0 && len(vuln.Packages) != 0 && len(vuln.CPEs) != 0 {
packagesByModule := make(map[string][]string)
for _, pkgInfo := range vuln.PackageInfos {
for _, pkg := range pkgInfo.Packages {
packagesByModule[pkg.Module] = append(packagesByModule[pkg.Module], pkg.Name)
}
for _, pkg := range vuln.Packages {
packagesByModule[pkg.Module] = append(packagesByModule[pkg.Module], pkg.Name)
}
for module, packages := range packagesByModule {
result, err := vulnDeleteStatement.Exec(pq.Array(vuln.SubCVEs), pq.Array(packages), pq.Array(vuln.CPEs), module)
Expand Down Expand Up @@ -100,7 +96,7 @@ func (pgSQL *pgSQL) insertRHELv2VulnerabilitiesBatched(vulnStmt, vulnDescription
defer utils.IgnoreError(vulnDeleteStmt.Close)

for _, vulnerability := range vulnerabilities {
if len(vulnerability.PackageInfos) == 0 {
if len(vulnerability.Packages) == 0 {
continue
}

Expand Down Expand Up @@ -154,10 +150,9 @@ func (pgSQL *pgSQL) InsertRHELv2Vulnerabilities(vulnerabilities []*database.RHEL
// md5Vuln creates an md5 hash from the members of the passed-in Vulnerability,
// giving us a stable, context-free identifier for this revision of the
// Vulnerability.
func md5Vuln(v *database.RHELv2Vulnerability, pkgInfoIdx, pkgIdx, cpeIdx int) []byte {
func md5Vuln(v *database.RHELv2Vulnerability, pkgIdx, cpeIdx int) []byte {
// Declare variables before necessary for readability.
pkgInfo := v.PackageInfos[pkgInfoIdx]
pkg := pkgInfo.Packages[pkgIdx]
pkg := v.Packages[pkgIdx]
cpe := v.CPEs[cpeIdx]

var b bytes.Buffer
Expand All @@ -175,8 +170,8 @@ func md5Vuln(v *database.RHELv2Vulnerability, pkgInfoIdx, pkgIdx, cpeIdx int) []
b.WriteString(pkg.Arch)
b.WriteString(cpe)
b.WriteString(pkg.ResolutionState)
b.WriteString(pkgInfo.FixedInVersion)
b.WriteString(pkgInfo.ArchOperation.String())
b.WriteString(pkg.FixedInVersion)
b.WriteString(pkg.ArchOperation.String())

checksum := md5.Sum(b.Bytes())
return checksum[:]
Expand Down Expand Up @@ -249,11 +244,8 @@ func (pgSQL *pgSQL) getRHELv2Vulns(tx *sql.Tx, record *database.RHELv2Record) ([

for rows.Next() {
var pkg database.RHELv2Package
pkgInfo := database.RHELv2PackageInfo{
Packages: []*database.RHELv2Package{&pkg},
}
vuln := database.RHELv2Vulnerability{
PackageInfos: []*database.RHELv2PackageInfo{&pkgInfo},
Packages: []*database.RHELv2Package{&pkg},
}
err := rows.Scan(
&vuln.ID,
Expand All @@ -269,8 +261,8 @@ func (pgSQL *pgSQL) getRHELv2Vulns(tx *sql.Tx, record *database.RHELv2Record) ([
&pkg.Name,
&pkg.Arch,
&pkg.ResolutionState,
&pkgInfo.FixedInVersion,
&pkgInfo.ArchOperation,
&pkg.FixedInVersion,
&pkg.ArchOperation,
)
if err != nil {
return nil, errors.Wrapf(err, "Scanning row for package: %s, module: %s, cpe: %s", record.Pkg.Name, record.Pkg.Module, record.CPE)
Expand Down
Loading