Fix scan confidence on Ubuntu/Debian/Raspbian #362
This commit is contained in:
		@@ -544,38 +544,59 @@ func (o *debian) scanPackageCveIDs(pack models.PackageInfo) ([]DetectedCveID, er
 | 
			
		||||
	return cveIDs, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (o *debian) getCveIDsFromChangelog(changelog string,
 | 
			
		||||
	packName string, versionOrLater string) ([]DetectedCveID, models.Changelog) {
 | 
			
		||||
// Debian Version Numbers
 | 
			
		||||
// https://readme.phys.ethz.ch/documentation/debian_version_numbers/
 | 
			
		||||
func (o *debian) getCveIDsFromChangelog(
 | 
			
		||||
	changelog, name, ver string) ([]DetectedCveID, models.Changelog) {
 | 
			
		||||
 | 
			
		||||
	if cveIDs, relevantChangelog, err := o.parseChangelog(changelog, packName, versionOrLater); err == nil {
 | 
			
		||||
		return cveIDs, relevantChangelog
 | 
			
		||||
	if cveIDs, relevant, err := o.parseChangelog(
 | 
			
		||||
		changelog, name, ver, models.ChangelogExactMatch); err == nil {
 | 
			
		||||
		return cveIDs, relevant
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	//TODO switch case ubuntu, debian
 | 
			
		||||
	ver := strings.Split(versionOrLater, "ubuntu")[0]
 | 
			
		||||
	if cveIDs, relevantChangelog, err := o.parseChangelog(changelog, packName, ver); err == nil {
 | 
			
		||||
		return cveIDs, relevantChangelog
 | 
			
		||||
	}
 | 
			
		||||
	var verAfterColon string
 | 
			
		||||
	var err error
 | 
			
		||||
 | 
			
		||||
	splittedByColon := strings.Split(versionOrLater, ":")
 | 
			
		||||
	splittedByColon := strings.Split(ver, ":")
 | 
			
		||||
	if 1 < len(splittedByColon) {
 | 
			
		||||
		ver = splittedByColon[1]
 | 
			
		||||
	}
 | 
			
		||||
	cveIDs, relevantChangelog, err := o.parseChangelog(changelog, packName, ver)
 | 
			
		||||
	if err == nil {
 | 
			
		||||
		return cveIDs, relevantChangelog
 | 
			
		||||
		verAfterColon = splittedByColon[1]
 | 
			
		||||
		if cveIDs, relevant, err := o.parseChangelog(
 | 
			
		||||
			changelog, name, verAfterColon, models.ChangelogLenientMatch); err == nil {
 | 
			
		||||
			return cveIDs, relevant
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ver = strings.Split(ver, "ubuntu")[0]
 | 
			
		||||
	if cveIDs, relevantChangelog, err := o.parseChangelog(changelog, packName, ver); err == nil {
 | 
			
		||||
		return cveIDs, relevantChangelog
 | 
			
		||||
	delim := []string{"+", "~", "build"}
 | 
			
		||||
	switch o.Distro.Family {
 | 
			
		||||
	case "ubuntu":
 | 
			
		||||
		delim = append(delim, "ubuntu")
 | 
			
		||||
	case "debian":
 | 
			
		||||
	case "Raspbian":
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for _, d := range delim {
 | 
			
		||||
		ss := strings.Split(ver, d)
 | 
			
		||||
		if 1 < len(ss) {
 | 
			
		||||
			if cveIDs, relevant, err := o.parseChangelog(
 | 
			
		||||
				changelog, name, ss[0], models.ChangelogLenientMatch); err == nil {
 | 
			
		||||
				return cveIDs, relevant
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		ss = strings.Split(verAfterColon, d)
 | 
			
		||||
		if 1 < len(ss) {
 | 
			
		||||
			if cveIDs, relevant, err := o.parseChangelog(
 | 
			
		||||
				changelog, name, ss[0], models.ChangelogLenientMatch); err == nil {
 | 
			
		||||
				return cveIDs, relevant
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Only logging the error.
 | 
			
		||||
	o.log.Error(err)
 | 
			
		||||
 | 
			
		||||
	for i, p := range o.Packages {
 | 
			
		||||
		if p.Name == packName {
 | 
			
		||||
		if p.Name == name {
 | 
			
		||||
			o.Packages[i].Changelog = models.Changelog{
 | 
			
		||||
				Contents: "",
 | 
			
		||||
				Method:   models.FailedToFindVersionInChangelog,
 | 
			
		||||
@@ -605,17 +626,10 @@ 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.
 | 
			
		||||
func (o *debian) parseChangelog(changelog string, packName string, versionOrLater string) ([]DetectedCveID, models.Changelog, error) {
 | 
			
		||||
 | 
			
		||||
func (o *debian) parseChangelog(changelog, name, ver string, confidence models.Confidence) ([]DetectedCveID, models.Changelog, error) {
 | 
			
		||||
	buf, cveIDs := []string{}, []string{}
 | 
			
		||||
	stopRe := regexp.MustCompile(fmt.Sprintf(`\(%s\)`, regexp.QuoteMeta(versionOrLater)))
 | 
			
		||||
	stopRe := regexp.MustCompile(fmt.Sprintf(`\(%s\)`, regexp.QuoteMeta(ver)))
 | 
			
		||||
	stopLineFound := false
 | 
			
		||||
	lenientStopLineFound := false
 | 
			
		||||
	versionOrLaterlenient := versionOrLater
 | 
			
		||||
	if i := strings.IndexRune(versionOrLaterlenient, '+'); i >= 0 {
 | 
			
		||||
		versionOrLaterlenient = versionOrLaterlenient[:i]
 | 
			
		||||
	}
 | 
			
		||||
	lenientRe := regexp.MustCompile(fmt.Sprintf(`\(%s\)`, regexp.QuoteMeta(versionOrLaterlenient)))
 | 
			
		||||
	lines := strings.Split(changelog, "\n")
 | 
			
		||||
	for _, line := range lines {
 | 
			
		||||
		buf = append(buf, line)
 | 
			
		||||
@@ -623,38 +637,30 @@ func (o *debian) parseChangelog(changelog string, packName string, versionOrLate
 | 
			
		||||
			//  o.log.Debugf("Found the stop line: %s", line)
 | 
			
		||||
			stopLineFound = true
 | 
			
		||||
			break
 | 
			
		||||
		} else if matchl := lenientRe.MatchString(line); matchl {
 | 
			
		||||
			lenientStopLineFound = true
 | 
			
		||||
			break
 | 
			
		||||
		} else if matches := cveRe.FindAllString(line, -1); 0 < len(matches) {
 | 
			
		||||
			for _, m := range matches {
 | 
			
		||||
				cveIDs = util.AppendIfMissing(cveIDs, m)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if !stopLineFound && !lenientStopLineFound {
 | 
			
		||||
	if !stopLineFound {
 | 
			
		||||
		return nil, models.Changelog{
 | 
			
		||||
				Contents: "",
 | 
			
		||||
				Method:   models.FailedToFindVersionInChangelog,
 | 
			
		||||
			}, fmt.Errorf(
 | 
			
		||||
				"Failed to scan CVE IDs. The version is not in changelog. name: %s, version: %s",
 | 
			
		||||
				packName,
 | 
			
		||||
				versionOrLater,
 | 
			
		||||
				name,
 | 
			
		||||
				ver,
 | 
			
		||||
			)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	confidence := models.ChangelogExactMatch
 | 
			
		||||
	if lenientStopLineFound {
 | 
			
		||||
		confidence = models.ChangelogLenientMatch
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	clog := models.Changelog{
 | 
			
		||||
		Contents: strings.Join(buf, "\n"),
 | 
			
		||||
		Method:   string(confidence.DetectionMethod),
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for i, p := range o.Packages {
 | 
			
		||||
		if p.Name == packName {
 | 
			
		||||
		if p.Name == name {
 | 
			
		||||
			o.Packages[i].Changelog = clog
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
@@ -58,7 +58,7 @@ func TestParseScannedPackagesLineDebian(t *testing.T) {
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestGetCveIDParsingChangelog(t *testing.T) {
 | 
			
		||||
func TestGetCveIDsFromChangelog(t *testing.T) {
 | 
			
		||||
 | 
			
		||||
	var tests = []struct {
 | 
			
		||||
		in        []string
 | 
			
		||||
@@ -81,9 +81,9 @@ systemd (228-4) unstable; urgency=medium
 | 
			
		||||
systemd (228-3) unstable; urgency=medium`,
 | 
			
		||||
			},
 | 
			
		||||
			[]DetectedCveID{
 | 
			
		||||
				{"CVE-2015-2325", models.ChangelogExactMatch},
 | 
			
		||||
				{"CVE-2015-2326", models.ChangelogExactMatch},
 | 
			
		||||
				{"CVE-2015-3210", models.ChangelogExactMatch},
 | 
			
		||||
				{"CVE-2015-2325", models.ChangelogLenientMatch},
 | 
			
		||||
				{"CVE-2015-2326", models.ChangelogLenientMatch},
 | 
			
		||||
				{"CVE-2015-3210", models.ChangelogLenientMatch},
 | 
			
		||||
			},
 | 
			
		||||
			models.Changelog{
 | 
			
		||||
				Contents: `systemd (229-2) unstable; urgency=medium
 | 
			
		||||
@@ -94,8 +94,7 @@ 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`,
 | 
			
		||||
				//TODO
 | 
			
		||||
				Method: models.ChangelogExactMatchStr,
 | 
			
		||||
				Method: models.ChangelogLenientMatchStr,
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
@@ -116,9 +115,9 @@ systemd (228-4) unstable; urgency=medium`,
 | 
			
		||||
		 pcre3 (2:8.35-7) unstable; urgency=medium`,
 | 
			
		||||
			},
 | 
			
		||||
			[]DetectedCveID{
 | 
			
		||||
				{"CVE-2015-2325", models.ChangelogExactMatch},
 | 
			
		||||
				{"CVE-2015-2326", models.ChangelogExactMatch},
 | 
			
		||||
				{"CVE-2015-3210", models.ChangelogExactMatch},
 | 
			
		||||
				{"CVE-2015-2325", models.ChangelogLenientMatch},
 | 
			
		||||
				{"CVE-2015-2326", models.ChangelogLenientMatch},
 | 
			
		||||
				{"CVE-2015-3210", models.ChangelogLenientMatch},
 | 
			
		||||
			},
 | 
			
		||||
			models.Changelog{
 | 
			
		||||
				Contents: `pcre3 (2:8.38-2) unstable; urgency=low
 | 
			
		||||
@@ -131,8 +130,7 @@ systemd (228-4) unstable; urgency=medium`,
 | 
			
		||||
		 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`,
 | 
			
		||||
				//TODO
 | 
			
		||||
				Method: models.ChangelogExactMatchStr,
 | 
			
		||||
				Method: models.ChangelogLenientMatchStr,
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
@@ -172,7 +170,6 @@ systemd (228-4) unstable; urgency=medium`,
 | 
			
		||||
		 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`,
 | 
			
		||||
				//TODO
 | 
			
		||||
				Method: models.ChangelogExactMatchStr,
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
@@ -195,10 +192,10 @@ systemd (228-4) unstable; urgency=medium`,
 | 
			
		||||
		 util-linux (2.27-3ubuntu1) xenial; urgency=medium`,
 | 
			
		||||
			},
 | 
			
		||||
			[]DetectedCveID{
 | 
			
		||||
				{"CVE-2015-2325", models.ChangelogExactMatch},
 | 
			
		||||
				{"CVE-2015-2326", models.ChangelogExactMatch},
 | 
			
		||||
				{"CVE-2015-3210", models.ChangelogExactMatch},
 | 
			
		||||
				{"CVE-2016-1000000", models.ChangelogExactMatch},
 | 
			
		||||
				{"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
 | 
			
		||||
@@ -209,8 +206,7 @@ systemd (228-4) unstable; urgency=medium`,
 | 
			
		||||
		 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`,
 | 
			
		||||
				//TODO
 | 
			
		||||
				Method: models.ChangelogExactMatchStr,
 | 
			
		||||
				Method: models.ChangelogLenientMatchStr,
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
@@ -232,10 +228,10 @@ systemd (228-4) unstable; urgency=medium`,
 | 
			
		||||
		 util-linux (2.27-3) xenial; urgency=medium`,
 | 
			
		||||
			},
 | 
			
		||||
			[]DetectedCveID{
 | 
			
		||||
				{"CVE-2015-2325", models.ChangelogExactMatch},
 | 
			
		||||
				{"CVE-2015-2326", models.ChangelogExactMatch},
 | 
			
		||||
				{"CVE-2015-3210", models.ChangelogExactMatch},
 | 
			
		||||
				{"CVE-2016-1000000", models.ChangelogExactMatch},
 | 
			
		||||
				{"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
 | 
			
		||||
@@ -250,8 +246,7 @@ systemd (228-4) unstable; 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`,
 | 
			
		||||
				//TODO
 | 
			
		||||
				Method: models.ChangelogExactMatchStr,
 | 
			
		||||
				Method: models.ChangelogLenientMatchStr,
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
@@ -276,16 +271,17 @@ systemd (228-4) unstable; urgency=medium`,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	d := newDebian(config.ServerInfo{})
 | 
			
		||||
	for _, tt := range tests {
 | 
			
		||||
	d.Distro.Family = "ubuntu"
 | 
			
		||||
	for i, tt := range tests {
 | 
			
		||||
		aCveIDs, aClog := d.getCveIDsFromChangelog(tt.in[2], tt.in[0], tt.in[1])
 | 
			
		||||
		if len(aCveIDs) != len(tt.cveIDs) {
 | 
			
		||||
			t.Errorf("Len of return array are'nt same. expected %#v, actual %#v", tt.cveIDs, aCveIDs)
 | 
			
		||||
			t.Errorf("[%d] Len of return array are'nt same. expected %#v, actual %#v", i, tt.cveIDs, aCveIDs)
 | 
			
		||||
			t.Errorf(pp.Sprintf("%s", tt.in))
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		for i := range tt.cveIDs {
 | 
			
		||||
			if !reflect.DeepEqual(tt.cveIDs[i], aCveIDs[i]) {
 | 
			
		||||
				t.Errorf("expected %v, actual %v", tt.cveIDs[i], aCveIDs[i])
 | 
			
		||||
		for j := range tt.cveIDs {
 | 
			
		||||
			if !reflect.DeepEqual(tt.cveIDs[j], aCveIDs[j]) {
 | 
			
		||||
				t.Errorf("[%d] expected %v, actual %v", i, tt.cveIDs[j], aCveIDs[j])
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user