Skip to content

Commit

Permalink
fix(detector/vuls2): use tag for selection logic
Browse files Browse the repository at this point in the history
  • Loading branch information
shino committed Dec 12, 2024
1 parent 49a205b commit 9e32f8f
Show file tree
Hide file tree
Showing 4 changed files with 244 additions and 99 deletions.
111 changes: 100 additions & 11 deletions detector/vuls2/vendor.go
Original file line number Diff line number Diff line change
@@ -1,16 +1,22 @@
package vuls2

import (
"cmp"
"fmt"
"slices"
"strings"

dataTypes "github.com/MaineK00n/vuls-data-update/pkg/extract/types/data"
"github.com/MaineK00n/vuls-data-update/pkg/extract/types/data/detection/condition/criteria/criterion"
"github.com/MaineK00n/vuls-data-update/pkg/extract/types/data/detection/condition/criteria/criterion/versioncriterion/fixstatus"
advisoryTypes "github.com/MaineK00n/vuls-data-update/pkg/extract/types/data/advisory"
criterionTypes "github.com/MaineK00n/vuls-data-update/pkg/extract/types/data/detection/condition/criteria/criterion"
noneexistcriterionTypes "github.com/MaineK00n/vuls-data-update/pkg/extract/types/data/detection/condition/criteria/criterion/noneexistcriterion"
fixstatusTypes "github.com/MaineK00n/vuls-data-update/pkg/extract/types/data/detection/condition/criteria/criterion/versioncriterion/fixstatus"
versioncriterionpackageTypes "github.com/MaineK00n/vuls-data-update/pkg/extract/types/data/detection/condition/criteria/criterion/versioncriterion/package"
segmentTypes "github.com/MaineK00n/vuls-data-update/pkg/extract/types/data/detection/segment"
referenceTypes "github.com/MaineK00n/vuls-data-update/pkg/extract/types/data/reference"
vulnerabilityTypes "github.com/MaineK00n/vuls-data-update/pkg/extract/types/data/vulnerability"
sourceTypes "github.com/MaineK00n/vuls-data-update/pkg/extract/types/source"
scanTypes "github.com/MaineK00n/vuls2/pkg/scan/types"
"github.com/future-architect/vuls/constant"
"github.com/future-architect/vuls/models"
rpm "github.com/knqyf263/go-rpm-version"
Expand All @@ -29,7 +35,7 @@ func resolveCveContentList(family string, sviX, sviY sourceVulnInfo, ccListX, cc
}
}

func resolveAffectedPackage(family string, rootIDX, rootIDY dataTypes.RootID, statusX, statusY models.PackageFixStatus) models.PackageFixStatus {
func resolvePackageByRootID(family string, rootIDX, rootIDY dataTypes.RootID, statusX, statusY models.PackageFixStatus) models.PackageFixStatus {
switch family {
// This logic is from old vuls's oval resolution. Maybe more widely applicable than these four distros.
case constant.RedHat, constant.CentOS, constant.Alma, constant.Rocky:
Expand All @@ -54,10 +60,68 @@ func resolveAffectedPackage(family string, rootIDX, rootIDY dataTypes.RootID, st
}
}

func ignoresCriterion(family string, cn criterion.FilteredCriterion) bool {
func mostPreferredTag(family string, segments []segmentTypes.Segment) segmentTypes.DetectionTag {
if len(segments) == 0 {
return segmentTypes.DetectionTag("")
}

s := slices.MaxFunc(segments, func(x, y segmentTypes.Segment) int {
return tagPreference(family, string(x.Tag)) - tagPreference(family, string(y.Tag))
})
return s.Tag
}

func resolvePackageByTag(family string, x, y pack) pack {
if tagPreference(family, string(x.tag)) < tagPreference(family, string(y.tag)) {
return y
}
return x
}

func resolveAdvisoryByTag(family string, x, y taggedAdvisory) taggedAdvisory {
if tagPreference(family, string(x.tag)) < tagPreference(family, string(y.tag)) {
return y
}
return x
}

func tagPreference(family string, tag string) int {
switch family {
case constant.RedHat, constant.CentOS:
switch {
case strings.HasSuffix(tag, "-including-unpatched"):
return 4
case strings.HasSuffix(tag, "-extras-including-unpatched"):
return 3
case strings.HasSuffix(tag, "-supplementary"):
return 2
default:
return 1
}
default:
return 1
}
}

func ignoresVulnerability(family string, v vulnerabilityTypes.Vulnerability, a *advisoryTypes.Advisory) bool {
switch family {
case constant.RedHat, constant.CentOS:
if a == nil && strings.Contains(v.Content.Description, "** REJECT **") {
return true
}
if a != nil && strings.Contains(a.Content.Description, "** REJECT **") {
return true
}
return false
default:
return false
}
}

func ignoresCriterion(family string, cn criterionTypes.FilteredCriterion) bool {
switch family {
case constant.RedHat, constant.CentOS, constant.Alma, constant.Rocky:
if cn.Criterion.Version.FixStatus != nil && cn.Criterion.Version.FixStatus.Class == fixstatus.ClassUnfixed {
if cn.Criterion.Version.FixStatus != nil && cn.Criterion.Version.FixStatus.Class == fixstatusTypes.ClassUnfixed {
switch cn.Criterion.Version.FixStatus.Vendor {
case "Will not fix", "Under investigation":
return true
Expand All @@ -69,11 +133,21 @@ func ignoresCriterion(family string, cn criterion.FilteredCriterion) bool {
}
}

func ignoresWholeCriteria(family string, cn criterion.FilteredCriterion) bool {
func ignoresWholeCriteria(family string, cn criterionTypes.FilteredCriterion) bool {
switch family {
case constant.RedHat, constant.CentOS, constant.Alma, constant.Rocky:
// Ignore whole criteria from root if kpatch-patch-* package is included.
return cn.Criterion.Type == criterion.CriterionTypeVersion && strings.HasPrefix(cn.Criterion.Version.Package.Name, "kpatch-patch-")
if cn.Criterion.Type == criterionTypes.CriterionTypeVersion && cn.Criterion.Version != nil &&
cn.Criterion.Version.Package.Type == versioncriterionpackageTypes.PackageTypeBinary && cn.Criterion.Version.Package.Binary != nil &&
strings.HasPrefix(cn.Criterion.Version.Package.Binary.Name, "kpatch-patch-") {
return true
}
if cn.Criterion.Type == criterionTypes.CriterionTypeNoneExist && cn.Criterion.NoneExist != nil &&
cn.Criterion.NoneExist.Type == noneexistcriterionTypes.PackageTypeBinary && cn.Criterion.NoneExist.Binary != nil &&
strings.HasPrefix(cn.Criterion.NoneExist.Binary.Name, "kpatch-patch-") {
return true
}
return false
default:
return false
}
Expand Down Expand Up @@ -112,10 +186,10 @@ func cveContentSourceLink(ccType models.CveContentType, v vulnerabilityTypes.Vul
}
}

func overwritesByNewVulnInfo(family, baseSourceID, newSourceID string) bool {
func resolveSourceVulnInfo(family string, x, y sourceVulnInfo) sourceVulnInfo {
switch family {
case constant.RedHat, constant.CentOS:
favorFunc := func(sourceID string) int {
preferenceFn := func(sourceID string) int {
switch sourceID {
case "redhat-csaf":
return 4
Expand All @@ -127,12 +201,27 @@ func overwritesByNewVulnInfo(family, baseSourceID, newSourceID string) bool {
return 1
}
}
return favorFunc(baseSourceID) < favorFunc(newSourceID)
if cmp.Or(
preferenceFn(string(x.sourceID))-preferenceFn(string(y.sourceID)),
tagPreference(family, string(x.tag))-tagPreference(family, string(y.tag)),
) < 0 {
return y
}
return x
default:
return true
return x
}
}

func affectedPackageName(family string, pkg scanTypes.OSPackage) string {
switch family {
case constant.RedHat, constant.CentOS, constant.Alma, constant.Rocky:
return pkg.Name
default:
// for families that uses source name in detecting vulnerabilities
return pkg.SrcName
}
}
func cveContentOptional(family string, rootID dataTypes.RootID, sourceID sourceTypes.SourceID) map[string]string {
switch family {
case constant.RedHat, constant.CentOS:
Expand Down
Loading

0 comments on commit 9e32f8f

Please sign in to comment.