Skip to content

Commit

Permalink
feat(epel): support EPEL(Extra Packages for Enterprise Linux) scan
Browse files Browse the repository at this point in the history
  • Loading branch information
MaineK00n committed Mar 6, 2022
1 parent 84dd33f commit 0cb65ec
Show file tree
Hide file tree
Showing 6 changed files with 135 additions and 46 deletions.
33 changes: 24 additions & 9 deletions pkg/detector/ospkg/alma/alma.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ import (
"k8s.io/utils/clock"

ftypes "github.com/aquasecurity/fanal/types"
dbTypes "github.com/aquasecurity/trivy-db/pkg/types"
"github.com/aquasecurity/trivy-db/pkg/vulnsrc/alma"
"github.com/aquasecurity/trivy-db/pkg/vulnsrc/epel"
"github.com/aquasecurity/trivy/pkg/log"
"github.com/aquasecurity/trivy/pkg/scanner/utils"
"github.com/aquasecurity/trivy/pkg/types"
Expand Down Expand Up @@ -37,7 +39,8 @@ func WithClock(clock clock.Clock) option {

// Scanner implements the AlmaLinux scanner
type Scanner struct {
vs alma.VulnSrc
osVS alma.VulnSrc
epelVS epel.VulnSrc
*options
}

Expand All @@ -51,7 +54,8 @@ func NewScanner(opts ...option) *Scanner {
opt(o)
}
return &Scanner{
vs: alma.NewVulnSrc(),
osVS: alma.NewVulnSrc(),
epelVS: epel.NewVulnSrc(),
options: o,
}
}
Expand All @@ -68,14 +72,25 @@ func (s *Scanner) Detect(osVer string, pkgs []ftypes.Package) ([]types.DetectedV
var vulns []types.DetectedVulnerability
var skipPkgs []string
for _, pkg := range pkgs {
if strings.Contains(pkg.Release, ".module_el") {
skipPkgs = append(skipPkgs, pkg.Name)
continue
}
pkgName := addModularNamespace(pkg.Name, pkg.Modularitylabel)
advisories, err := s.vs.Get(osVer, pkgName)
if err != nil {
return nil, xerrors.Errorf("failed to get AlmaLinux advisories: %w", err)

var advisories []dbTypes.Advisory
var err error
// https://docs.fedoraproject.org/en-US/epel/epel-faq/#how_can_i_find_out_if_a_package_is_from_epel
if pkg.Vendor == "Fedora Project" {
advisories, err = s.epelVS.Get(osVer, pkgName)
if err != nil {
return nil, xerrors.Errorf("failed to get EPEL advisories: %w", err)
}
} else {
if strings.Contains(pkg.Release, ".module_el") {
skipPkgs = append(skipPkgs, pkg.Name)
continue
}
advisories, err = s.osVS.Get(osVer, pkgName)
if err != nil {
return nil, xerrors.Errorf("failed to get AlmaLinux advisories: %w", err)
}
}

installed := utils.FormatVersion(pkg)
Expand Down
33 changes: 28 additions & 5 deletions pkg/detector/ospkg/amazon/amazon.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ import (
"golang.org/x/xerrors"

ftypes "github.com/aquasecurity/fanal/types"
dbTypes "github.com/aquasecurity/trivy-db/pkg/types"
"github.com/aquasecurity/trivy-db/pkg/vulnsrc/amazon"
"github.com/aquasecurity/trivy-db/pkg/vulnsrc/epel"
"github.com/aquasecurity/trivy/pkg/log"
"github.com/aquasecurity/trivy/pkg/scanner/utils"
"github.com/aquasecurity/trivy/pkg/types"
Expand All @@ -23,6 +25,11 @@ var (
// N/A
"2": time.Date(3000, 1, 1, 23, 59, 59, 0, time.UTC),
}

epelVersions = map[string]string{
"1": "6",
"2": "7",
}
)

type options struct {
Expand All @@ -40,7 +47,8 @@ func WithClock(clock clock.Clock) option {

// Scanner to scan amazon vulnerabilities
type Scanner struct {
ac amazon.VulnSrc
osVS amazon.VulnSrc
epelVS epel.VulnSrc
options
}

Expand All @@ -55,7 +63,8 @@ func NewScanner(opts ...option) *Scanner {
opt(o)
}
return &Scanner{
ac: amazon.NewVulnSrc(),
osVS: amazon.NewVulnSrc(),
epelVS: epel.NewVulnSrc(),
options: *o,
}
}
Expand All @@ -73,9 +82,23 @@ func (s *Scanner) Detect(osVer string, pkgs []ftypes.Package) ([]types.DetectedV

var vulns []types.DetectedVulnerability
for _, pkg := range pkgs {
advisories, err := s.ac.Get(osVer, pkg.Name)
if err != nil {
return nil, xerrors.Errorf("failed to get amazon advisories: %w", err)
var advisories []dbTypes.Advisory
var err error
// https://docs.fedoraproject.org/en-US/epel/epel-faq/#how_can_i_find_out_if_a_package_is_from_epel
if pkg.Vendor == "Fedora Project" {
epelVer, ok := epelVersions[osVer]
if !ok || epelVer == "6" {
continue
}
advisories, err = s.epelVS.Get(epelVer, pkg.Name)
if err != nil {
return nil, xerrors.Errorf("failed to get EPEL advisories: %w", err)
}
} else {
advisories, err = s.osVS.Get(osVer, pkg.Name)
if err != nil {
return nil, xerrors.Errorf("failed to get amazon advisories: %w", err)
}
}

installed := utils.FormatVersion(pkg)
Expand Down
33 changes: 26 additions & 7 deletions pkg/detector/ospkg/oracle/oracle.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import (
"k8s.io/utils/clock"

ftypes "github.com/aquasecurity/fanal/types"
dbTypes "github.com/aquasecurity/trivy-db/pkg/types"
"github.com/aquasecurity/trivy-db/pkg/vulnsrc/epel"
oracleoval "github.com/aquasecurity/trivy-db/pkg/vulnsrc/oracle-oval"
"github.com/aquasecurity/trivy/pkg/log"
"github.com/aquasecurity/trivy/pkg/scanner/utils"
Expand All @@ -31,15 +33,17 @@ var (

// Scanner implements oracle vulnerability scanner
type Scanner struct {
vs oracleoval.VulnSrc
clock clock.Clock
osVS oracleoval.VulnSrc
fedoraEPELVS epel.VulnSrc
clock clock.Clock
}

// NewScanner is the factory method to return oracle vulnerabilities
func NewScanner() *Scanner {
return &Scanner{
vs: oracleoval.NewVulnSrc(),
clock: clock.RealClock{},
osVS: oracleoval.NewVulnSrc(),
fedoraEPELVS: epel.NewVulnSrc(),
clock: clock.RealClock{},
}
}

Expand All @@ -66,9 +70,24 @@ func (s *Scanner) Detect(osVer string, pkgs []ftypes.Package) ([]types.DetectedV

var vulns []types.DetectedVulnerability
for _, pkg := range pkgs {
advisories, err := s.vs.Get(osVer, pkg.Name)
if err != nil {
return nil, xerrors.Errorf("failed to get Oracle Linux advisory: %w", err)
var advisories []dbTypes.Advisory
var err error
// https://docs.fedoraproject.org/en-US/epel/epel-faq/#how_can_i_find_out_if_a_package_is_from_epel
if pkg.Vendor == "Fedora Project" {
switch osVer {
case "7", "8", "9":
advisories, err = s.fedoraEPELVS.Get(osVer, pkg.Name)
if err != nil {
return nil, xerrors.Errorf("failed to get EPEL advisory: %w", err)
}
default:
continue
}
} else {
advisories, err = s.osVS.Get(osVer, pkg.Name)
if err != nil {
return nil, xerrors.Errorf("failed to get Oracle Linux advisory: %w", err)
}
}

installed := utils.FormatVersion(pkg)
Expand Down
4 changes: 2 additions & 2 deletions pkg/detector/ospkg/oracle/oracle_test.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package oracle

import (
dbTypes "github.com/aquasecurity/trivy-db/pkg/types"
"testing"
"time"

Expand All @@ -12,6 +11,7 @@ import (

ftypes "github.com/aquasecurity/fanal/types"
"github.com/aquasecurity/trivy-db/pkg/db"
dbTypes "github.com/aquasecurity/trivy-db/pkg/types"
oracleoval "github.com/aquasecurity/trivy-db/pkg/vulnsrc/oracle-oval"
"github.com/aquasecurity/trivy/pkg/dbtest"
"github.com/aquasecurity/trivy/pkg/types"
Expand Down Expand Up @@ -82,7 +82,7 @@ func TestScanner_IsSupportedVersion(t *testing.T) {

for testName, v := range vectors {
s := &Scanner{
vs: oracleoval.NewVulnSrc(),
osVS: oracleoval.NewVulnSrc(),
clock: v.clock,
}
t.Run(testName, func(t *testing.T) {
Expand Down
44 changes: 31 additions & 13 deletions pkg/detector/ospkg/redhat/redhat.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
ftypes "github.com/aquasecurity/fanal/types"
dbTypes "github.com/aquasecurity/trivy-db/pkg/types"
ustrings "github.com/aquasecurity/trivy-db/pkg/utils/strings"
"github.com/aquasecurity/trivy-db/pkg/vulnsrc/epel"
redhat "github.com/aquasecurity/trivy-db/pkg/vulnsrc/redhat-oval"
"github.com/aquasecurity/trivy-db/pkg/vulnsrc/vulnerability"
"github.com/aquasecurity/trivy/pkg/log"
Expand Down Expand Up @@ -71,7 +72,8 @@ func WithClock(clock clock.Clock) option {

// Scanner implements the Alpine scanner
type Scanner struct {
vs redhat.VulnSrc
osVS redhat.VulnSrc
epelVS epel.VulnSrc
*options
}

Expand All @@ -85,7 +87,8 @@ func NewScanner(opts ...option) *Scanner {
opt(o)
}
return &Scanner{
vs: redhat.NewVulnSrc(),
osVS: redhat.NewVulnSrc(),
epelVS: epel.NewVulnSrc(),
options: o,
}
}
Expand Down Expand Up @@ -119,18 +122,33 @@ func (s *Scanner) detect(osVer string, pkg ftypes.Package) ([]types.DetectedVuln
// For Red Hat OVAL v2 containing only binary package names
pkgName := addModularNamespace(pkg.Name, pkg.Modularitylabel)

var contentSets []string
var nvr string
if pkg.BuildInfo == nil {
contentSets = defaultContentSets[osVer]
var advisories []dbTypes.Advisory
var err error
// https://docs.fedoraproject.org/en-US/epel/epel-faq/#how_can_i_find_out_if_a_package_is_from_epel
if pkg.Vendor == "Fedora Project" {
switch osVer {
case "7", "8", "9":
advisories, err = s.epelVS.Get(osVer, pkgName)
if err != nil {
return nil, xerrors.Errorf("failed to get EPEL advisories: %w", err)
}
default:
return []types.DetectedVulnerability{}, nil
}
} else {
contentSets = pkg.BuildInfo.ContentSets
nvr = fmt.Sprintf("%s-%s", pkg.BuildInfo.Nvr, pkg.BuildInfo.Arch)
}
var contentSets []string
var nvr string
if pkg.BuildInfo == nil {
contentSets = defaultContentSets[osVer]
} else {
contentSets = pkg.BuildInfo.ContentSets
nvr = fmt.Sprintf("%s-%s", pkg.BuildInfo.Nvr, pkg.BuildInfo.Arch)
}

advisories, err := s.vs.Get(pkgName, contentSets, []string{nvr})
if err != nil {
return nil, xerrors.Errorf("failed to get Red Hat advisories: %w", err)
advisories, err = s.osVS.Get(pkgName, contentSets, []string{nvr})
if err != nil {
return nil, xerrors.Errorf("failed to get Red Hat advisories: %w", err)
}
}

installed := utils.FormatVersion(pkg)
Expand All @@ -144,7 +162,7 @@ func (s *Scanner) detect(osVer string, pkg ftypes.Package) ([]types.DetectedVuln
PkgName: pkg.Name,
InstalledVersion: utils.FormatVersion(pkg),
Layer: pkg.Layer,
SeveritySource: vulnerability.RedHat,
SeveritySource: string(vulnerability.RedHat),
Vulnerability: dbTypes.Vulnerability{
Severity: adv.Severity.String(),
},
Expand Down
34 changes: 24 additions & 10 deletions pkg/detector/ospkg/rocky/rocky.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import (
"k8s.io/utils/clock"

ftypes "github.com/aquasecurity/fanal/types"
dbTypes "github.com/aquasecurity/trivy-db/pkg/types"
"github.com/aquasecurity/trivy-db/pkg/vulnsrc/epel"
"github.com/aquasecurity/trivy-db/pkg/vulnsrc/rocky"
"github.com/aquasecurity/trivy/pkg/log"
"github.com/aquasecurity/trivy/pkg/scanner/utils"
Expand Down Expand Up @@ -37,7 +39,8 @@ func WithClock(clock clock.Clock) option {

// Scanner implements the Rocky Linux scanner
type Scanner struct {
vs rocky.VulnSrc
osVS rocky.VulnSrc
epelVS epel.VulnSrc
*options
}

Expand All @@ -51,7 +54,8 @@ func NewScanner(opts ...option) *Scanner {
opt(o)
}
return &Scanner{
vs: rocky.NewVulnSrc(),
osVS: rocky.NewVulnSrc(),
epelVS: epel.NewVulnSrc(),
options: o,
}
}
Expand All @@ -68,16 +72,26 @@ func (s *Scanner) Detect(osVer string, pkgs []ftypes.Package) ([]types.DetectedV
var vulns []types.DetectedVulnerability
var skipPkgs []string
for _, pkg := range pkgs {
if pkg.Modularitylabel != "" {
skipPkgs = append(skipPkgs, pkg.Name)
continue
}
pkgName := addModularNamespace(pkg.Name, pkg.Modularitylabel)
advisories, err := s.vs.Get(osVer, pkgName)
if err != nil {
return nil, xerrors.Errorf("failed to get Rocky Linux advisories: %w", err)
}

var advisories []dbTypes.Advisory
var err error
// https://docs.fedoraproject.org/en-US/epel/epel-faq/#how_can_i_find_out_if_a_package_is_from_epel
if pkg.Vendor == "Fedora Project" {
advisories, err = s.epelVS.Get(osVer, pkgName)
if err != nil {
return nil, xerrors.Errorf("failed to get EPEL advisories: %w", err)
}
} else {
if pkg.Modularitylabel != "" {
skipPkgs = append(skipPkgs, pkg.Name)
continue
}
advisories, err = s.osVS.Get(osVer, pkgName)
if err != nil {
return nil, xerrors.Errorf("failed to get Rocky Linux advisories: %w", err)
}
}
installed := utils.FormatVersion(pkg)
installedVersion := version.NewVersion(installed)

Expand Down

0 comments on commit 0cb65ec

Please sign in to comment.