Skip to content

Commit

Permalink
Add support for determineversions API (google#612). (google#621)
Browse files Browse the repository at this point in the history
Fixes google#612.

Tested on https://github.com/opencv/opencv

We need to set up an e2e test for this as well (maybe add some
submodules + vendored libs to
https://github.com/ossf-tests/scorecard-check-osv-e2e).

```
Scanning dir /tmp/opencv
Scanning /tmp/opencv/ at commit e9e6b1e22c1a966a81aca1217b16a51fe7311b3b
Scanning directory for vendored libs: /tmp/opencv/3rdparty
Scanning potential vendored dir: /tmp/opencv/3rdparty/carotene
Scanning potential vendored dir: /tmp/opencv/3rdparty/cpufeatures
Scanning potential vendored dir: /tmp/opencv/3rdparty/ffmpeg
Scanning potential vendored dir: /tmp/opencv/3rdparty/flatbuffers
Scanning potential vendored dir: /tmp/opencv/3rdparty/include
Scanning potential vendored dir: /tmp/opencv/3rdparty/ippicv
Scanning potential vendored dir: /tmp/opencv/3rdparty/ittnotify
Scanning potential vendored dir: /tmp/opencv/3rdparty/libjasper
Scanning potential vendored dir: /tmp/opencv/3rdparty/libjpeg
Identified /tmp/opencv/3rdparty/libjpeg as https://github.com/libjpeg-turbo/libjpeg-turbo at 9fc018fd1aa9598f21c9bc4d8d53c0cef007bdcf.
Scanning potential vendored dir: /tmp/opencv/3rdparty/libjpeg-turbo
Identified /tmp/opencv/3rdparty/libjpeg-turbo as https://github.com/libjpeg-turbo/libjpeg-turbo at c5f269eb9665435271c05fbcaf8721fa58e9eafa.
Scanning potential vendored dir: /tmp/opencv/3rdparty/libpng
Identified /tmp/opencv/3rdparty/libpng as https://github.com/gemini-testing/png-img at 4a9d62598d369566680300c96ec0a22f1dec48c3.
Scanning potential vendored dir: /tmp/opencv/3rdparty/libspng
Scanning potential vendored dir: /tmp/opencv/3rdparty/libtiff
Identified /tmp/opencv/3rdparty/libtiff as https://gitlab.com/libtiff/libtiff at 4862b0d7bcc786304ff4e8c31e8d5ccfb868fb99.
Scanning potential vendored dir: /tmp/opencv/3rdparty/libtim-vx
Scanning potential vendored dir: /tmp/opencv/3rdparty/libwebp
Identified /tmp/opencv/3rdparty/libwebp as https://chromium.googlesource.com/webm/libwebp at fd7bb21c0cb56e8a82e9bfa376164b842f433f3b.
Scanning potential vendored dir: /tmp/opencv/3rdparty/openexr
Identified /tmp/opencv/3rdparty/openexr as https://github.com/AcademySoftwareFoundation/openexr at 0ac2ea34c8f3134148a5df4052e40f155b76f6fb.
Scanning potential vendored dir: /tmp/opencv/3rdparty/openjpeg
Identified /tmp/opencv/3rdparty/openjpeg as https://github.com/uclouvain/openjpeg at a5891555eb49ed7cc26b2901ea680acda136d811.
Scanning potential vendored dir: /tmp/opencv/3rdparty/openvx
Scanning potential vendored dir: /tmp/opencv/3rdparty/protobuf
Identified /tmp/opencv/3rdparty/protobuf as https://github.com/protocolbuffers/protobuf at 7c40b2df1fdf6f414c1c18c789715a9c948a0725.
Scanning potential vendored dir: /tmp/opencv/3rdparty/quirc
Scanning potential vendored dir: /tmp/opencv/3rdparty/tbb
Scanning potential vendored dir: /tmp/opencv/3rdparty/zlib
Identified /tmp/opencv/3rdparty/zlib as https://github.com/madler/zlib at 04f42ceca40f73e2978b50e93806c2a18c1281fc.
Scanning directory for vendored libs: /tmp/opencv/modules/core/3rdparty
Scanning potential vendored dir: /tmp/opencv/modules/core/3rdparty/SoftFloat
Scanning directory for vendored libs: /tmp/opencv/modules/features2d/3rdparty
Scanning potential vendored dir: /tmp/opencv/modules/features2d/3rdparty/mscr
Scanned /tmp/opencv/platforms/maven/opencv/pom.xml file and found 0 packages
Failed to resolve version of org.ops4j.pax.exam:pax-exam-container-karaf: property "pax.exam.version" could not be found for "org.opencv:opencv-it"
Failed to resolve version of org.ops4j.pax.exam:pax-exam-junit4: property "pax.exam.version" could not be found for "org.opencv:opencv-it"
Failed to resolve version of ${project.groupId}:opencv: property "project.version" could not be found for "org.opencv:opencv-it"
Scanned /tmp/opencv/platforms/maven/opencv-it/pom.xml file and found 12 packages
Scanned /tmp/opencv/platforms/maven/pom.xml file and found 0 packages
Scanned /tmp/opencv/samples/dnn/dnn_model_runner/dnn_conversion/requirements.txt file and found 11 packages
╭─────────────────────────────────────┬──────┬───────────┬─────────────────────┬─────────────────────┬───────────────────────────────────────────────────────────────────────────────── ≈
│ OSV URL                             │ CVSS │ ECOSYSTEM │ PACKAGE             │ VERSION             │ SOURCE                                                                           ≈
├─────────────────────────────────────┼──────┼───────────┼─────────────────────┴─────────────────────┼───────────────────────────────────────────────────────────────────────────────── ≈
│ https://osv.dev/OSV-2022-394        │      │ GIT       │  e9e6b1e22c1a966a81aca1217b16a51fe7311b3b │ ../../../../../../tmp/opencv                                                     ≈
│ https://osv.dev/OSV-2023-444        │      │ GIT       │  e9e6b1e22c1a966a81aca1217b16a51fe7311b3b │ ../../../../../../tmp/opencv                                                     ≈
│ https://osv.dev/CVE-2021-29390      │ 7.1  │ GIT       │  9fc018fd1aa9598f21c9bc4d8d53c0cef007bdcf │ ../../../../../../tmp/opencv/3rdparty/libjpeg                                    ≈
│ https://osv.dev/CVE-2021-46822      │ 5.5  │ GIT       │  9fc018fd1aa9598f21c9bc4d8d53c0cef007bdcf │ ../../../../../../tmp/opencv/3rdparty/libjpeg                                    ≈
│ https://osv.dev/CVE-2022-1056       │ 5.5  │ GIT       │  4862b0d7bcc786304ff4e8c31e8d5ccfb868fb99 │ ../../../../../../tmp/opencv/3rdparty/libtiff                                    ≈
│ https://osv.dev/CVE-2022-1210       │ 6.5  │ GIT       │  4862b0d7bcc786304ff4e8c31e8d5ccfb868fb99 │ ../../../../../../tmp/opencv/3rdparty/libtiff                                    ≈
│ https://osv.dev/CVE-2022-1354       │ 5.5  │ GIT       │  4862b0d7bcc786304ff4e8c31e8d5ccfb868fb99 │ ../../../../../../tmp/opencv/3rdparty/libtiff                                    ≈
│ https://osv.dev/CVE-2022-1355       │ 6.1  │ GIT       │  4862b0d7bcc786304ff4e8c31e8d5ccfb868fb99 │ ../../../../../../tmp/opencv/3rdparty/libtiff                                    ≈
│ https://osv.dev/CVE-2022-1622       │ 5.5  │ GIT       │  4862b0d7bcc786304ff4e8c31e8d5ccfb868fb99 │ ../../../../../../tmp/opencv/3rdparty/libtiff                                    ≈
│ https://osv.dev/CVE-2022-1623       │ 5.5  │ GIT       │  4862b0d7bcc786304ff4e8c31e8d5ccfb868fb99 │ ../../../../../../tmp/opencv/3rdparty/libtiff                                    ≈
│ https://osv.dev/CVE-2022-3970       │ 8.8  │ GIT       │  4862b0d7bcc786304ff4e8c31e8d5ccfb868fb99 │ ../../../../../../tmp/opencv/3rdparty/libtiff                                    ≈
│ https://osv.dev/CVE-2022-40090      │ 6.5  │ GIT       │  4862b0d7bcc786304ff4e8c31e8d5ccfb868fb99 │ ../../../../../../tmp/opencv/3rdparty/libtiff                                    ≈
│ https://osv.dev/CVE-2023-1916       │ 6.1  │ GIT       │  4862b0d7bcc786304ff4e8c31e8d5ccfb868fb99 │ ../../../../../../tmp/opencv/3rdparty/libtiff                                    ≈
│ https://osv.dev/CVE-2023-25433      │ 5.5  │ GIT       │  4862b0d7bcc786304ff4e8c31e8d5ccfb868fb99 │ ../../../../../../tmp/opencv/3rdparty/libtiff                                    ≈
│ https://osv.dev/CVE-2023-25434      │ 8.8  │ GIT       │  4862b0d7bcc786304ff4e8c31e8d5ccfb868fb99 │ ../../../../../../tmp/opencv/3rdparty/libtiff                                    ≈
│ https://osv.dev/CVE-2023-25435      │ 5.5  │ GIT       │  4862b0d7bcc786304ff4e8c31e8d5ccfb868fb99 │ ../../../../../../tmp/opencv/3rdparty/libtiff                                    ≈
│ https://osv.dev/CVE-2023-26965      │ 5.5  │ GIT       │  4862b0d7bcc786304ff4e8c31e8d5ccfb868fb99 │ ../../../../../../tmp/opencv/3rdparty/libtiff                                    ≈
│ https://osv.dev/CVE-2023-26966      │ 5.5  │ GIT       │  4862b0d7bcc786304ff4e8c31e8d5ccfb868fb99 │ ../../../../../../tmp/opencv/3rdparty/libtiff                                    ≈
│ https://osv.dev/CVE-2023-2731       │ 5.5  │ GIT       │  4862b0d7bcc786304ff4e8c31e8d5ccfb868fb99 │ ../../../../../../tmp/opencv/3rdparty/libtiff                                    ≈
│ https://osv.dev/CVE-2023-2908       │ 5.5  │ GIT       │  4862b0d7bcc786304ff4e8c31e8d5ccfb868fb99 │ ../../../../../../tmp/opencv/3rdparty/libtiff                                    ≈
│ https://osv.dev/CVE-2023-30775      │ 5.5  │ GIT       │  4862b0d7bcc786304ff4e8c31e8d5ccfb868fb99 │ ../../../../../../tmp/opencv/3rdparty/libtiff                                    ≈
│ https://osv.dev/CVE-2023-3576       │ 5.5  │ GIT       │  4862b0d7bcc786304ff4e8c31e8d5ccfb868fb99 │ ../../../../../../tmp/opencv/3rdparty/libtiff                                    ≈
│ https://osv.dev/CVE-2023-3618       │ 6.5  │ GIT       │  4862b0d7bcc786304ff4e8c31e8d5ccfb868fb99 │ ../../../../../../tmp/opencv/3rdparty/libtiff                                    ≈
│ https://osv.dev/CVE-2023-40745      │ 6.5  │ GIT       │  4862b0d7bcc786304ff4e8c31e8d5ccfb868fb99 │ ../../../../../../tmp/opencv/3rdparty/libtiff                                    ≈
│ https://osv.dev/CVE-2023-41175      │ 6.5  │ GIT       │  4862b0d7bcc786304ff4e8c31e8d5ccfb868fb99 │ ../../../../../../tmp/opencv/3rdparty/libtiff                                    ≈
│ https://osv.dev/CVE-2023-4863       │ 8.8  │ GIT       │  fd7bb21c0cb56e8a82e9bfa376164b842f433f3b │ ../../../../../../tmp/opencv/3rdparty/libwebp                                    ≈
│ https://osv.dev/CVE-2018-18443      │ 4.3  │ GIT       │  0ac2ea34c8f3134148a5df4052e40f155b76f6fb │ ../../../../../../tmp/opencv/3rdparty/openexr                                    ≈
│ https://osv.dev/CVE-2018-18444      │ 8.8  │ GIT       │  0ac2ea34c8f3134148a5df4052e40f155b76f6fb │ ../../../../../../tmp/opencv/3rdparty/openexr                                    ≈
│ https://osv.dev/CVE-2020-11758      │ 5.5  │ GIT       │  0ac2ea34c8f3134148a5df4052e40f155b76f6fb │ ../../../../../../tmp/opencv/3rdparty/openexr                                    ≈
│ https://osv.dev/CVE-2020-11759      │ 5.5  │ GIT       │  0ac2ea34c8f3134148a5df4052e40f155b76f6fb │ ../../../../../../tmp/opencv/3rdparty/openexr                                    ≈
│ https://osv.dev/CVE-2020-11760      │ 5.5  │ GIT       │  0ac2ea34c8f3134148a5df4052e40f155b76f6fb │ ../../../../../../tmp/opencv/3rdparty/openexr                                    ≈
│ https://osv.dev/CVE-2020-11761      │ 5.5  │ GIT       │  0ac2ea34c8f3134148a5df4052e40f155b76f6fb │ ../../../../../../tmp/opencv/3rdparty/openexr                                    ≈
│ https://osv.dev/CVE-2020-11762      │ 5.5  │ GIT       │  0ac2ea34c8f3134148a5df4052e40f155b76f6fb │ ../../../../../../tmp/opencv/3rdparty/openexr                                    ≈
│ https://osv.dev/CVE-2020-11763      │ 5.5  │ GIT       │  0ac2ea34c8f3134148a5df4052e40f155b76f6fb │ ../../../../../../tmp/opencv/3rdparty/openexr                                    ≈
│ https://osv.dev/CVE-2020-11764      │ 5.5  │ GIT       │  0ac2ea34c8f3134148a5df4052e40f155b76f6fb │ ../../../../../../tmp/opencv/3rdparty/openexr                                    ≈
│ https://osv.dev/CVE-2020-11765      │ 5.5  │ GIT       │  0ac2ea34c8f3134148a5df4052e40f155b76f6fb │ ../../../../../../tmp/opencv/3rdparty/openexr                                    ≈
│ https://osv.dev/CVE-2020-15304      │ 5.5  │ GIT       │  0ac2ea34c8f3134148a5df4052e40f155b76f6fb │ ../../../../../../tmp/opencv/3rdparty/openexr                                    ≈
│ https://osv.dev/CVE-2020-15305      │ 5.5  │ GIT       │  0ac2ea34c8f3134148a5df4052e40f155b76f6fb │ ../../../../../../tmp/opencv/3rdparty/openexr                                    ≈
│ https://osv.dev/CVE-2020-15306      │ 5.5  │ GIT       │  0ac2ea34c8f3134148a5df4052e40f155b76f6fb │ ../../../../../../tmp/opencv/3rdparty/openexr                                    ≈
│ https://osv.dev/CVE-2020-16587      │ 5.5  │ GIT       │  0ac2ea34c8f3134148a5df4052e40f155b76f6fb │ ../../../../../../tmp/opencv/3rdparty/openexr                                    ≈
│ https://osv.dev/CVE-2020-16588      │ 5.5  │ GIT       │  0ac2ea34c8f3134148a5df4052e40f155b76f6fb │ ../../../../../../tmp/opencv/3rdparty/openexr                                    ≈
│ https://osv.dev/CVE-2020-16589      │ 5.5  │ GIT       │  0ac2ea34c8f3134148a5df4052e40f155b76f6fb │ ../../../../../../tmp/opencv/3rdparty/openexr                                    ≈
│ https://osv.dev/CVE-2021-20298      │ 7.5  │ GIT       │  0ac2ea34c8f3134148a5df4052e40f155b76f6fb │ ../../../../../../tmp/opencv/3rdparty/openexr                                    ≈
│ https://osv.dev/CVE-2021-20299      │ 7.5  │ GIT       │  0ac2ea34c8f3134148a5df4052e40f155b76f6fb │ ../../../../../../tmp/opencv/3rdparty/openexr                                    ≈
│ https://osv.dev/CVE-2021-20300      │ 5.5  │ GIT       │  0ac2ea34c8f3134148a5df4052e40f155b76f6fb │ ../../../../../../tmp/opencv/3rdparty/openexr                                    ≈
│ https://osv.dev/CVE-2021-20302      │ 5.5  │ GIT       │  0ac2ea34c8f3134148a5df4052e40f155b76f6fb │ ../../../../../../tmp/opencv/3rdparty/openexr                                    ≈
│ https://osv.dev/CVE-2021-20303      │ 6.1  │ GIT       │  0ac2ea34c8f3134148a5df4052e40f155b76f6fb │ ../../../../../../tmp/opencv/3rdparty/openexr                                    ≈
│ https://osv.dev/CVE-2021-20304      │ 7.5  │ GIT       │  0ac2ea34c8f3134148a5df4052e40f155b76f6fb │ ../../../../../../tmp/opencv/3rdparty/openexr                                    ≈
│ https://osv.dev/CVE-2021-23169      │ 8.8  │ GIT       │  0ac2ea34c8f3134148a5df4052e40f155b76f6fb │ ../../../../../../tmp/opencv/3rdparty/openexr                                    ≈
│ https://osv.dev/CVE-2021-23215      │ 5.5  │ GIT       │  0ac2ea34c8f3134148a5df4052e40f155b76f6fb │ ../../../../../../tmp/opencv/3rdparty/openexr                                    ≈
│ https://osv.dev/CVE-2021-26260      │ 5.5  │ GIT       │  0ac2ea34c8f3134148a5df4052e40f155b76f6fb │ ../../../../../../tmp/opencv/3rdparty/openexr                                    ≈
│ https://osv.dev/CVE-2021-26945      │ 5.5  │ GIT       │  0ac2ea34c8f3134148a5df4052e40f155b76f6fb │ ../../../../../../tmp/opencv/3rdparty/openexr                                    ≈
│ https://osv.dev/CVE-2021-3598       │ 5.5  │ GIT       │  0ac2ea34c8f3134148a5df4052e40f155b76f6fb │ ../../../../../../tmp/opencv/3rdparty/openexr                                    ≈
│ https://osv.dev/CVE-2021-3605       │ 5.5  │ GIT       │  0ac2ea34c8f3134148a5df4052e40f155b76f6fb │ ../../../../../../tmp/opencv/3rdparty/openexr                                    ≈
│ https://osv.dev/CVE-2021-3933       │ 5.5  │ GIT       │  0ac2ea34c8f3134148a5df4052e40f155b76f6fb │ ../../../../../../tmp/opencv/3rdparty/openexr                                    ≈
│ https://osv.dev/CVE-2021-3941       │ 6.5  │ GIT       │  0ac2ea34c8f3134148a5df4052e40f155b76f6fb │ ../../../../../../tmp/opencv/3rdparty/openexr                                    ≈
│ https://osv.dev/OSV-2022-416        │      │ GIT       │  a5891555eb49ed7cc26b2901ea680acda136d811 │ ../../../../../../tmp/opencv/3rdparty/openjpeg                                   ≈
│ https://osv.dev/CVE-2021-22569      │ 5.5  │ GIT       │  7c40b2df1fdf6f414c1c18c789715a9c948a0725 │ ../../../../../../tmp/opencv/3rdparty/protobuf                                   ≈
│ https://osv.dev/CVE-2022-3509       │ 7.5  │ GIT       │  7c40b2df1fdf6f414c1c18c789715a9c948a0725 │ ../../../../../../tmp/opencv/3rdparty/protobuf                                   ≈
│ https://osv.dev/CVE-2022-3510       │ 7.5  │ GIT       │  7c40b2df1fdf6f414c1c18c789715a9c948a0725 │ ../../../../../../tmp/opencv/3rdparty/protobuf                                   ≈
│ https://osv.dev/CVE-2023-45853      │ 9.8  │ GIT       │  04f42ceca40f73e2978b50e93806c2a18c1281fc │ ../../../../../../tmp/opencv/3rdparty/zlib
```

---------

Co-authored-by: Rex P <106129829+another-rex@users.noreply.github.com>
  • Loading branch information
oliverchang and another-rex committed Nov 1, 2023
1 parent ac2897c commit 2b7f858
Show file tree
Hide file tree
Showing 2 changed files with 185 additions and 2 deletions.
64 changes: 64 additions & 0 deletions pkg/osv/osv.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ const (
QueryEndpoint = "https://api.osv.dev/v1/querybatch"
// GetEndpoint is the URL for getting vulenrabilities from OSV.
GetEndpoint = "https://api.osv.dev/v1/vulns"
// DetermineVersionEndpoint is the URL for posting determineversion queries to OSV.
DetermineVersionEndpoint = "https://api.osv.dev/v1experimental/determineversion"
// BaseVulnerabilityURL is the base URL for detailed vulnerability views.
BaseVulnerabilityURL = "https://osv.dev/"
// maxQueriesPerRequest splits up querybatch into multiple requests if
Expand Down Expand Up @@ -76,6 +78,30 @@ type HydratedBatchedResponse struct {
Results []Response `json:"results"`
}

// DetermineVersionHash holds the per file hash and path information for determineversion.
type DetermineVersionHash struct {
Path string `json:"path"`
Hash []byte `json:"hash"`
}

type DetermineVersionResponse struct {
Matches []struct {
Score float64 `json:"score"`
RepoInfo struct {
Type string `json:"type"`
Address string `json:"address"`
Tag string `json:"tag"`
Version string `json:"version"`
Commit string `json:"commit"`
} `json:"repo_info"`
} `json:"matches"`
}

type determineVersionsRequest struct {
Name string `json:"name"`
FileHashes []DetermineVersionHash `json:"file_hashes"`
}

// MakeCommitRequest makes a commit hash request.
func MakeCommitRequest(commit string) *Query {
return &Query{
Expand Down Expand Up @@ -302,3 +328,41 @@ func makeRetryRequest(action func() (*http.Response, error)) (*http.Response, er

return resp, err
}

func MakeDetermineVersionRequest(name string, hashes []DetermineVersionHash) (*DetermineVersionResponse, error) {
var buf bytes.Buffer

request := determineVersionsRequest{
Name: name,
FileHashes: hashes,
}

if err := json.NewEncoder(&buf).Encode(request); err != nil {
return nil, err
}

//nolint:noctx
req, err := http.NewRequest(http.MethodPost, DetermineVersionEndpoint, &buf)
if err != nil {
return nil, err
}
req.Header.Set("Content-Type", "application/json")
if RequestUserAgent != "" {
req.Header.Set("User-Agent", RequestUserAgent)
}

client := http.DefaultClient
resp, err := client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()

var result DetermineVersionResponse
decoder := json.NewDecoder(resp.Body)
if err := decoder.Decode(&result); err != nil {
return nil, err
}

return &result, nil
}
123 changes: 121 additions & 2 deletions pkg/osvscanner/osvscanner.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@ package osvscanner

import (
"bufio"
"crypto/md5" //nolint:gosec
"errors"
"fmt"
"io/fs"
"os"
"os/exec"
"path"
Expand Down Expand Up @@ -58,12 +60,35 @@ var VulnerabilitiesFoundErr = errors.New("vulnerabilities found")
//nolint:errname,stylecheck // Would require version bump to change
var OnlyUncalledVulnerabilitiesFoundErr = errors.New("only uncalled vulnerabilities found")

var (
vendoredLibNames = map[string]struct{}{
"3rdparty": {},
"dep": {},
"deps": {},
"thirdparty": {},
"third-party": {},
"third_party": {},
"libs": {},
"external": {},
"externals": {},
"vendor": {},
"vendored": {},
}
)

const (
// This value may need to be tweaked, or be provided as a configurable flag.
determineVersionThreshold = 0.15
maxDetermineVersionFiles = 10000
)

// scanDir walks through the given directory to try to find any relevant files
// These include:
// - Any lockfiles with scanLockfile
// - Any SBOM files with scanSBOMFile
// - Any git repositories with scanGit
func scanDir(r reporter.Reporter, dir string, skipGit bool, recursive bool, useGitIgnore bool) ([]scannedPackage, error) {

func scanDir(r reporter.Reporter, dir string, skipGit bool, recursive bool, useGitIgnore bool, compareOffline bool) ([]scannedPackage, error) {
var ignoreMatcher *gitIgnoreMatcher
if useGitIgnore {
var err error
Expand Down Expand Up @@ -133,6 +158,16 @@ func scanDir(r reporter.Reporter, dir string, skipGit bool, recursive bool, useG
scannedPackages = append(scannedPackages, pkgs...)
}

if info.IsDir() && !compareOffline {
if _, ok := vendoredLibNames[strings.ToLower(filepath.Base(path))]; ok {
pkgs, err := scanDirWithVendoredLibs(r, path)
if err != nil {
r.PrintText(fmt.Sprintf("scan failed for dir containing vendored libs %s: %v\n", path, err))
}
scannedPackages = append(scannedPackages, pkgs...)
}
}

if !root && !recursive && info.IsDir() {
return filepath.SkipDir
}
Expand Down Expand Up @@ -181,6 +216,90 @@ func parseGitIgnores(path string) (*gitIgnoreMatcher, error) {
return &gitIgnoreMatcher{matcher: matcher, repoPath: repopath}, nil
}

func queryDetermineVersions(repoDir string) (*osv.DetermineVersionResponse, error) {
fileExts := []string{
".hpp",
".h",
".hh",
".cc",
".c",
".cpp",
}

var hashes []osv.DetermineVersionHash
if err := filepath.Walk(repoDir, func(p string, info fs.FileInfo, err error) error {
if info.IsDir() {
if _, err := os.Stat(filepath.Join(p, ".git")); err == nil {
// Found a git repo, stop here as otherwise we may get duplicated
// results with our regular git commit scanning.
return filepath.SkipDir
}

return nil
}
for _, ext := range fileExts {
if filepath.Ext(p) == ext {
buf, err := os.ReadFile(p)
if err != nil {
return err
}
hash := md5.Sum(buf) //nolint:gosec
hashes = append(hashes, osv.DetermineVersionHash{
Path: strings.ReplaceAll(p, repoDir, ""),
Hash: hash[:],
})
if len(hashes) > maxDetermineVersionFiles {
return errors.New("too many files to hash")
}
}
}

return nil
}); err != nil {
return nil, fmt.Errorf("failed during hashing: %w", err)
}

result, err := osv.MakeDetermineVersionRequest(filepath.Base(repoDir), hashes)
if err != nil {
return nil, fmt.Errorf("failed to determine versions: %w", err)
}

return result, nil
}

func scanDirWithVendoredLibs(r reporter.Reporter, path string) ([]scannedPackage, error) {
r.PrintText(fmt.Sprintf("Scanning directory for vendored libs: %s\n", path))
entries, err := os.ReadDir(path)
if err != nil {
return nil, err
}

var packages []scannedPackage
for _, entry := range entries {
if !entry.IsDir() {
continue
}

libPath := filepath.Join(path, entry.Name())

r.PrintText(fmt.Sprintf("Scanning potential vendored dir: %s\n", libPath))
// TODO: make this a goroutine to parallelise this operation
results, err := queryDetermineVersions(libPath)
if err != nil {
r.PrintText(fmt.Sprintf("Error scanning sub-directory '%s' with error: %v", libPath, err))
continue
}

if len(results.Matches) > 0 && results.Matches[0].Score > determineVersionThreshold {
match := results.Matches[0]
r.PrintText(fmt.Sprintf("Identified %s as %s at %s.\n", libPath, match.RepoInfo.Address, match.RepoInfo.Commit))
packages = append(packages, createCommitQueryPackage(match.RepoInfo.Commit, libPath))
}
}

return packages, nil
}

// gitIgnoreMatcher.match will return true if the file/directory matches a gitignore entry
// i.e. true if it should be ignored
func (m *gitIgnoreMatcher) match(absPath string, isDir bool) (bool, error) {
Expand Down Expand Up @@ -632,7 +751,7 @@ func DoScan(actions ScannerActions, r reporter.Reporter) (models.VulnerabilityRe

for _, dir := range actions.DirectoryPaths {
r.PrintText(fmt.Sprintf("Scanning dir %s\n", dir))
pkgs, err := scanDir(r, dir, actions.SkipGit, actions.Recursive, !actions.NoIgnore)
pkgs, err := scanDir(r, dir, actions.SkipGit, actions.Recursive, !actions.NoIgnore, actions.CompareOffline)
if err != nil {
return models.VulnerabilityResults{}, err
}
Expand Down

0 comments on commit 2b7f858

Please sign in to comment.