Skip to content

Commit

Permalink
add FixedInVersions to check affected packages
Browse files Browse the repository at this point in the history
Signed-off-by: liang chenye <liangchenye@huawei.com>
  • Loading branch information
liangchenye committed Jul 12, 2016
1 parent f1498b1 commit cb42892
Show file tree
Hide file tree
Showing 22 changed files with 397 additions and 248 deletions.
10 changes: 5 additions & 5 deletions api/v1/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ Server: clair
"Description": "The parse_datetime function in GNU coreutils allows remote attackers to cause a denial of service (crash) or possibly execute arbitrary code via a crafted date string, as demonstrated by the \"--date=TZ=\"123\"345\" @1\" string to the touch or date command.",
"Link": "https://security-tracker.debian.org/tracker/CVE-2014-9471",
"Severity": "Low",
"FixedBy": "9.23-5"
"FixedBy": ">= 9.23-5"
}
]
}
Expand Down Expand Up @@ -289,7 +289,7 @@ POST http://localhost:6060/v1/namespaces/debian%3A8/vulnerabilities HTTP/1.1
{
"Name": "coreutils",
"NamespaceName": "debian:8",
"Version": "8.23-1"
"FixedInVersions": ">= 8.23-1"
}
]
}
Expand Down Expand Up @@ -322,7 +322,7 @@ Server: clair
{
"Name": "coreutils",
"NamespaceName": "debian:8",
"Version": "8.23-1"
"FixedInVersions": ">= 8.23-1"
}
]
}
Expand Down Expand Up @@ -373,7 +373,7 @@ Server: clair
{
"Name": "coreutils",
"NamespaceName": "debian:8",
"Version": "8.23-1"
"FixedInVersions": ">= 8.23-1"
}
]
}
Expand Down Expand Up @@ -592,7 +592,7 @@ Server: clair
{
"Name": "grep",
"NamespaceName": "debian:8",
"Version": "2.25"
"FixedInVersions": ">= 2.25"
}
]
},
Expand Down
27 changes: 14 additions & 13 deletions api/v1/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ func LayerFromDatabaseModel(dbLayer database.Layer, withFeatures, withVulnerabil
Metadata: dbVuln.Metadata,
}

if dbVuln.FixedBy != types.MaxVersion {
if dbVuln.FixedBy.String() != types.NewFixedInVersionsFromOV(types.OpGreaterEqual, types.MaxVersion).String() {
vuln.FixedBy = dbVuln.FixedBy.String()
}
feature.Vulnerabilities = append(feature.Vulnerabilities, vuln)
Expand Down Expand Up @@ -154,31 +154,32 @@ type Feature struct {
Name string `json:"Name,omitempty"`
NamespaceName string `json:"NamespaceName,omitempty"`
Version string `json:"Version,omitempty"`
FixedInVersions string `json:"FixedInVersions,omitempty"`
Vulnerabilities []Vulnerability `json:"Vulnerabilities,omitempty"`
AddedBy string `json:"AddedBy,omitempty"`
}

func FeatureFromDatabaseModel(dbFeatureVersion database.FeatureVersion) Feature {
versionStr := dbFeatureVersion.Version.String()
if versionStr == types.MaxVersion.String() {
versionStr = "None"
fixedInVersionsStr := dbFeatureVersion.FixedInVersions.String()
if fixedInVersionsStr == types.NewFixedInVersionsFromOV(types.OpGreaterEqual, types.MaxVersion).String() {
fixedInVersionsStr = "None"
}

return Feature{
Name: dbFeatureVersion.Feature.Name,
NamespaceName: dbFeatureVersion.Feature.Namespace.Name,
Version: versionStr,
AddedBy: dbFeatureVersion.AddedBy.Name,
Name: dbFeatureVersion.Feature.Name,
NamespaceName: dbFeatureVersion.Feature.Namespace.Name,
FixedInVersions: fixedInVersionsStr,
AddedBy: dbFeatureVersion.AddedBy.Name,
}
}

func (f Feature) DatabaseModel() (database.FeatureVersion, error) {
var version types.Version
if f.Version == "None" {
version = types.MaxVersion
var fivs types.FixedInVersions
if f.FixedInVersions == "None" {
fivs = types.NewFixedInVersionsFromOV(types.OpGreaterEqual, types.MaxVersion)
} else {
var err error
version, err = types.NewVersion(f.Version)
fivs, err = types.NewFixedInVersions(f.FixedInVersions)
if err != nil {
return database.FeatureVersion{}, err
}
Expand All @@ -189,7 +190,7 @@ func (f Feature) DatabaseModel() (database.FeatureVersion, error) {
Name: f.Name,
Namespace: database.Namespace{Name: f.NamespaceName},
},
Version: version,
FixedInVersions: fivs,
}, nil
}

Expand Down
9 changes: 5 additions & 4 deletions database/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,10 @@ type Feature struct {
type FeatureVersion struct {
Model

Feature Feature
Version types.Version
AffectedBy []Vulnerability
Feature Feature
Version types.Version
FixedInVersions types.FixedInVersions
AffectedBy []Vulnerability

// For output purposes. Only make sense when the feature version is in the context of an image.
AddedBy Layer
Expand All @@ -78,7 +79,7 @@ type Vulnerability struct {

// For output purposes. Only make sense when the vulnerability
// is already about a specific Feature/FeatureVersion.
FixedBy types.Version `json:",omitempty"`
FixedBy types.FixedInVersions `json:",omitempty"`
}

type MetadataMap map[string]interface{}
Expand Down
8 changes: 5 additions & 3 deletions database/pgsql/complex_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,8 @@ func TestRaceAffects(t *testing.T) {
Namespace: feature.Namespace,
FixedIn: []database.FeatureVersion{
{
Feature: feature,
Version: types.NewVersionUnsafe(strconv.Itoa(version)),
Feature: feature,
FixedInVersions: types.NewFixedInVersionsUnsafe(">=" + strconv.Itoa(version)),
},
},
Severity: types.Unknown,
Expand Down Expand Up @@ -149,7 +149,9 @@ func TestRaceAffects(t *testing.T) {
// Get expected affects.
for i := numVulnerabilities; i > featureVersionVersion; i-- {
for _, vulnerability := range vulnerabilities[i] {
expectedAffectedNames = append(expectedAffectedNames, vulnerability.Name)
if vulnerability.FixedIn[0].FixedInVersions.Affected(featureVersion.Version) {
expectedAffectedNames = append(expectedAffectedNames, vulnerability.Name)
}
}
}

Expand Down
8 changes: 3 additions & 5 deletions database/pgsql/feature.go
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ func (pgSQL *pgSQL) insertFeatureVersions(featureVersions []database.FeatureVers
type vulnerabilityAffectsFeatureVersion struct {
vulnerabilityID int
fixedInID int
fixedInVersion types.Version
fixedInVersions types.FixedInVersions
}

func linkFeatureVersionToVulnerabilities(tx *sql.Tx, featureVersion database.FeatureVersion) error {
Expand All @@ -210,14 +210,12 @@ func linkFeatureVersionToVulnerabilities(tx *sql.Tx, featureVersion database.Fea
for rows.Next() {
var affect vulnerabilityAffectsFeatureVersion

err := rows.Scan(&affect.fixedInID, &affect.vulnerabilityID, &affect.fixedInVersion)
err := rows.Scan(&affect.fixedInID, &affect.vulnerabilityID, &affect.fixedInVersions)
if err != nil {
return handleError("searchVulnerabilityFixedInFeature.Scan()", err)
}

if featureVersion.Version.Compare(affect.fixedInVersion) < 0 {
// The version of the FeatureVersion we are inserting is lower than the fixed version on this
// Vulnerability, thus, this FeatureVersion is affected by it.
if affect.fixedInVersions.Affected(featureVersion.Version) {
affects = append(affects, affect)
}
}
Expand Down
2 changes: 1 addition & 1 deletion database/pgsql/layer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ func TestFindLayer(t *testing.T) {
assert.Equal(t, types.High, featureVersion.AffectedBy[0].Severity)
assert.Equal(t, "A vulnerability affecting OpenSSL < 2.0 on Debian 7.0", featureVersion.AffectedBy[0].Description)
assert.Equal(t, "http://google.com/#q=CVE-OPENSSL-1-DEB7", featureVersion.AffectedBy[0].Link)
assert.Equal(t, types.NewVersionUnsafe("2.0"), featureVersion.AffectedBy[0].FixedBy)
assert.Equal(t, types.NewFixedInVersionsUnsafe(">= 2.0").String(), featureVersion.AffectedBy[0].FixedBy.String())
}
default:
t.Errorf("unexpected package %s for layer-1", featureVersion.Feature.Name)
Expand Down
12 changes: 6 additions & 6 deletions database/pgsql/notification_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,8 @@ func TestNotification(t *testing.T) {
Severity: "Unknown",
FixedIn: []database.FeatureVersion{
{
Feature: f1,
Version: types.NewVersionUnsafe("1.0"),
Feature: f1,
FixedInVersions: types.NewFixedInVersionsUnsafe(">= 1.0"),
},
},
}
Expand Down Expand Up @@ -164,12 +164,12 @@ func TestNotification(t *testing.T) {
v1b.Severity = types.High
v1b.FixedIn = []database.FeatureVersion{
{
Feature: f1,
Version: types.MinVersion,
Feature: f1,
FixedInVersions: types.NewFixedInVersionsFromOV(types.OpGreaterEqual, types.MinVersion),
},
{
Feature: f2,
Version: types.MaxVersion,
Feature: f2,
FixedInVersions: types.NewFixedInVersionsFromOV(types.OpGreaterEqual, types.MaxVersion),
},
}

Expand Down
4 changes: 2 additions & 2 deletions database/pgsql/testdata/data.sql
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ INSERT INTO vulnerability (id, namespace_id, name, description, link, severity)
(2, 1, 'CVE-NOPE', 'A vulnerability affecting nothing', '', 'Unknown');

INSERT INTO vulnerability_fixedin_feature (id, vulnerability_id, feature_id, version) VALUES
(1, 1, 2, '2.0'),
(2, 1, 4, '1.9-abc');
(1, 1, 2, '>= 2.0'),
(2, 1, 4, '>= 1.9-abc');

INSERT INTO vulnerability_affects_featureversion (id, vulnerability_id, featureversion_id, fixedin_id) VALUES
(1, 1, 2, 1); -- CVE-OPENSSL-1-DEB7 affects Debian:7 OpenSSL 1.0
Expand Down
25 changes: 11 additions & 14 deletions database/pgsql/vulnerability.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,11 +140,11 @@ func scanVulnerability(queryer Queryer, queryName string, vulnerabilityRow *sql.

for rows.Next() {
var featureVersionID zero.Int
var featureVersionVersion zero.String
var featureVersionFixedInVersions zero.String
var featureVersionFeatureName zero.String

err := rows.Scan(
&featureVersionVersion,
&featureVersionFixedInVersions,
&featureVersionID,
&featureVersionFeatureName,
)
Expand All @@ -163,7 +163,7 @@ func scanVulnerability(queryer Queryer, queryName string, vulnerabilityRow *sql.
Namespace: vulnerability.Namespace,
Name: featureVersionFeatureName.String,
},
Version: types.NewVersionUnsafe(featureVersionVersion.String),
FixedInVersions: types.NewFixedInVersionsUnsafe(featureVersionFixedInVersions.String),
}
vulnerability.FixedIn = append(vulnerability.FixedIn, featureVersion)
}
Expand Down Expand Up @@ -274,7 +274,7 @@ func (pgSQL *pgSQL) insertVulnerability(vulnerability database.Vulnerability, on
// for diffing existing vulnerabilities.
var fixedIn []database.FeatureVersion
for _, fv := range vulnerability.FixedIn {
if fv.Version != types.MinVersion {
if fv.FixedInVersions.String() != types.NewFixedInVersionsFromOV(types.OpGreaterEqual, types.MinVersion).String() {
fixedIn = append(fixedIn, fv)
}
}
Expand Down Expand Up @@ -350,7 +350,7 @@ func applyFixedInDiff(currentList, diff []database.FeatureVersion) ([]database.F
different := false

for _, name := range addedNames {
if diffMap[name].Version == types.MinVersion {
if diffMap[name].FixedInVersions.String() == types.NewFixedInVersionsFromOV(types.OpGreaterEqual, types.MinVersion).String() {
// MinVersion only makes sense when a Feature is already fixed in some version,
// in which case we would be in the "inBothNames".
continue
Expand All @@ -363,7 +363,7 @@ func applyFixedInDiff(currentList, diff []database.FeatureVersion) ([]database.F
for _, name := range inBothNames {
fv := diffMap[name]

if fv.Version == types.MinVersion {
if fv.FixedInVersions.String() == types.NewFixedInVersionsFromOV(types.OpGreaterEqual, types.MinVersion).String() {
// MinVersion means that the Feature doesn't affect the Vulnerability anymore.
delete(currentMap, name)
different = true
Expand Down Expand Up @@ -438,15 +438,15 @@ func (pgSQL *pgSQL) insertVulnerabilityFixedInFeatureVersions(tx *sql.Tx, vulner
err = tx.QueryRow(
insertVulnerabilityFixedInFeature,
vulnerabilityID, fv.Feature.ID,
&fv.Version,
&fv.FixedInVersions,
).Scan(&fixedInID)

if err != nil {
return handleError("insertVulnerabilityFixedInFeature", err)
}

// Insert Vulnerability_Affects_FeatureVersion.
err = linkVulnerabilityToFeatureVersions(tx, fixedInID, vulnerabilityID, fv.Feature.ID, fv.Version)
err = linkVulnerabilityToFeatureVersions(tx, fixedInID, vulnerabilityID, fv.Feature.ID, fv.FixedInVersions)
if err != nil {
return err
}
Expand All @@ -455,7 +455,7 @@ func (pgSQL *pgSQL) insertVulnerabilityFixedInFeatureVersions(tx *sql.Tx, vulner
return nil
}

func linkVulnerabilityToFeatureVersions(tx *sql.Tx, fixedInID, vulnerabilityID, featureID int, fixedInVersion types.Version) error {
func linkVulnerabilityToFeatureVersions(tx *sql.Tx, fixedInID, vulnerabilityID, featureID int, fixedInVersions types.FixedInVersions) error {
// Find every FeatureVersions of the Feature that the vulnerability affects.
// TODO(Quentin-M): LIMIT
rows, err := tx.Query(searchFeatureVersionByFeature, featureID)
Expand All @@ -472,10 +472,7 @@ func linkVulnerabilityToFeatureVersions(tx *sql.Tx, fixedInID, vulnerabilityID,
if err != nil {
return handleError("searchFeatureVersionByFeature.Scan()", err)
}

if affected.Version.Compare(fixedInVersion) < 0 {
// The version of the FeatureVersion is lower than the fixed version of this vulnerability,
// thus, this FeatureVersion is affected by it.
if fixedInVersions.Affected(affected.Version) {
affecteds = append(affecteds, affected)
}
}
Expand Down Expand Up @@ -527,7 +524,7 @@ func (pgSQL *pgSQL) DeleteVulnerabilityFix(vulnerabilityNamespace, vulnerability
Name: vulnerabilityNamespace,
},
},
Version: types.MinVersion,
FixedInVersions: types.NewFixedInVersionsFromOV(types.OpGreaterEqual, types.MinVersion),
},
},
}
Expand Down
24 changes: 12 additions & 12 deletions database/pgsql/vulnerability_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,12 @@ func TestFindVulnerability(t *testing.T) {
Namespace: database.Namespace{Name: "debian:7"},
FixedIn: []database.FeatureVersion{
{
Feature: database.Feature{Name: "openssl"},
Version: types.NewVersionUnsafe("2.0"),
Feature: database.Feature{Name: "openssl"},
FixedInVersions: types.NewFixedInVersionsUnsafe(">= 2.0"),
},
{
Feature: database.Feature{Name: "libssl"},
Version: types.NewVersionUnsafe("1.9-abc"),
Feature: database.Feature{Name: "libssl"},
FixedInVersions: types.NewFixedInVersionsUnsafe(">= 1.9-abc"),
},
},
}
Expand Down Expand Up @@ -114,50 +114,50 @@ func TestInsertVulnerability(t *testing.T) {
Name: "TestInsertVulnerabilityFeatureVersion1",
Namespace: n1,
},
Version: types.NewVersionUnsafe("1.0"),
FixedInVersions: types.NewFixedInVersionsUnsafe(">= 1.0"),
}
f2 := database.FeatureVersion{
Feature: database.Feature{
Name: "TestInsertVulnerabilityFeatureVersion1",
Namespace: n2,
},
Version: types.NewVersionUnsafe("1.0"),
FixedInVersions: types.NewFixedInVersionsUnsafe(">= 1.0"),
}
f3 := database.FeatureVersion{
Feature: database.Feature{
Name: "TestInsertVulnerabilityFeatureVersion2",
},
Version: types.MaxVersion,
FixedInVersions: types.NewFixedInVersionsFromOV(types.OpGreaterEqual, types.MaxVersion),
}
f4 := database.FeatureVersion{
Feature: database.Feature{
Name: "TestInsertVulnerabilityFeatureVersion2",
},
Version: types.NewVersionUnsafe("1.4"),
FixedInVersions: types.NewFixedInVersionsUnsafe(">= 1.4"),
}
f5 := database.FeatureVersion{
Feature: database.Feature{
Name: "TestInsertVulnerabilityFeatureVersion3",
},
Version: types.NewVersionUnsafe("1.5"),
FixedInVersions: types.NewFixedInVersionsUnsafe(">= 1.5"),
}
f6 := database.FeatureVersion{
Feature: database.Feature{
Name: "TestInsertVulnerabilityFeatureVersion4",
},
Version: types.NewVersionUnsafe("0.1"),
FixedInVersions: types.NewFixedInVersionsUnsafe(">= 0.1"),
}
f7 := database.FeatureVersion{
Feature: database.Feature{
Name: "TestInsertVulnerabilityFeatureVersion5",
},
Version: types.MaxVersion,
FixedInVersions: types.NewFixedInVersionsFromOV(types.OpGreaterEqual, types.MaxVersion),
}
f8 := database.FeatureVersion{
Feature: database.Feature{
Name: "TestInsertVulnerabilityFeatureVersion5",
},
Version: types.MinVersion,
FixedInVersions: types.NewFixedInVersionsFromOV(types.OpGreaterEqual, types.MinVersion),
}

// Insert invalid vulnerabilities.
Expand Down
Loading

0 comments on commit cb42892

Please sign in to comment.