github.com/devseccon/trivy@v0.47.1-0.20231123133102-bd902a0bd996/pkg/detector/ospkg/oracle/oracle.go (about) 1 package oracle 2 3 import ( 4 "strings" 5 "time" 6 7 version "github.com/knqyf263/go-rpm-version" 8 "golang.org/x/xerrors" 9 "k8s.io/utils/clock" 10 11 oracleoval "github.com/aquasecurity/trivy-db/pkg/vulnsrc/oracle-oval" 12 osver "github.com/devseccon/trivy/pkg/detector/ospkg/version" 13 ftypes "github.com/devseccon/trivy/pkg/fanal/types" 14 "github.com/devseccon/trivy/pkg/log" 15 "github.com/devseccon/trivy/pkg/scanner/utils" 16 "github.com/devseccon/trivy/pkg/types" 17 ) 18 19 var ( 20 eolDates = map[string]time.Time{ 21 // Source: 22 // https://www.oracle.com/a/ocom/docs/elsp-lifetime-069338.pdf 23 // https://community.oracle.com/docs/DOC-917964 24 "3": time.Date(2011, 12, 31, 23, 59, 59, 0, time.UTC), 25 "4": time.Date(2013, 12, 31, 23, 59, 59, 0, time.UTC), 26 "5": time.Date(2017, 12, 31, 23, 59, 59, 0, time.UTC), 27 "6": time.Date(2021, 3, 21, 23, 59, 59, 0, time.UTC), 28 "7": time.Date(2024, 7, 23, 23, 59, 59, 0, time.UTC), 29 "8": time.Date(2029, 7, 18, 23, 59, 59, 0, time.UTC), 30 "9": time.Date(2032, 7, 18, 23, 59, 59, 0, time.UTC), 31 } 32 ) 33 34 // Scanner implements oracle vulnerability scanner 35 type Scanner struct { 36 vs *oracleoval.VulnSrc 37 clock clock.Clock 38 } 39 40 // NewScanner is the factory method to return oracle vulnerabilities 41 func NewScanner() *Scanner { 42 return &Scanner{ 43 vs: oracleoval.NewVulnSrc(), 44 clock: clock.RealClock{}, 45 } 46 } 47 48 func extractKsplice(v string) string { 49 subs := strings.Split(strings.ToLower(v), ".") 50 for _, s := range subs { 51 if strings.HasPrefix(s, "ksplice") { 52 return s 53 } 54 } 55 return "" 56 } 57 58 // Detect scans and return vulnerability in Oracle scanner 59 func (s *Scanner) Detect(osVer string, _ *ftypes.Repository, pkgs []ftypes.Package) ([]types.DetectedVulnerability, error) { 60 log.Logger.Info("Detecting Oracle Linux vulnerabilities...") 61 62 osVer = osver.Major(osVer) 63 log.Logger.Debugf("Oracle Linux: os version: %s", osVer) 64 log.Logger.Debugf("Oracle Linux: the number of packages: %d", len(pkgs)) 65 66 var vulns []types.DetectedVulnerability 67 for _, pkg := range pkgs { 68 advisories, err := s.vs.Get(osVer, pkg.Name) 69 if err != nil { 70 return nil, xerrors.Errorf("failed to get Oracle Linux advisory: %w", err) 71 } 72 73 installed := utils.FormatVersion(pkg) 74 installedVersion := version.NewVersion(installed) 75 for _, adv := range advisories { 76 // when one of them doesn't have ksplice, we'll also skip it 77 // extract kspliceX and compare it with kspliceY in advisories 78 // if kspliceX and kspliceY are different, we will skip the advisory 79 if extractKsplice(adv.FixedVersion) != extractKsplice(pkg.Release) { 80 continue 81 } 82 83 fixedVersion := version.NewVersion(adv.FixedVersion) 84 vuln := types.DetectedVulnerability{ 85 VulnerabilityID: adv.VulnerabilityID, 86 PkgID: pkg.ID, 87 PkgName: pkg.Name, 88 InstalledVersion: installed, 89 PkgRef: pkg.Ref, 90 Layer: pkg.Layer, 91 Custom: adv.Custom, 92 DataSource: adv.DataSource, 93 } 94 if installedVersion.LessThan(fixedVersion) { 95 vuln.FixedVersion = adv.FixedVersion 96 vulns = append(vulns, vuln) 97 } 98 } 99 } 100 return vulns, nil 101 } 102 103 // IsSupportedVersion checks if the version is supported. 104 func (s *Scanner) IsSupportedVersion(osFamily ftypes.OSType, osVer string) bool { 105 return osver.Supported(s.clock, eolDates, osFamily, osver.Major(osVer)) 106 }