From 5811173c8eaf7bcf102a61bc84ab6786921a1310 Mon Sep 17 00:00:00 2001 From: Kota Kanbe Date: Thu, 23 May 2019 16:20:35 +0900 Subject: [PATCH 1/2] fix(scan): a bug of kernel Vulns detection on Ubuntu18 --- models/vulninfos.go | 2 +- oval/debian.go | 97 +++++++++++++++++++++++++++++++++++++++++++++ oval/util.go | 16 ++++++-- 3 files changed, 111 insertions(+), 4 deletions(-) diff --git a/models/vulninfos.go b/models/vulninfos.go index 2b6730dbde..52dc7adb49 100644 --- a/models/vulninfos.go +++ b/models/vulninfos.go @@ -562,7 +562,7 @@ func (v VulnInfo) AttackVector() string { return "" } -// PatchStatus returns attack vector string +// PatchStatus returns fixed or unfixed string func (v VulnInfo) PatchStatus(packs Packages) string { // Vuls don't know patch status of the CPE if len(v.CpeURIs) != 0 { diff --git a/oval/debian.go b/oval/debian.go index 69d4b774b0..4d037e528c 100644 --- a/oval/debian.go +++ b/oval/debian.go @@ -18,6 +18,8 @@ along with this program. If not, see . package oval import ( + "fmt" + "github.com/future-architect/vuls/config" "github.com/future-architect/vuls/models" "github.com/future-architect/vuls/util" @@ -189,6 +191,16 @@ func NewUbuntu() Ubuntu { // FillWithOval returns scan result after updating CVE info by OVAL func (o Ubuntu) FillWithOval(driver db.DB, r *models.ScanResult) (nCVEs int, err error) { + switch major(r.Release) { + case "14", "16": + return o.ubuntu1416(driver, r) + case "18": + return o.ubuntu18(driver, r) + } + return 0, fmt.Errorf("Ubuntu %s is not support for now", r.Release) +} + +func (o Ubuntu) ubuntu1416(driver db.DB, r *models.ScanResult) (nCVEs int, err error) { ovalKernelImageNames := []string{ "linux-aws", "linux-azure", @@ -282,3 +294,88 @@ func (o Ubuntu) FillWithOval(driver db.DB, r *models.ScanResult) (nCVEs int, err } return len(relatedDefs.entries), nil } + +func (o Ubuntu) ubuntu18(driver db.DB, r *models.ScanResult) (nCVEs int, err error) { + // kernel names in OVAL except for linux-image-generic + ovalKernelImageNames := []string{ + "linux-image-aws", + "linux-image-azure", + "linux-image-extra-virtual", + "linux-image-gcp", + "linux-image-generic-lpae", + "linux-image-kvm", + "linux-image-lowlatency", + "linux-image-oem", + "linux-image-oracle", + "linux-image-raspi2", + "linux-image-snapdragon", + "linux-image-virtual", + } + linuxImage := "linux-image-" + r.RunningKernel.Release + + const linuxImageGeneric = "linux-image-generic" + unusedKernels := []models.Package{} + found := false + if r.Container.ContainerID == "" { + if v, ok := r.Packages[linuxImage]; ok { + r.Packages[linuxImageGeneric] = models.Package{ + Name: linuxImageGeneric, + Version: v.Version, + NewVersion: v.NewVersion, + } + // remove unused kernels from packages + for _, n := range ovalKernelImageNames { + if v, ok := r.Packages[n]; ok { + unusedKernels = append(unusedKernels, v) + delete(r.Packages, n) + } + } + found = true + } else { + util.Log.Warnf("Running kernel image %s is not found in installed Packages. So all vulns for installed kernel wll be detected", + r.RunningKernel.Version) + } + } + + var relatedDefs ovalResult + if config.Conf.OvalDict.IsFetchViaHTTP() { + if relatedDefs, err = getDefsByPackNameViaHTTP(r); err != nil { + return 0, err + } + } else { + if relatedDefs, err = getDefsByPackNameFromOvalDB(driver, r); err != nil { + return 0, err + } + } + + if found { + delete(r.Packages, linuxImageGeneric) + for _, p := range unusedKernels { + r.Packages[p.Name] = p + } + } + + for _, defPacks := range relatedDefs.entries { + // Remove "linux" added above to search for oval + // "linux" is not a real package name (key of affected packages in OVAL) + if _, ok := defPacks.actuallyAffectedPackNames[linuxImageGeneric]; !found && ok { + defPacks.actuallyAffectedPackNames[linuxImage] = true + delete(defPacks.actuallyAffectedPackNames, linuxImageGeneric) + for i, p := range defPacks.def.AffectedPacks { + if p.Name == linuxImageGeneric { + p.Name = linuxImage + defPacks.def.AffectedPacks[i] = p + } + } + } + o.update(r, defPacks) + } + + for _, vuln := range r.ScannedCves { + if cont, ok := vuln.CveContents[models.Ubuntu]; ok { + cont.SourceLink = "http://people.ubuntu.com/~ubuntu-security/cve/" + cont.CveID + vuln.CveContents[models.Ubuntu] = cont + } + } + return len(relatedDefs.entries), nil +} diff --git a/oval/util.go b/oval/util.go index dec924f218..c3c1ef72ff 100644 --- a/oval/util.go +++ b/oval/util.go @@ -289,19 +289,29 @@ func isOvalDefAffected(def ovalmodels.Definition, req request, family string, ru return true, true } + // Compare between the installed version vs the version in OVAL less, err := lessThan(family, req.versionRelease, ovalPack) if err != nil { util.Log.Debugf("Failed to parse versions: %s, Ver: %#v, OVAL: %#v, DefID: %s", err, req.versionRelease, ovalPack, def.DefinitionID) return false, false } - if less { - if req.isSrcPack { - // Unable to judge whether fixed or not fixed of src package(Ubuntu, Debian) + // If the version of installed is less than in OVAL + switch family { + case config.RedHat, + config.Amazon, + config.SUSEEnterpriseServer, + config.Debian, + config.Ubuntu: + // Use fixed state in OVAL for these distros. return true, false } + // But CentOS can't judge whether fixed or unfixed. + // Because fixed state in RHEL's OVAL is different. + // So, it have to be judged version comparison. + // `offline` or `fast` scan mode can't get a updatable version. // In these mode, the blow field was set empty. // Vuls can not judge fixed or unfixed. From f488f012a0a08c0fd2d3e584a05b33b2deef766a Mon Sep 17 00:00:00 2001 From: Kota Kanbe Date: Thu, 23 May 2019 16:54:36 +0900 Subject: [PATCH 2/2] fix the test case --- oval/util_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/oval/util_test.go b/oval/util_test.go index 0073e9b615..e136441075 100644 --- a/oval/util_test.go +++ b/oval/util_test.go @@ -285,7 +285,7 @@ func TestIsOvalDefAffected(t *testing.T) { }, }, affected: true, - notFixedYet: true, + notFixedYet: false, }, // 4. Ubuntu // ovalpack.NotFixedYet == false @@ -371,7 +371,7 @@ func TestIsOvalDefAffected(t *testing.T) { }, }, affected: true, - notFixedYet: true, + notFixedYet: false, }, // 7 RedHat { @@ -450,7 +450,7 @@ func TestIsOvalDefAffected(t *testing.T) { }, }, affected: true, - notFixedYet: true, + notFixedYet: false, }, // 10 RedHat {