github.com/google/osv-scalibr@v0.4.1/annotator/ffa/unknownbinariesanno/filterknownbinaries.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 unknownbinariesanno removes all packages extracted by unknown binaries 16 // filters out the known binaries, and records the remaining as a finding. 17 package unknownbinariesanno 18 19 import ( 20 "context" 21 "fmt" 22 "slices" 23 24 "github.com/google/osv-scalibr/annotator" 25 "github.com/google/osv-scalibr/annotator/ffa/unknownbinariesanno/internal/apkfilter" 26 "github.com/google/osv-scalibr/annotator/ffa/unknownbinariesanno/internal/dpkgfilter" 27 "github.com/google/osv-scalibr/annotator/ffa/unknownbinariesanno/internal/filter" 28 "github.com/google/osv-scalibr/extractor" 29 "github.com/google/osv-scalibr/extractor/filesystem/ffa/unknownbinariesextr" 30 "github.com/google/osv-scalibr/inventory" 31 "github.com/google/osv-scalibr/plugin" 32 ) 33 34 // Name of the plugin 35 const Name = "ffa/unknownbinaries" 36 37 // List of filters to apply to exclude known binaries 38 var filters = []filter.Filter{ 39 dpkgfilter.DpkgFilter{}, 40 apkfilter.ApkFilter{}, 41 } 42 43 // Annotator further processes the UnknownBinaryExtractor 44 type Annotator struct { 45 } 46 47 // New returns a new Annotator. 48 func New() annotator.Annotator { 49 return &Annotator{} 50 } 51 52 // Annotate filters out binaries extracted by unknwonbinaries extractor that can be accounted for by other 53 // inventories or metadata on the FS. 54 func (anno *Annotator) Annotate(ctx context.Context, input *annotator.ScanInput, inv *inventory.Inventory) error { 55 unknownBinariesSet := map[string]*extractor.Package{} 56 filteredPackages := make([]*extractor.Package, 0, len(inv.Packages)) 57 for _, e := range inv.Packages { 58 if !slices.Contains(e.Plugins, unknownbinariesextr.Name) { 59 filteredPackages = append(filteredPackages, e) 60 continue 61 } 62 63 unknownBinariesSet[e.Locations[0]] = e 64 } 65 66 // First account for all the files we have successfully extracted. 67 for _, e := range filteredPackages { 68 for _, location := range e.Locations { 69 delete(unknownBinariesSet, location) 70 } 71 } 72 73 // Remove all unknown binary packages from output packages 74 inv.Packages = filteredPackages 75 76 // Two sets of filters, one with a hashset that gets elements deleted out of, and another with a simple loop 77 78 // Hash set filter 79 for _, f := range filters { 80 err := f.HashSetFilter(ctx, input.ScanRoot.FS, unknownBinariesSet) 81 if err != nil { 82 return fmt.Errorf("%s halted at %q (%q) because %w", anno.Name(), input.ScanRoot.Path, f.Name(), err) 83 } 84 } 85 86 // Loop Filter 87 RemainingPathsLoop: 88 for p, val := range unknownBinariesSet { 89 for _, f := range filters { 90 if f.ShouldExclude(ctx, input.ScanRoot.FS, p) { 91 continue RemainingPathsLoop 92 } 93 } 94 95 // TODO(b/400910349): We are currently readding it as packages, but eventually we would want a separate type 96 // as this information does not behave like packages. 97 inv.Packages = append(inv.Packages, val) 98 } 99 100 return nil 101 } 102 103 var _ annotator.Annotator = &Annotator{} 104 105 // Name returns the name of the enricher. 106 func (*Annotator) Name() string { 107 return Name 108 } 109 110 // Version returns the version of the enricher. 111 func (*Annotator) Version() int { 112 return 0 113 } 114 115 // Requirements returns the requirements of the enricher. 116 func (*Annotator) Requirements() *plugin.Capabilities { 117 return &plugin.Capabilities{} 118 } 119 120 // RequiredPlugins returns the names of the plugins required by the enricher. 121 func (*Annotator) RequiredPlugins() []string { 122 return []string{unknownbinariesextr.Name} 123 }