github.com/google/osv-scalibr@v0.4.1/detector/endoflife/linuxdistro/linuxdistro.go (about) 1 // Copyright 2025 Google LLC 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 // Package linuxdistro implements a detector for End-of-Life Linux distributions 16 package linuxdistro 17 18 import ( 19 "context" 20 "time" 21 22 "github.com/google/osv-scalibr/detector" 23 "github.com/google/osv-scalibr/extractor/filesystem/os/osrelease" 24 scalibrfs "github.com/google/osv-scalibr/fs" 25 "github.com/google/osv-scalibr/inventory" 26 "github.com/google/osv-scalibr/packageindex" 27 "github.com/google/osv-scalibr/plugin" 28 ) 29 30 const ( 31 // Name of the detector. 32 Name = "endoflife/linuxdistro" 33 ) 34 35 var now = time.Now 36 37 // Detector is a SCALIBR Detector for End-Of-Life linux distributions 38 type Detector struct{} 39 40 // New returns a detector. 41 func New() detector.Detector { 42 return &Detector{} 43 } 44 45 // Name of the detector. 46 func (Detector) Name() string { return Name } 47 48 // Version of the detector. 49 func (Detector) Version() int { return 0 } 50 51 // Requirements of the detector. 52 func (Detector) Requirements() *plugin.Capabilities { 53 return &plugin.Capabilities{OS: plugin.OSLinux} 54 } 55 56 // RequiredExtractors returns nothing (no deps). 57 func (Detector) RequiredExtractors() []string { return []string{} } 58 59 func eolFinding(target *inventory.GenericFindingTargetDetails) inventory.Finding { 60 title := "End-of-Life operating system" 61 description := "The system is running a Linux distribution that has reached end-of-life " + 62 "(EOL) and is no longer maintained by the vendor. This means it no longer " + 63 "receives security updates or patches." 64 recommendation := "Upgrade the operating system to a supported release or arrange " + 65 "an extended support with the vendor." 66 return inventory.Finding{GenericFindings: []*inventory.GenericFinding{{ 67 Adv: &inventory.GenericFindingAdvisory{ 68 ID: &inventory.AdvisoryID{ 69 Publisher: "SCALIBR", 70 Reference: "linux-end-of-life", 71 }, 72 Title: title, 73 Description: description, 74 Recommendation: recommendation, 75 Sev: inventory.SeverityCritical, 76 }, 77 Target: target, 78 }}} 79 } 80 81 var eolDetector = map[string]func(map[string]string, scalibrfs.FS) bool{ 82 "fedora": fedoraEOL, 83 "ubuntu": ubuntuEOL, 84 } 85 86 // Scan checks for the presence of an end-of-life Linux OS on the host. 87 func (d Detector) Scan(ctx context.Context, scanRoot *scalibrfs.ScanRoot, px *packageindex.PackageIndex) (inventory.Finding, error) { 88 osRelease, err := osrelease.GetOSRelease(scanRoot.FS) 89 if err != nil { 90 return inventory.Finding{}, err 91 } 92 distro, ok := osRelease["ID"] 93 if !ok { 94 return inventory.Finding{}, err 95 } 96 if detector, ok := eolDetector[distro]; ok { 97 if detector(osRelease, scanRoot.FS) { 98 target := &inventory.GenericFindingTargetDetails{Extra: "distro: " + distro} 99 return eolFinding(target), nil 100 } 101 } 102 return inventory.Finding{}, nil 103 } 104 105 // DetectedFinding returns generic vulnerability information about what is detected. 106 func (d Detector) DetectedFinding() inventory.Finding { 107 return eolFinding(nil) 108 }