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  }