Compare commits

...

15 Commits

Author SHA1 Message Date
Quentin Machu
94bcf91cdf Merge pull request #263 from Quentin-M/rhel_unique_fixedin
pgsql: Do not insert entry in Vulnerability_FixedIn_Feature if existing
2016-11-14 12:00:58 -05:00
Jimmy Zelinskie
5157f27eac README: bump versions 1.2.5 2016-10-25 11:46:28 -04:00
Matt Moore
df1b2a13c4 Add Ubuntu yakkety to the namespace mapping. 2016-10-25 11:44:03 -04:00
Jimmy Zelinskie
ade5b2bb6b README: s/1.2.2/1.2.4 2016-10-25 11:43:35 -04:00
Jimmy Zelinskie
fd586bb39e Merge pull request #229 from vbatts/redhatrelease_detector
Redhatrelease detector
2016-09-06 15:06:45 -04:00
Jimmy Zelinskie
8d974c75ae Merge pull request #236 from robszumski/doc-link
readme: add link to docs dir
2016-08-24 14:03:50 -04:00
Rob Szumski
f0f69bb7ad readme: clarify docs on github 2016-08-24 10:56:06 -07:00
Rob Szumski
bf3be2ef1f readme: add link to docs dir 2016-08-24 10:25:32 -07:00
Jimmy Zelinskie
e714ca0688 Merge pull request #235 from jzelinskie/doc-move
docs: move to standard Documentation dir
2016-08-24 12:11:15 -04:00
Jimmy Zelinskie
cb5ba4debf readme: link docs to coreos.com 2016-08-24 11:19:52 -04:00
Jimmy Zelinskie
dbef1f8bce docs: move to standard Documentation dir 2016-08-23 17:11:30 -04:00
Quentin Machu
643ddc0cb4 updater: enable fetching of RHEL 5 vulnerabilities (#217)
The RHEL updater currently ignores vulnerabilities for CentOS <= 5.
s the naming of the constant firstConsideredRHEL suggests it, it
should actually considers CentOS 5 and ignores CentOS < 5.

Fixes #215
2016-07-15 19:04:38 +02:00
Fabian Ruff
cc22bd284c Switch to https for ubuntu cve tracker
Fixes #168
2016-05-25 20:27:39 -04:00
Jimmy Zelinskie
da446b65d6 pgsql: use subquery to plan GetNotification query (#182)
This change enables the query planner to wait and sort the result set of
our query rather than attempting to re-use the layer table's index for
the ORDER BY clause. Because the result set is always small, this makes
queries that were previous tens of seconds, now tens of milliseconds.
2016-05-20 13:28:19 -04:00
Jimmy Zelinskie
be3d697dc4 pgsql: remove unnecessary join used in GetNotification (#179) 2016-05-20 13:28:13 -04:00
13 changed files with 99 additions and 44 deletions

View File

@ -73,9 +73,9 @@ This runs a PostgreSQL database insecurely and locally in a container.
This method should only be used for testing.
```sh
$ curl -L https://raw.githubusercontent.com/coreos/clair/master/docker-compose.yml -o $HOME/docker-compose.yml
$ curl -L https://raw.githubusercontent.com/coreos/clair/v1.2.5/docker-compose.yml -o $HOME/docker-compose.yml
$ mkdir $HOME/clair_config
$ curl -L https://raw.githubusercontent.com/coreos/clair/master/config.example.yaml -o $HOME/clair_config/config.yaml
$ curl -L https://raw.githubusercontent.com/coreos/clair/v1.2.5/config.example.yaml -o $HOME/clair_config/config.yaml
$ $EDITOR $HOME/clair_config/config.yaml # Edit database source to be postgresql://postgres:password@postgres:5432?sslmode=disable
$ docker-compose -f $HOME/docker-compose.yml up -d
```
@ -93,9 +93,9 @@ This is the recommended method for production deployments.
```sh
$ mkdir $HOME/clair_config
$ curl -L https://raw.githubusercontent.com/coreos/clair/master/config.example.yaml -o $HOME/clair_config/config.yaml
$ curl -L https://raw.githubusercontent.com/coreos/clair/v1.2.5/config.example.yaml -o $HOME/clair_config/config.yaml
$ $EDITOR $HOME/clair_config/config.yaml # Add the URI for your postgres database
$ docker run -d -p 6060-6061:6060-6061 -v $HOME/clair_config:/config quay.io/coreos/clair -config=/config/config.yaml
$ docker run -d -p 6060-6061:6060-6061 -v $HOME/clair_config:/config quay.io/coreos/clair:v1.2.5 -config=/config/config.yaml
```
### Source
@ -119,10 +119,10 @@ $ ./$GOBIN/clair -config=config.yaml
## Documentation
Documentation can be found in a `README.md` file located in the directory of the component.
The latest stable documentation can be found [on the CoreOS website]. Documentation for the current branch can be found [inside the Documentation directory][docs-dir] at the root of the project's source code.
- [Notifier](https://github.com/coreos/clair/blob/master/notifier/README.md)
- [v1 API](https://github.com/coreos/clair/blob/master/api/v1/README.md)
[on the CoreOS website]: https://coreos.com/clair/docs/latest/
[docs-dir]: /Documentation
### Architecture at a Glance

View File

@ -40,4 +40,5 @@ var UbuntuReleasesMapping = map[string]string{
"vivid": "15.04",
"wily": "15.10",
"xenial": "16.04",
"yakkety": "16.10",
}

View File

@ -129,11 +129,11 @@ func (pgSQL *pgSQL) insertFeatureVersion(featureVersion database.FeatureVersion)
}
// Find or create FeatureVersion.
var newOrExisting string
var created bool
t = time.Now()
err = tx.QueryRow(soiFeatureVersion, featureID, &featureVersion.Version).
Scan(&newOrExisting, &featureVersion.ID)
Scan(&created, &featureVersion.ID)
observeQueryTime("insertFeatureVersion", "soiFeatureVersion", t)
if err != nil {
@ -141,8 +141,9 @@ func (pgSQL *pgSQL) insertFeatureVersion(featureVersion database.FeatureVersion)
return 0, handleError("soiFeatureVersion", err)
}
if newOrExisting == "exi" {
// That featureVersion already exists, return its id.
if !created {
// The featureVersion already existed, no need to link it to
// vulnerabilities.
tx.Commit()
if pgSQL.cache != nil {

View File

@ -63,9 +63,9 @@ const (
WHERE NOT EXISTS (SELECT id FROM FeatureVersion WHERE feature_id = $1 AND version = $2)
RETURNING id
)
SELECT 'exi', id FROM FeatureVersion WHERE feature_id = $1 AND version = $2
SELECT false, id FROM FeatureVersion WHERE feature_id = $1 AND version = $2
UNION
SELECT 'new', id FROM new_featureversion`
SELECT true, id FROM new_featureversion`
searchVulnerabilityFixedInFeature = `
SELECT id, vulnerability_id, version FROM Vulnerability_FixedIn_Feature
@ -160,10 +160,16 @@ const (
VALUES($1, $2, $3, $4, $5, $6, CURRENT_TIMESTAMP)
RETURNING id`
insertVulnerabilityFixedInFeature = `
INSERT INTO Vulnerability_FixedIn_Feature(vulnerability_id, feature_id, version)
VALUES($1, $2, $3)
RETURNING id`
soiVulnerabilityFixedInFeature = `
WITH new_fixedinfeature AS (
INSERT INTO Vulnerability_FixedIn_Feature(vulnerability_id, feature_id, version)
SELECT CAST($1 AS INTEGER), CAST($2 AS INTEGER), CAST($3 AS VARCHAR)
WHERE NOT EXISTS (SELECT id FROM Vulnerability_FixedIn_Feature WHERE vulnerability_id = $1 AND feature_id = $2)
RETURNING id
)
SELECT false, id FROM Vulnerability_FixedIn_Feature WHERE vulnerability_id = $1 AND feature_id = $2
UNION
SELECT true, id FROM new_fixedinfeature`
searchFeatureVersionByFeature = `SELECT id, version FROM FeatureVersion WHERE feature_id = $1`
@ -205,17 +211,22 @@ const (
WHERE name = $1`
searchNotificationLayerIntroducingVulnerability = `
WITH subquery AS (
SELECT l.ID, l.name
FROM Vulnerability v, Vulnerability_Affects_FeatureVersion vafv, FeatureVersion fv, Layer_diff_FeatureVersion ldfv, Layer l
WHERE v.id = $1
AND v.id = vafv.vulnerability_id
AND vafv.featureversion_id = fv.id
AND fv.id = ldfv.featureversion_id
AND ldfv.modification = 'add'
AND ldfv.layer_id = l.id
AND l.id >= $2
FROM Vulnerability_Affects_FeatureVersion vafv, FeatureVersion fv, Layer_diff_FeatureVersion ldfv, Layer l
WHERE l.id >= $2
AND vafv.vulnerability_id = $1
AND vafv.featureversion_id = fv.id
AND ldfv.featureversion_id = fv.id
AND ldfv.modification = 'add'
AND ldfv.layer_id = l.id
ORDER BY l.ID
LIMIT $3`
)
SELECT *
FROM subquery
LIMIT $3;
`
// complex_test.go
searchComplexTestFeatureVersionAffects = `

View File

@ -433,18 +433,25 @@ func (pgSQL *pgSQL) insertVulnerabilityFixedInFeatureVersions(tx *sql.Tx, vulner
for _, fv := range fixedIn {
var fixedInID int
var created bool
// Insert Vulnerability_FixedIn_Feature.
// Find or create entry in Vulnerability_FixedIn_Feature.
err = tx.QueryRow(
insertVulnerabilityFixedInFeature,
soiVulnerabilityFixedInFeature,
vulnerabilityID, fv.Feature.ID,
&fv.Version,
).Scan(&fixedInID)
).Scan(&created, &fixedInID)
if err != nil {
return handleError("insertVulnerabilityFixedInFeature", err)
}
if !created {
// The relationship between the feature and the vulnerability already
// existed, no need to update Vulnerability_Affects_FeatureVersion.
continue
}
// Insert Vulnerability_Affects_FeatureVersion.
err = linkVulnerabilityToFeatureVersions(tx, fixedInID, vulnerabilityID, fv.Feature.ID, fv.Version)
if err != nil {

View File

@ -225,25 +225,24 @@ func TestInsertVulnerability(t *testing.T) {
v1.Description = "TestInsertVulnerabilityLink2"
v1.Link = "TestInsertVulnerabilityLink2"
v1.Severity = types.High
// Update f3 in f4, add fixed in f5, add fixed in f6 which already exists, removes fixed in f7 by
// adding f8 which is f7 but with MinVersion.
v1.FixedIn = []database.FeatureVersion{f4, f5, f6, f8}
// Update f3 in f4, add fixed in f5, add fixed in f6 which already exists,
// removes fixed in f7 by adding f8 which is f7 but with MinVersion, and
// add fixed by f5 a second time (duplicated).
v1.FixedIn = []database.FeatureVersion{f4, f5, f6, f8, f5}
err = datastore.InsertVulnerabilities([]database.Vulnerability{v1}, true)
if assert.Nil(t, err) {
v1f, err := datastore.FindVulnerability(n1.Name, v1.Name)
if assert.Nil(t, err) {
// Remove f8 from the struct for comparison as it was just here to cancel f7.
// Remove one of the f5 too as it was twice in the struct but the database
// implementation should have dedup'd it.
v1.FixedIn = v1.FixedIn[:len(v1.FixedIn)-2]
// We already had f1 before the update.
// Add it to the struct for comparison.
v1.FixedIn = append(v1.FixedIn, f1)
// Removes f8 from the struct for comparison as it was just here to cancel f7.
for i := 0; i < len(v1.FixedIn); i++ {
if v1.FixedIn[i].Feature.Name == f8.Feature.Name {
v1.FixedIn = append(v1.FixedIn[:i], v1.FixedIn[i+1:]...)
}
}
equalsVuln(t, &v1, &v1f)
}
}

View File

@ -290,7 +290,8 @@ func toFeatureVersions(criteria criteria) []database.FeatureVersion {
}
}
if osVersion > firstConsideredRHEL {
if osVersion >= firstConsideredRHEL {
// TODO(vbatts) this is where features need multiple labels ('centos' and 'rhel')
featureVersion.Feature.Namespace.Name = "centos" + ":" + strconv.Itoa(osVersion)
} else {
continue

View File

@ -36,7 +36,7 @@ import (
const (
trackerURI = "https://launchpad.net/ubuntu-cve-tracker"
trackerRepository = "lp:ubuntu-cve-tracker"
trackerRepository = "https://launchpad.net/ubuntu-cve-tracker"
updaterFlag = "ubuntuUpdater"
cveURL = "http://people.ubuntu.com/~ubuntu-security/cve/%s"
)

View File

@ -21,6 +21,7 @@ import (
"sync"
"github.com/coreos/clair/database"
"github.com/coreos/pkg/capnslog"
)
// The NamespaceDetector interface defines a way to detect a Namespace from input data.
@ -34,6 +35,8 @@ type NamespaceDetector interface {
}
var (
nlog = capnslog.NewPackageLogger("github.com/coreos/clair", "worker/detectors")
namespaceDetectorsLock sync.Mutex
namespaceDetectors = make(map[string]NamespaceDetector)
)
@ -62,8 +65,9 @@ func RegisterNamespaceDetector(name string, f NamespaceDetector) {
// DetectNamespace finds the OS of the layer by using every registered NamespaceDetector.
func DetectNamespace(data map[string][]byte) *database.Namespace {
for _, detector := range namespaceDetectors {
for name, detector := range namespaceDetectors {
if namespace := detector.Detect(data); namespace != nil {
nlog.Debugf("detector: %q; namespace: %q\n", name, namespace.Name)
return namespace
}
}

View File

@ -24,6 +24,8 @@ import (
)
var (
//log = capnslog.NewPackageLogger("github.com/coreos/clair", "worker/detectors/namespace/osrelease")
osReleaseOSRegexp = regexp.MustCompile(`^ID=(.*)`)
osReleaseVersionRegexp = regexp.MustCompile(`^VERSION_ID=(.*)`)
)
@ -42,6 +44,12 @@ func init() {
func (detector *OsReleaseNamespaceDetector) Detect(data map[string][]byte) *database.Namespace {
var OS, version string
for _, filePath := range detector.getExcludeFiles() {
if _, hasFile := data[filePath]; hasFile {
return nil
}
}
for _, filePath := range detector.GetRequiredFiles() {
f, hasFile := data[filePath]
if !hasFile {
@ -74,3 +82,8 @@ func (detector *OsReleaseNamespaceDetector) Detect(data map[string][]byte) *data
func (detector *OsReleaseNamespaceDetector) GetRequiredFiles() []string {
return []string{"etc/os-release", "usr/lib/os-release"}
}
// getExcludeFiles returns the list of files that are ought to exclude this detector from Detect()
func (detector *OsReleaseNamespaceDetector) getExcludeFiles() []string {
return []string{"etc/redhat-release", "usr/lib/centos-release"}
}

View File

@ -20,9 +20,15 @@ import (
"github.com/coreos/clair/database"
"github.com/coreos/clair/worker/detectors"
"github.com/coreos/pkg/capnslog"
)
var redhatReleaseRegexp = regexp.MustCompile(`(?P<os>[^\s]*) (Linux release|release) (?P<version>[\d]+)`)
var (
log = capnslog.NewPackageLogger("github.com/coreos/clair", "worker/detectors/namespace/redhatrelease")
centosReleaseRegexp = regexp.MustCompile(`(?P<os>[^\s]*) (Linux release|release) (?P<version>[\d]+)`)
redhatReleaseRegexp = regexp.MustCompile(`(?P<os>Red Hat Enterprise Linux) (Client release|Server release|Workstation release) (?P<version>[\d]+)`)
)
// RedhatReleaseNamespaceDetector implements NamespaceDetector and detects the OS from the
// /etc/centos-release, /etc/redhat-release and /etc/system-release files.
@ -31,6 +37,7 @@ var redhatReleaseRegexp = regexp.MustCompile(`(?P<os>[^\s]*) (Linux release|rele
// eg. CentOS release 5.11 (Final)
// eg. CentOS release 6.6 (Final)
// eg. CentOS Linux release 7.1.1503 (Core)
// eg. Red Hat Enterprise Linux Server release 7.2 (Maipo)
type RedhatReleaseNamespaceDetector struct{}
func init() {
@ -44,10 +51,21 @@ func (detector *RedhatReleaseNamespaceDetector) Detect(data map[string][]byte) *
continue
}
r := redhatReleaseRegexp.FindStringSubmatch(string(f))
var r []string
// try for RHEL
r = redhatReleaseRegexp.FindStringSubmatch(string(f))
if len(r) == 4 {
// TODO(vbatts) this is a hack until https://github.com/coreos/clair/pull/193
return &database.Namespace{Name: "centos" + ":" + r[3]}
}
// then try centos first
r = centosReleaseRegexp.FindStringSubmatch(string(f))
if len(r) == 4 {
return &database.Namespace{Name: strings.ToLower(r[1]) + ":" + r[3]}
}
}
return nil