diff --git a/models/cvecontents.go b/models/cvecontents.go index f86607d2..6fa75853 100644 --- a/models/cvecontents.go +++ b/models/cvecontents.go @@ -160,7 +160,7 @@ func (v CveContents) MaxCvss2Score() CveContentCvss { return value } - // If CVSS score isn't on NVD, RedHat and JVN use OVAL's Severity information. + // If CVSS score isn't on NVD, RedHat and JVN, use OVAL's Severity information. // Convert severity to cvss srore, then returns max severity. // Only Ubuntu, RedHat and Oracle OVAL has severity data. order = []CveContentType{Ubuntu, RedHat, Oracle} diff --git a/scan/debian.go b/scan/debian.go index e1609d63..a3601305 100644 --- a/scan/debian.go +++ b/scan/debian.go @@ -18,6 +18,7 @@ along with this program. If not, see . package scan import ( + "bufio" "fmt" "regexp" "strconv" @@ -28,6 +29,8 @@ import ( "github.com/future-architect/vuls/config" "github.com/future-architect/vuls/models" "github.com/future-architect/vuls/util" + + "github.com/knqyf263/go-deb-version" ) // inherit OsTypeInterface @@ -571,9 +574,6 @@ func (o *debian) scanPackageCveIDs(pack models.Package) ([]DetectedCveID, *model return cveIDs, clogFilledPack, nil } -// Debian Version Numbers -// https://readme.phys.ethz.ch/documentation/debian_version_numbers/ -// TODO Changed to parse and compare versions func (o *debian) getCveIDsFromChangelog( changelog, name, ver string) ([]DetectedCveID, *models.Package) { @@ -636,25 +636,43 @@ func (o *debian) getCveIDsFromChangelog( var cveRe = regexp.MustCompile(`(CVE-\d{4}-\d{4,})`) // Collect CVE-IDs included in the changelog. -// The version which specified in argument(versionOrLater) is excluded. +// The version specified in argument(versionOrLater) is used to compare. func (o *debian) parseChangelog(changelog, name, ver string, confidence models.Confidence) ([]DetectedCveID, *models.Package, error) { + installedVer, err := version.NewVersion(ver) + if err != nil { + return nil, nil, fmt.Errorf("Failed to parse installed version: %s, %s", ver, err) + } buf, cveIDs := []string{}, []string{} - stopRe := regexp.MustCompile(fmt.Sprintf(`\(%s\)`, regexp.QuoteMeta(ver))) - stopLineFound := false - lines := strings.Split(changelog, "\n") - for _, line := range lines { + scanner := bufio.NewScanner(strings.NewReader(changelog)) + found := false + for scanner.Scan() { + line := scanner.Text() buf = append(buf, line) - if match := stopRe.MatchString(line); match { - // o.log.Debugf("Found the stop line: %s", line) - stopLineFound = true - break - } else if matches := cveRe.FindAllString(line, -1); 0 < len(matches) { + if matches := cveRe.FindAllString(line, -1); 0 < len(matches) { for _, m := range matches { cveIDs = util.AppendIfMissing(cveIDs, m) } } + + ss := strings.Fields(line) + if len(ss) < 2 { + continue + } + + if !strings.HasPrefix(ss[1], "(") || !strings.HasSuffix(ss[1], ")") { + continue + } + clogVer, err := version.NewVersion(ss[1][1 : len(ss[1])-1]) + if err != nil { + continue + } + if installedVer.Equal(clogVer) || installedVer.GreaterThan(clogVer) { + found = true + break + } } - if !stopLineFound { + + if !found { pack := o.Packages[name] pack.Changelog = models.Changelog{ Contents: "", @@ -666,7 +684,7 @@ func (o *debian) parseChangelog(changelog, name, ver string, confidence models.C } clog := models.Changelog{ - Contents: strings.Join(buf, "\n"), + Contents: strings.Join(buf[0:len(buf)-1], "\n"), Method: confidence.DetectionMethod, } pack := o.Packages[name] diff --git a/scan/debian_test.go b/scan/debian_test.go index 11492477..269214e9 100644 --- a/scan/debian_test.go +++ b/scan/debian_test.go @@ -66,7 +66,7 @@ func TestGetCveIDsFromChangelog(t *testing.T) { changelog models.Changelog }{ { - // verubuntu1 + //0 verubuntu1 []string{ "systemd", "228-4ubuntu1", @@ -81,9 +81,9 @@ systemd (228-4) unstable; urgency=medium systemd (228-3) unstable; urgency=medium`, }, []DetectedCveID{ - {"CVE-2015-2325", models.ChangelogLenientMatch}, - {"CVE-2015-2326", models.ChangelogLenientMatch}, - {"CVE-2015-3210", models.ChangelogLenientMatch}, + {"CVE-2015-2325", models.ChangelogExactMatch}, + {"CVE-2015-2326", models.ChangelogExactMatch}, + {"CVE-2015-3210", models.ChangelogExactMatch}, }, models.Changelog{ Contents: `systemd (229-2) unstable; urgency=medium @@ -92,13 +92,12 @@ systemd (228-6) unstable; urgency=medium CVE-2015-2325: heap buffer overflow in compile_branch(). (Closes: #781795) CVE-2015-2326: heap buffer overflow in pcre_compile2(). (Closes: #783285) CVE-2015-3210: heap buffer overflow in pcre_compile2() / -systemd (228-5) unstable; urgency=medium -systemd (228-4) unstable; urgency=medium`, - Method: models.ChangelogLenientMatchStr, +systemd (228-5) unstable; urgency=medium`, + Method: models.ChangelogExactMatchStr, }, }, { - // ver + //1 ver []string{ "libpcre3", "2:8.35-7.1ubuntu1", @@ -115,9 +114,9 @@ systemd (228-4) unstable; urgency=medium`, pcre3 (2:8.35-7) unstable; urgency=medium`, }, []DetectedCveID{ - {"CVE-2015-2325", models.ChangelogLenientMatch}, - {"CVE-2015-2326", models.ChangelogLenientMatch}, - {"CVE-2015-3210", models.ChangelogLenientMatch}, + {"CVE-2015-2325", models.ChangelogExactMatch}, + {"CVE-2015-2326", models.ChangelogExactMatch}, + {"CVE-2015-3210", models.ChangelogExactMatch}, }, models.Changelog{ Contents: `pcre3 (2:8.38-2) unstable; urgency=low @@ -128,13 +127,12 @@ systemd (228-4) unstable; urgency=medium`, pcre3 (2:8.35-7.2) unstable; urgency=low CVE-2015-2325: heap buffer overflow in compile_branch(). (Closes: #781795) CVE-2015-2326: heap buffer overflow in pcre_compile2(). (Closes: #783285) - CVE-2015-3210: heap buffer overflow in pcre_compile2() / - pcre3 (2:8.35-7.1) unstable; urgency=medium`, - Method: models.ChangelogLenientMatchStr, + CVE-2015-3210: heap buffer overflow in pcre_compile2() /`, + Method: models.ChangelogExactMatchStr, }, }, { - // ver-ubuntu3 + //2 ver-ubuntu3 []string{ "sysvinit", "2.88dsf-59.2ubuntu3", @@ -168,13 +166,12 @@ systemd (228-4) unstable; urgency=medium`, sysvinit (2.88dsf-59.3) unstable; urgency=medium CVE-2015-2325: heap buffer overflow in compile_branch(). (Closes: #781795) CVE-2015-2326: heap buffer overflow in pcre_compile2(). (Closes: #783285) - CVE-2015-3210: heap buffer overflow in pcre_compile2() / - sysvinit (2.88dsf-59.2ubuntu3) xenial; urgency=medium`, + CVE-2015-3210: heap buffer overflow in pcre_compile2() /`, Method: models.ChangelogExactMatchStr, }, }, { - // 1:ver-ubuntu3 + //3 1:ver-ubuntu3 []string{ "bsdutils", "1:2.27.1-1ubuntu3", @@ -192,25 +189,25 @@ systemd (228-4) unstable; urgency=medium`, util-linux (2.27-3ubuntu1) xenial; urgency=medium`, }, []DetectedCveID{ - {"CVE-2015-2325", models.ChangelogLenientMatch}, - {"CVE-2015-2326", models.ChangelogLenientMatch}, - {"CVE-2015-3210", models.ChangelogLenientMatch}, - {"CVE-2016-1000000", models.ChangelogLenientMatch}, + // {"CVE-2015-2325", models.ChangelogLenientMatch}, + // {"CVE-2015-2326", models.ChangelogLenientMatch}, + // {"CVE-2015-3210", models.ChangelogLenientMatch}, + // {"CVE-2016-1000000", models.ChangelogLenientMatch}, }, models.Changelog{ - Contents: `util-linux (2.27.1-3ubuntu1) xenial; urgency=medium - util-linux (2.27.1-3) unstable; urgency=medium - CVE-2015-2325: heap buffer overflow in compile_branch(). (Closes: #781795) - CVE-2015-2326: heap buffer overflow in pcre_compile2(). (Closes: #783285) - CVE-2015-3210: CVE-2016-1000000heap buffer overflow in pcre_compile2() / - util-linux (2.27.1-2) unstable; urgency=medium - util-linux (2.27.1-1ubuntu4) xenial; urgency=medium - util-linux (2.27.1-1ubuntu3) xenial; urgency=medium`, - Method: models.ChangelogLenientMatchStr, + // Contents: `util-linux (2.27.1-3ubuntu1) xenial; urgency=medium + // util-linux (2.27.1-3) unstable; urgency=medium + // CVE-2015-2325: heap buffer overflow in compile_branch(). (Closes: #781795) + // CVE-2015-2326: heap buffer overflow in pcre_compile2(). (Closes: #783285) + // CVE-2015-3210: CVE-2016-1000000heap buffer overflow in pcre_compile2() / + // util-linux (2.27.1-2) unstable; urgency=medium + // util-linux (2.27.1-1ubuntu4) xenial; urgency=medium + // util-linux (2.27.1-1ubuntu3) xenial; urgency=medium`, + Method: models.ChangelogExactMatchStr, }, }, { - // 1:ver-ubuntu3 + //4 1:ver-ubuntu3 []string{ "bsdutils", "1:2.27-3ubuntu3", @@ -228,29 +225,28 @@ systemd (228-4) unstable; urgency=medium`, util-linux (2.27-3) xenial; urgency=medium`, }, []DetectedCveID{ - {"CVE-2015-2325", models.ChangelogLenientMatch}, - {"CVE-2015-2326", models.ChangelogLenientMatch}, - {"CVE-2015-3210", models.ChangelogLenientMatch}, - {"CVE-2016-1000000", models.ChangelogLenientMatch}, + // {"CVE-2015-2325", models.ChangelogLenientMatch}, + // {"CVE-2015-2326", models.ChangelogLenientMatch}, + // {"CVE-2015-3210", models.ChangelogLenientMatch}, + // {"CVE-2016-1000000", models.ChangelogLenientMatch}, }, models.Changelog{ - Contents: `util-linux (2.27.1-3ubuntu1) xenial; urgency=medium - util-linux (2.27.1-3) unstable; urgency=medium - CVE-2015-2325: heap buffer overflow in compile_branch(). (Closes: #781795) - CVE-2015-2326: heap buffer overflow in pcre_compile2(). (Closes: #783285) - CVE-2015-3210: CVE-2016-1000000heap buffer overflow in pcre_compile2() / - util-linux (2.27.1-2) unstable; urgency=medium - util-linux (2.27.1-1ubuntu4) xenial; urgency=medium - util-linux (2.27.1-1ubuntu3) xenial; urgency=medium - util-linux (2.27.1-1ubuntu2) xenial; urgency=medium - util-linux (2.27.1-1ubuntu1) xenial; urgency=medium - util-linux (2.27.1-1) unstable; urgency=medium - util-linux (2.27-3) xenial; urgency=medium`, - Method: models.ChangelogLenientMatchStr, + // Contents: `util-linux (2.27.1-3ubuntu1) xenial; urgency=medium + // util-linux (2.27.1-3) unstable; urgency=medium + // CVE-2015-2325: heap buffer overflow in compile_branch(). (Closes: #781795) + // CVE-2015-2326: heap buffer overflow in pcre_compile2(). (Closes: #783285) + // CVE-2015-3210: CVE-2016-1000000heap buffer overflow in pcre_compile2() / + // util-linux (2.27.1-2) unstable; urgency=medium + // util-linux (2.27.1-1ubuntu4) xenial; urgency=medium + // util-linux (2.27.1-1ubuntu3) xenial; urgency=medium + // util-linux (2.27.1-1ubuntu2) xenial; urgency=medium + // util-linux (2.27.1-1ubuntu1) xenial; urgency=medium + // util-linux (2.27.1-1) unstable; urgency=medium`, + Method: models.ChangelogExactMatchStr, }, }, { - // https://github.com/future-architect/vuls/pull/350 + //5 https://github.com/future-architect/vuls/pull/350 []string{ "tar", "1.27.1-2+b1", @@ -259,13 +255,12 @@ systemd (228-4) unstable; urgency=medium`, tar (1.27.1-2) unstable; urgency=low`, }, []DetectedCveID{ - {"CVE-2016-6321", models.ChangelogLenientMatch}, + {"CVE-2016-6321", models.ChangelogExactMatch}, }, models.Changelog{ Contents: `tar (1.27.1-2+deb8u1) jessie-security; urgency=high - * CVE-2016-6321: Bypassing the extract path name. - tar (1.27.1-2) unstable; urgency=low`, - Method: models.ChangelogLenientMatchStr, + * CVE-2016-6321: Bypassing the extract path name.`, + Method: models.ChangelogExactMatchStr, }, }, } @@ -286,11 +281,11 @@ systemd (228-4) unstable; urgency=medium`, } if aPack.Changelog.Contents != tt.changelog.Contents { - t.Errorf(pp.Sprintf("expected: %s, actual: %s", tt.changelog.Contents, aPack.Changelog.Contents)) + t.Error(pp.Sprintf("[%d] expected: %s, actual: %s", i, tt.changelog.Contents, aPack.Changelog.Contents)) } if aPack.Changelog.Method != tt.changelog.Method { - t.Errorf(pp.Sprintf("expected: %s, actual: %s", tt.changelog.Method, aPack.Changelog.Method)) + t.Error(pp.Sprintf("[%d] expected: %s, actual: %s", i, tt.changelog.Method, aPack.Changelog.Method)) } } }