Merge pull request #379 from future-architect/fix-scan-confidence-on-debian

Fix scan confidence on Ubuntu/Debian/Raspbian #362
This commit is contained in:
Kota Kanbe
2017-03-13 21:03:12 +09:00
committed by GitHub
2 changed files with 71 additions and 69 deletions

View File

@@ -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
}
}

View File

@@ -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])
}
}