Jonathan Amsterdam | 7ec1ba1 | 2023-02-13 11:45:16 -0500 | [diff] [blame] | 1 | // Copyright 2022 The Go Authors. All rights reserved. |
| 2 | // Use of this source code is governed by a BSD-style |
| 3 | // license that can be found in the LICENSE file. |
| 4 | |
Zvonimir Pavlinovic | 73f2fb0 | 2023-09-15 09:28:08 -0700 | [diff] [blame] | 5 | // This program runs govulncheck on a module in source mode and then |
Jonathan Amsterdam | 7ec1ba1 | 2023-02-13 11:45:16 -0500 | [diff] [blame] | 6 | // writes the result as JSON. It is intended to be run in a sandbox. |
Zvonimir Pavlinovic | 73f2fb0 | 2023-09-15 09:28:08 -0700 | [diff] [blame] | 7 | // For running govulncheck on binaries, see cmd/compare_sandbox. |
Jonathan Amsterdam | 7ec1ba1 | 2023-02-13 11:45:16 -0500 | [diff] [blame] | 8 | // |
| 9 | // Unless it panics, this program always terminates with exit code 0. |
| 10 | // If there is an error, it writes a JSON object with field "Error". |
Zvonimir Pavlinovic | b6a3328 | 2023-03-14 16:50:37 -0700 | [diff] [blame] | 11 | // Otherwise, it writes a internal/govulncheck.SandboxResponse as JSON. |
Jonathan Amsterdam | 7ec1ba1 | 2023-02-13 11:45:16 -0500 | [diff] [blame] | 12 | package main |
| 13 | |
| 14 | import ( |
Maceo Thompson | 1dc3668 | 2023-03-09 18:34:22 +0000 | [diff] [blame] | 15 | "encoding/json" |
Jonathan Amsterdam | 7ec1ba1 | 2023-02-13 11:45:16 -0500 | [diff] [blame] | 16 | "errors" |
| 17 | "flag" |
| 18 | "fmt" |
| 19 | "io" |
Jonathan Amsterdam | 7ec1ba1 | 2023-02-13 11:45:16 -0500 | [diff] [blame] | 20 | "os" |
Jonathan Amsterdam | 7ec1ba1 | 2023-02-13 11:45:16 -0500 | [diff] [blame] | 21 | |
Zvonimir Pavlinovic | 85d1577 | 2023-03-14 16:12:23 -0700 | [diff] [blame] | 22 | "golang.org/x/pkgsite-metrics/internal/govulncheck" |
Jonathan Amsterdam | 7ec1ba1 | 2023-02-13 11:45:16 -0500 | [diff] [blame] | 23 | ) |
| 24 | |
Zvonimir Pavlinovic | d732a2c | 2023-03-17 16:18:37 -0700 | [diff] [blame] | 25 | // main function for govulncheck sandbox that accepts four inputs |
| 26 | // in the following order: |
| 27 | // - path to govulncheck |
| 28 | // - govulncheck mode |
| 29 | // - input module or binary to analyze |
| 30 | // - full path to the vulnerability database |
Jonathan Amsterdam | 7ec1ba1 | 2023-02-13 11:45:16 -0500 | [diff] [blame] | 31 | func main() { |
| 32 | flag.Parse() |
Zvonimir Pavlinovic | d732a2c | 2023-03-17 16:18:37 -0700 | [diff] [blame] | 33 | run(os.Stdout, flag.Args()) |
Jonathan Amsterdam | 7ec1ba1 | 2023-02-13 11:45:16 -0500 | [diff] [blame] | 34 | } |
| 35 | |
Zvonimir Pavlinovic | d732a2c | 2023-03-17 16:18:37 -0700 | [diff] [blame] | 36 | func run(w io.Writer, args []string) { |
Jonathan Amsterdam | 7ec1ba1 | 2023-02-13 11:45:16 -0500 | [diff] [blame] | 37 | |
| 38 | fail := func(err error) { |
| 39 | fmt.Fprintf(w, `{"Error": %q}`, err) |
| 40 | fmt.Fprintln(w) |
| 41 | } |
| 42 | |
Zvonimir Pavlinovic | d732a2c | 2023-03-17 16:18:37 -0700 | [diff] [blame] | 43 | if len(args) != 4 { |
| 44 | fail(errors.New("need four args: govulncheck path, mode, input module dir or binary, full path to vuln db")) |
Jonathan Amsterdam | 7ec1ba1 | 2023-02-13 11:45:16 -0500 | [diff] [blame] | 45 | return |
| 46 | } |
Zvonimir Pavlinovic | 73f2fb0 | 2023-09-15 09:28:08 -0700 | [diff] [blame] | 47 | |
| 48 | modeFlag := args[1] |
| 49 | if modeFlag == govulncheck.FlagBinary { |
| 50 | fail(errors.New("binaries are only analyzed in compare_sandbox")) |
Jonathan Amsterdam | 7ec1ba1 | 2023-02-13 11:45:16 -0500 | [diff] [blame] | 51 | return |
| 52 | } |
Maceo Thompson | aab7eeb | 2023-03-01 21:45:31 +0000 | [diff] [blame] | 53 | |
Zvonimir Pavlinovic | 73f2fb0 | 2023-09-15 09:28:08 -0700 | [diff] [blame] | 54 | resp, err := runGovulncheck(args[0], modeFlag, args[2], args[3]) |
Zvonimir Pavlinovic | 985587f | 2023-03-09 18:01:22 -0800 | [diff] [blame] | 55 | if err != nil { |
| 56 | fail(err) |
| 57 | return |
Maceo Thompson | aab7eeb | 2023-03-01 21:45:31 +0000 | [diff] [blame] | 58 | } |
Maceo Thompson | 1dc3668 | 2023-03-09 18:34:22 +0000 | [diff] [blame] | 59 | b, err := json.MarshalIndent(resp, "", "\t") |
| 60 | if err != nil { |
| 61 | fail(fmt.Errorf("json.MarshalIndent: %v", err)) |
| 62 | return |
| 63 | } |
| 64 | |
Jonathan Amsterdam | 7ec1ba1 | 2023-02-13 11:45:16 -0500 | [diff] [blame] | 65 | w.Write(b) |
| 66 | fmt.Println() |
| 67 | } |
| 68 | |
Zvonimir Pavlinovic | 73f2fb0 | 2023-09-15 09:28:08 -0700 | [diff] [blame] | 69 | func runGovulncheck(govulncheckPath, modeFlag, filePath, vulnDBDir string) (*govulncheck.SandboxResponse, error) { |
Maceo Thompson | e3b973e | 2023-05-22 21:23:01 +0000 | [diff] [blame] | 70 | response := govulncheck.SandboxResponse{ |
| 71 | Stats: govulncheck.ScanStats{}, |
Zvonimir Pavlinovic | eac61d4 | 2023-03-08 16:29:28 -0800 | [diff] [blame] | 72 | } |
Maceo Thompson | 465ecaa | 2023-06-27 13:24:38 -0400 | [diff] [blame] | 73 | |
Zvonimir Pavlinovic | 73f2fb0 | 2023-09-15 09:28:08 -0700 | [diff] [blame] | 74 | findings, err := govulncheck.RunGovulncheckCmd(govulncheckPath, modeFlag, "./...", filePath, vulnDBDir, &response.Stats) |
Maceo Thompson | 1dc3668 | 2023-03-09 18:34:22 +0000 | [diff] [blame] | 75 | if err != nil { |
| 76 | return nil, err |
| 77 | } |
Maceo Thompson | e3b973e | 2023-05-22 21:23:01 +0000 | [diff] [blame] | 78 | response.Findings = findings |
Maceo Thompson | 1dc3668 | 2023-03-09 18:34:22 +0000 | [diff] [blame] | 79 | return &response, nil |
Maceo Thompson | aab7eeb | 2023-03-01 21:45:31 +0000 | [diff] [blame] | 80 | } |