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

fix(scan): a bug of kernel Vulns detection on Ubuntu18 #818

Merged
merged 2 commits into from
May 23, 2019
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
2 changes: 1 addition & 1 deletion models/vulninfos.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
97 changes: 97 additions & 0 deletions oval/debian.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
package oval

import (
"fmt"

"github.com/future-architect/vuls/config"
"github.com/future-architect/vuls/models"
"github.com/future-architect/vuls/util"
Expand Down Expand Up @@ -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",
Expand Down Expand Up @@ -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
}
16 changes: 13 additions & 3 deletions oval/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
6 changes: 3 additions & 3 deletions oval/util_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,7 @@ func TestIsOvalDefAffected(t *testing.T) {
},
},
affected: true,
notFixedYet: true,
notFixedYet: false,
},
// 4. Ubuntu
// ovalpack.NotFixedYet == false
Expand Down Expand Up @@ -371,7 +371,7 @@ func TestIsOvalDefAffected(t *testing.T) {
},
},
affected: true,
notFixedYet: true,
notFixedYet: false,
},
// 7 RedHat
{
Expand Down Expand Up @@ -450,7 +450,7 @@ func TestIsOvalDefAffected(t *testing.T) {
},
},
affected: true,
notFixedYet: true,
notFixedYet: false,
},
// 10 RedHat
{
Expand Down