Skip to content

Commit

Permalink
Fix scan confidence on Ubuntu/Debian/Raspbian future-architect#362
Browse files Browse the repository at this point in the history
  • Loading branch information
kotakanbe authored and Alan Lapthorn committed May 11, 2017
1 parent df40835 commit 13a9476
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 68 deletions.
84 changes: 45 additions & 39 deletions scan/debian.go
Original file line number Diff line number Diff line change
Expand Up @@ -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]
verAfterColon = splittedByColon[1]
if cveIDs, relevant, err := o.parseChangelog(
changelog, name, verAfterColon, models.ChangelogLenientMatch); err == nil {
return cveIDs, relevant
}
}
cveIDs, relevantChangelog, err := o.parseChangelog(changelog, packName, ver)
if err == nil {
return cveIDs, relevantChangelog

delim := []string{"+", "~", "build"}
switch o.Distro.Family {
case "ubuntu":
delim = append(delim, "ubuntu")
case "debian":
case "Raspbian":
}

ver = strings.Split(ver, "ubuntu")[0]
if cveIDs, relevantChangelog, err := o.parseChangelog(changelog, packName, ver); err == nil {
return cveIDs, relevantChangelog
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,
Expand Down Expand Up @@ -605,56 +626,41 @@ 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)
if match := stopRe.MatchString(line); match {
// 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
}
}
Expand Down
54 changes: 25 additions & 29 deletions scan/debian_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ func TestParseScannedPackagesLineDebian(t *testing.T) {

}

func TestGetCveIDParsingChangelog(t *testing.T) {
func TestGetCveIDsFromChangelog(t *testing.T) {

var tests = []struct {
in []string
Expand All @@ -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
Expand All @@ -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,
},
},
{
Expand All @@ -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
Expand All @@ -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,
},
},
{
Expand Down Expand Up @@ -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,
},
},
Expand All @@ -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
Expand All @@ -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,
},
},
{
Expand All @@ -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
Expand All @@ -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,
},
},
{
Expand All @@ -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])
}
}

Expand Down

0 comments on commit 13a9476

Please sign in to comment.